VS2010 配布環境:Win7/Vista
教えてください。
Win7でディスプレイ制御をしたく、
GetDisplayConfigBufferSizes/SetDisplayConfig/QueryDisplayConfig
を使用します。Win7上での動作は問題ありません。
同じモジュールをVistaでも配布する必要がありますが、
Win7のみ対応APIのようでエントリポイント不明で例外となります。
(MSDNにはVista以上とあるが、ヘッダにはWINVER>0601)
ためしに、user32.libをプロジェクト設定から外して
LoadLibrary→GetProcAddres→見つからなければVista
と判定してVista上の例外回避はできたのですが
今度はWin7上でアクセスバイオレーションが出るようになってしまいました。
どうすればいいか手詰まりの状況です。
正しい方法?を教えて頂きたく宜しくお願いします。
GetProcAddress で指定している関数名が間違っているとか
正しくキャストできていないのでアセンブラレベルで正しく呼べていないとか
単純にその辺のような気のせいがする。
いかんせんソースコードの提示無しでは妄想に憶測を重ねるだけかと。
> ためしに、user32.libをプロジェクト設定から外して
はずさなくても良いのでは・・・
んでは、自分は別のアプローチを・・。
targetver.h ってのがあると思うのですが、無ければ
WINVERと、_WIN32_WINNTの定義をしている部分を検索してください。
この定義は全てのインクルードに先立って行われるので、プリコンパイルの
近傍にあります(多分)。
さて、この二つの定義は「最低限必要なプラットホームのバージョン」を意味し、
コンパイル時に決定される条件となります。
例えば、#defien _WIN32_WINNT 0601 //(Windows7)が指定された場合、
コンパイラはこのアプリが動作するときの、最低限必要なプラットホームの
バージョンはWindows7だとして処理します。
当然ですが、この場合、Vista(0600)はそのプラットホームに満たないので、
対象外(Vistaでは動作しなくて良い)という処理になるわけです。
つまり、疑惑の関数がWindows7のみ対応であれば、
#define WINVER 0600 // Vista以上で動いてね
#defien _WIN32_WINNT 0600 // Vista以上で動いてね
とすれば、当該関数のところで何らかの警告かエラーが出ると思われます。
ごめん orz.
ヘッダーを確認済みなのですね(vv;)
そうなると、MSさんのドキュメントの間違いである可能性が高いですね。
http://msdn.microsoft.com/en-us/library/windows/hardware/ff566778(v=vs.85).aspx
には、そう書いてあるし。
んで、アクセスバイオレーションはどこで発生するのでしょう。
> ためしに、user32.libをプロジェクト設定から外して
> LoadLibrary→GetProcAddres→見つからなければVista
user32.libを外さないで、
GetProcAddressで見つかったら、
その関数ポインタを呼ぶようにすれば良いと思います。
ちなみに、GUIならはuser32.dllはloadされているはずなので
GetModuleHandleでも良いです。
追加です。
ヘッダの関数宣言にWINAPIなどがついていれば
関数ポインタの関数型にもつけてください。 (WINAPI は __stdcallの意)
たくさんのコメントありがとうございます。
なかなか手がつけられず遅くなって申し訳ありません。
結果としてロマさんの御指摘(WINAPI宣言漏れ)で解決しました。
typedef LONG (*TYPE_GETDISPLAYCONFIGBUFFERSIZES)(UINT32, UINT32*, UINT32*);
↓
typedef LONG (WINAPI *TYPE_GETDISPLAYCONFIGBUFFERSIZES)(UINT32, UINT32*,
UINT32*);
やはり最初にソース提示すべきでしたね...。
お恥ずかしいですが、コピペでなんとなく動くを繰り返していたので、
きちんと勉強して理解したいと思います。
ありがとうございましたm(_ _)m
解決した後で何ですが、VS2010を使用されているなら
decltypeの使用を検討しても良いのではないでしょうか?
http://dev.activebasic.com/egtra/2009/06/04/202/
マイナーな機能ですが遅延ロードというのがあります。
LoadLibrary → GetProcAddress を自動でやってくれる機能です。
プロジェクトのプロパティで、[DLLの遅延読み込み]に user32.dll を書いてやること
で、普通に GetDisplayConfigBufferSizes(...) と書いたのが、内部的に動的呼び出し
に変換されます。
ただし、VerifyVersionInfo API 等を使用して、非対応バージョン(Vista)では、この
部分のコードを呼び出さないようにする必要があります。