ボンジュール・マドモアゼル

本サイトの情報は自己責任にてご利用下さい。

[Win32 プログラミング大全] warning C4312: '型キャスト' : 'LONG' からより大きいサイズの 'HMODULE' へ変換します。

 
「warning C4312: '型キャスト' : 'LONG' からより大きいサイズの 'HMODULE' へ変換します。」について

153 名前:デフォルトの名無しさん :05/02/20 05:02:21
質問です。
ウィンドプロシージャ関数内でダイアログを呼び出そうとして
DialogBox(GetWindowInstance(hWnd),MAKEINTRESOURCE(IDD_MYDIALOG), hWnd,DlgProc);
としました。すると以下のような警告が出てしまいました。
warning C4312: '型キャスト' : 'LONG' からより大きいサイズの 'HMODULE' へ変換します。
どうやらGetWindowInstance関数でインスタンスハンドルを取得した場合に出るようなのですが

その先の改善の仕方がどうにもわかりません、この警告を消す方法を教えてください、お願いします。

155 名前:デフォルトの名無しさん :05/02/20 06:46:57
>>153
Win64への以降を睨んで、VCやWindows.hは64bitへ対応する準備がなされている。
まずWin64ではハンドル・ポインタが64bitになるのに、int/longは32bitのまま。
だからハンドル・ポインタを格納する整数型にint/longを使っているとまずいので、
そういう警告が出る。(ハンドル・ポインタ→int/longも警告が出る)

http://pc5.2ch.net/test/read.cgi/tech/1108815602/32
ハンドル・ポインタを整数に格納するときは*_PTRを使うことになっている。
すると64bit対応したと見て警告が出なくなる。

今回のGetWindowInstanceは古いものだとGetWindowLongを呼び出すマクロだが、
最近の物だとGetWindowLongPtrを呼び出すように変更されている。
PlatformSDKをアップデートしてみろ。(直接書き替えても別に悪くは無いが)

182 名前:153 :05/02/20 22:38:40
>>155
ありがとうございます。ためになりました!!
スタートページからPlatformSDKをアップデートしようとしたんですが
更新できる項目がなにもなかったのでwindowsX.hの中を見ていたら
GetWindowInstace関数はGetWindowLongPtr関数を呼び出すように
書かれていました。
それでもこの警告が出てしまうので、実行時には今のところ問題なさ
そうだし、この警告を消すのはあきらめることにしました。

>>182
Win32ではGet/SetWindowLongPtrは単にGet/SetWindowLongを呼び出すマクロになっているだけだからどうしようもない

220 名前:182 :05/02/22 10:05:33
おはようございます
>>153の警告を消すのをあきらめるとか言っておい
てやっぱりあきらめられず色々やってました。
結局、WinUser.hというヘッダーファイルにたどり着き
そこにGetWindowLong関数が記述してあったので、
戻り値がLONGとなっていたのをLONG_PTRに書き変えて
リビルドすると警告はきれいさっぱり消えてくれました。


結果目的は達成することができました!ですが最後に質問させてください
勝手に上のようにヘッダーファイルを書き換えてしまったのですが
それによって不具合が生じることなどが考えられるでしょうか?
よろしくお願いします。

221 名前:デフォルトの名無しさん :05/02/22 10:10:11
それなら戻り値をLONG_PTRにキャストしてやれば良いんじゃね?

222 名前:182 :05/02/22 10:25:03
どうもです
戻り値をLONG_PTRにキャストするとLOGN_PTRをHINSTANCEに
変換できないという旨のエラーが出てしまいました。
それと書き換えてない状態でGetWindowInstance関数が戻すの
はあくまでLONG型のデータらしくそれをキャストしても同じ旨の
警告がでるみたいです・・

240 名前:デフォルトの名無しさん :05/02/23 17:56:03
>>220
>>199
それと221はたぶんGetWindowInstanceを一旦LONG_PTRにキャストしてから HINSTANCEにキャストするように直せということじゃないか?

249 名前:182 :05/02/23 23:04:13
>>240
そっか・・そうですよね!気づきませんでした
そのことをまったく考えてなかったです。
目が覚めました。ありがとうございます!
★初心者にVisual C++を教えるスレ★ Part17


そこで、

winuser.h の GetWindowLong関数の戻り値を LONG から LONG_PTR に修正してみる
WINUSERAPI
LONG LONG_PTR

WINAPI
GetWindowLongW(
__in HWND hWnd,
__in int nIndex);

これは確かに警告が消えた。次に

GetWindowInstance関数の戻り値を LONG_PTR にキャストして、HMODULE にキャストしてみる

HINSTANCE hinst = (HMODULE)(LONG_PTR)GetWindowInstance(hwnd);
HINSTANCE hinst = LongToHandle(GetWindowInstance(hwnd));

残念ながらこれは警告が消えなかった。しかし、次のように、windowsx.h に細工をしてやると警告を消すことができた。
#define GetWindowInstance(hwnd) ((HMODULE)LongToHandle(GetWindowLongPtr(hwnd, GWLP_HINSTANCE)))


なお、LongToHandle は、basetsd.h で次のように定義されている。
#define LongToHandle( h ) ((HANDLE)(LONG_PTR) (h) )


(参考) GetWindowLongPtr について msdn より.

GetWindowLongPtr
指定されたウィンドウに関する情報を取得します。ウィンドウの拡張ウィンドウメモリ内の指定されたオフセット位置にある値もこの関数を使って取得できます。
この関数は、GetWindowLong 関数の改訂版です。32 ビット版 Windows と 64 ビット版 Windows の両方ともと互換性のあるコードを記述するには、GetWindowLongPtr 関数を使ってください。

msdn プラットフォーム SDK GetWindowLongPtr

[Win32 プログラミング大全] #define STRICT

 
windows.h ヘッダーファイルをインクルードする前に、次のようにシンボル STRICT を定義することで、厳密な型チェックを利用することができる。

#define STRICT

Win32 プログラミング大全(上) 71頁


本が古いので、Windows Server 2003 SP1 SDK Release にて現状を調べてみた。



なので、今は特に #define STRICT は書かなくてもよさそう(自信なし)。