トップ回答者
MFCアプリケーションでのBeginPanningFeedback

質問
-
Visual Studio 2015にてMFCアプリケーションを作成しています。
アプリケーション内でBeginPanningFeedback、UpdatePanningFeedback、EndPannigFeedback関数を使用しようとしているのですが、これら3つの関数がリンクエラーとなりリンクできません。error LNK2019: 未解決の外部シンボル _BeginPanningFeedback@4 が関数...
error LNK2019: 未解決の外部シンボル _UpdatePanningFeedback@16 が関数...
error LNK2019: 未解決の外部シンボル _EndPanningFeedback@8 が関数...
UxTheme.hをインクルードしていて、プロジェクトのプロパティのリンク→入力→追加の依存ファイルにUxTheme.libを指定しています。
同じことをWindowsアプリケーション(MFCを使用せず)で行うと、正しくリンクできるようです。
この症状の解決方法はありますでしょうか?
- 編集済み syaki 2016年4月1日 9:05
回答
-
原因は、
BeginPanningFeedback、UpdatePanningFeedback、EndPannigFeedback 関数は C++ リンケージで定義されているのですが、ヘッダーファイル「uxtheme.h」が C リンケージで読み込まれているからです。この場合、dwmapi.lib をリンクしても、前述の関数シンボルが見つからなくなります。
私の環境ではインクルードの順序は下記のようになっていました。
"[プロジェクトフォルダ]\stdafx.h"
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\include\afxwin.h"
"C:\Program Files (x86)\Windows Kits\8.1\Include\um\dwmapi.h"
"C:\Program Files (x86)\Windows Kits\8.1\Include\um\Uxtheme.h"
上記の dwmapi.h の中で
#ifdef __cplusplus extern "C" { #endif <中略> #include <uxtheme.h> <中略> #ifdef __cplusplus } #endif
というような感じで include されていました。
1つの解決方法は、
MFCのヘッダー中で Uxtheme.h をインクルードさせないように _UXTHEME_H_ を定義し、その後自分で関数の宣言を行います。以下のように stdafx.h の中の
#include <afxwin.h> // MFC のコアおよび標準コンポーネント
の部分を下記のように置き換えます
#define _UXTHEME_H_ typedef struct _MARGINS { int cxLeftWidth; // width of left border that retains its size int cxRightWidth; // width of right border that retains its size int cyTopHeight; // height of top border that retains its size int cyBottomHeight; // height of bottom border that retains its size } MARGINS, *PMARGINS; #include <afxwin.h> // MFC のコアおよび標準コンポーネント BOOL WINAPI BeginPanningFeedback( __in HWND hwnd); BOOL WINAPI UpdatePanningFeedback( __in HWND hwnd, __in LONG lTotalOverpanOffsetX, __in LONG lTotalOverpanOffsetY, __in BOOL fInInertia); BOOL WINAPI EndPanningFeedback( __in HWND hwnd, __in BOOL fAnimateBack); // Uxtheme.h はインクルードせず Uxtheme の使いたいAPIは自分で宣言して下さい。
※構造体 _MARGINS を定義しているのは afxwin.h の中で使われているからです。
ちなみに、VS2008 を確認してみましたが、afxwin.h の中でリンケージ指定なしで Uxtheme.h がインクルードされていました。リンクエラーにならなかったのはそのためですね。なぜ今のような設定になっているか知る由はありませんが、不具合とも取れますね。
Uxtheme の中の3つ関数 BeginPanningFeedback、UpdatePanningFeedback、EndPannigFeedback 以外は C リンケージで定義されているので他の Uxtheme 関数のリンクは既定でも普通にリンクできました。
以上参考になりましたら幸いです。
- 編集済み kenjinoteMVP 2016年4月3日 3:22
- 回答としてマーク syaki 2016年4月4日 0:44
すべての返信
-
すみません。解決方法というよりは、回避方法ですが、
動的リンクで、関数をロードしてみてはいかがでしょうか?
ヘッダー部
typedef BOOL(WINAPI * BeginPanningFeedbackPtr)(HWND hWnd); typedef BOOL(WINAPI * UpdatePanningFeedbackPtr)(HWND hWnd, LONG offsetX, LONG offsetY, BOOL fInInertia); typedef BOOL(WINAPI * EndPanningFeedbackPtr)(HWND hWnd, BOOL fAnimateBack); BeginPanningFeedbackPtr beginPanningFeedback = 0; UpdatePanningFeedbackPtr updatePanningFeedback = 0; EndPanningFeedbackPtr endPanningFeedback = 0;
クラスの初期化部
HMODULE hTheme = ::LoadLibrary(TEXT("uxtheme.dll")); if (hTheme) { beginPanningFeedback = (BeginPanningFeedbackPtr)GetProcAddress(hTheme, "BeginPanningFeedback"); updatePanningFeedback = (UpdatePanningFeedbackPtr)GetProcAddress(hTheme, "UpdatePanningFeedback"); endPanningFeedback = (EndPanningFeedbackPtr)GetProcAddress(hTheme, "EndPanningFeedback"); }
上記の関数が正しくロードできた場合(非ゼロの場合)は
BeginPanningFeedback、UpdatePanningFeedback、EndPannigFeedback関数
を使う代わりに、beginPanningFeedback、updatePanningFeedback、endPanningFeedback関数を使用します。 -
原因は、
BeginPanningFeedback、UpdatePanningFeedback、EndPannigFeedback 関数は C++ リンケージで定義されているのですが、ヘッダーファイル「uxtheme.h」が C リンケージで読み込まれているからです。この場合、dwmapi.lib をリンクしても、前述の関数シンボルが見つからなくなります。
私の環境ではインクルードの順序は下記のようになっていました。
"[プロジェクトフォルダ]\stdafx.h"
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\include\afxwin.h"
"C:\Program Files (x86)\Windows Kits\8.1\Include\um\dwmapi.h"
"C:\Program Files (x86)\Windows Kits\8.1\Include\um\Uxtheme.h"
上記の dwmapi.h の中で
#ifdef __cplusplus extern "C" { #endif <中略> #include <uxtheme.h> <中略> #ifdef __cplusplus } #endif
というような感じで include されていました。
1つの解決方法は、
MFCのヘッダー中で Uxtheme.h をインクルードさせないように _UXTHEME_H_ を定義し、その後自分で関数の宣言を行います。以下のように stdafx.h の中の
#include <afxwin.h> // MFC のコアおよび標準コンポーネント
の部分を下記のように置き換えます
#define _UXTHEME_H_ typedef struct _MARGINS { int cxLeftWidth; // width of left border that retains its size int cxRightWidth; // width of right border that retains its size int cyTopHeight; // height of top border that retains its size int cyBottomHeight; // height of bottom border that retains its size } MARGINS, *PMARGINS; #include <afxwin.h> // MFC のコアおよび標準コンポーネント BOOL WINAPI BeginPanningFeedback( __in HWND hwnd); BOOL WINAPI UpdatePanningFeedback( __in HWND hwnd, __in LONG lTotalOverpanOffsetX, __in LONG lTotalOverpanOffsetY, __in BOOL fInInertia); BOOL WINAPI EndPanningFeedback( __in HWND hwnd, __in BOOL fAnimateBack); // Uxtheme.h はインクルードせず Uxtheme の使いたいAPIは自分で宣言して下さい。
※構造体 _MARGINS を定義しているのは afxwin.h の中で使われているからです。
ちなみに、VS2008 を確認してみましたが、afxwin.h の中でリンケージ指定なしで Uxtheme.h がインクルードされていました。リンクエラーにならなかったのはそのためですね。なぜ今のような設定になっているか知る由はありませんが、不具合とも取れますね。
Uxtheme の中の3つ関数 BeginPanningFeedback、UpdatePanningFeedback、EndPannigFeedback 以外は C リンケージで定義されているので他の Uxtheme 関数のリンクは既定でも普通にリンクできました。
以上参考になりましたら幸いです。
- 編集済み kenjinoteMVP 2016年4月3日 3:22
- 回答としてマーク syaki 2016年4月4日 0:44