- ベストアンサー
(SHORT)
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
★既に『符号なし』を『符号あり』へのキャストという回答がありますね。 ・でも、多分質問者さんもキャストのことは知っていると勝手に解釈して なぜ、(SHORT)キャストする必要があるのかってことですよね。→効果。 ・そこで、追加アドバイスします。 理由:効果とは? ・『WM_MOUSEWHEEL』というメッセージの『wParam』の上位 16 ビットは マウス・ホイールの回転の方向を返しますよね。 このとき、負の値も返すんですよ。 ・だから、『HIWORD』マクロ関数だけではすべてが符号なしの整数ですから 回転の方向を感知できません。SHORT 型にキャストすることで 32767 以上 の数値を『負の値』として解釈できるため、その後の上下の矢印を正しく 表示できます。→これが SHORT 型にキャストする理由と効果です。 ・このキャストを行わないと、常に『↑』矢印だけの表示になってしまい マウス・ホイールの回転の方向を検出できません。 余談: ・『WM_LBUTTONDOWN』というメッセージの『lParam』も同様に、 INT cx = (SHORT)LOWORD(lParam); INT cy = (SHORT)HIWORD(lParam); としてマウス・カーソルの位置を取得させます。 ・このメッセージも『lParam』は負の数を返すためです。 ・SHORT 型へのキャストはこのような理由で必要となるのです。 ・以上。おわり。
その他の回答 (3)
- php504
- ベストアンサー率42% (926/2160)
HIWORDマクロの値はWORDでこれは16ビット符号なし整数です。 SHORTは16ビット符号つき整数です。 符号なしから符号ありへの変換を行っているようです。
お礼
回答ありがとうございます! 符号なしから符号ありへの変換を行っているようです。 と言うのは、参考になりました! ありがとうございます!
- tea_sheep
- ベストアンサー率53% (8/15)
HIWORDマクロが返す値は符号なし整数(WORD型)なので これを符号つき整数であると解釈させるためにSHORTへの キャストを行っています。
お礼
回答ありがとうございます! 解説どうもでした!
- stiffels
- ベストアンサー率34% (25/72)
WORDからSHORTへキャストするのを明示的にやっているのだと思いますよ。
お礼
回答ありがとうございます! 参考になりました!
関連するQ&A
- wParam
wParamは、unsigned int型で、仮想キーコードを、格納してますよね。 wsprintf()内で(TCHAR)キャストしてますが、 これは、変数strの型がTCHAR型なので(wParamは、unsigned intなので型をあわせるために)やっているんですか? (TCHAR)キャストしないとエラーになりますか?教えてください。 HDC hdc; TCHAR str[255]; swich(umsg){ case WM_CHAR: wsprintf( str, TEXT("%c"), (TCHAR)wPara ); hdc = GetDC(hwnd); TextOut(hdc, 0, 0, str, lstrlen(str)); return0 }
- ベストアンサー
- C・C++・C#
- WM_PAINT
WM_PAINT について教えてほしいのですが、 WM_PAINTがシステムから発行されるタイミングとして、 クライアント領域に無効領域がある時 UpdateWindow()を呼び出した時 InvalidateRect()を呼び出した時があると思いますが 例えば LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM) { LPCTSTR Str = TEXT("Kitty"); switch (msg) { case WM_CREATE: hdc = GetDC(hwnd); SetTextColor(hdc , RGB(255, 0 , 0)); ReleaseDC(hwnd , hdc); return 0; case WM_PAINT: hdc = BeginPaint(hwnd , &ps); TextOut(hdc, 10 , 10 , Str, lstrlen(Str)); EndPaint(hwnd , &ps); return 0; } return DefWindowProc(hwnd , msg , wp , lp); } の場合, WM_PAINTはどのタイミングでシステムから呼び出されるんですか? WinMain()でUpdateWindow()もInvalidateRect()もつかっていないのですが。 いつシステムから送られるかご教授をお願いします。
- ベストアンサー
- C・C++・C#
- TextOut( ) が動かない
LRESULT CALLBACK WndProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ PAINTSTRUCT ps; HDC hdc; switch(msg){ case WM_KEYDOWN: if( wParam == VK_ESCAPE ){ hdc = BeginPaint(hWnd, &ps); TextOut(hdc,0,0,str,strlen(str)); EndPaint(hWnd, &ps); } break; case WM_PAINT: break; エスケープキーで文字表示をやりたいけど TextOut( ) が動作していないみたいでした。 switch(msg){ case WM_KEYDOWN: if( wParam == VK_ESCAPE ){ hdc = BeginPaint(hWnd, &ps); TextOut(hdc,0,0,str,strlen(str)); EndPaint(hWnd, &ps); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); TextOut(hdc,0,0,str,strlen(str)); EndPaint(hWnd, &ps); break; とすると、常に文字が表示されたから、やっぱり case WM_KEYDOWN: の中の TextOut( ) が 動作していないんだと思いました。 TextOut( ) は case WM_PAINT: からのつながりが ある場合でないと実行されないんですか? ソースのおかしいところがあったら教えてください。
- ベストアンサー
- C・C++・C#
- TextOut( ) を BeginPaint( ) と GetDC( )
LRESULT CALLBACK の case WM_PAINT: で、 hdc = BeginPaint(hWnd, &ps); TextOut(hdc,0,0,str,strlen(str)); EndPaint(hWnd, &ps); ↑問題無し。↓文字がちらつく。 hdc = GetDC(hWnd); TextOut(hdc,0,0,str,strlen(str)); ReleaseDC(hWnd,hdc); ちらつきの原因は、高速で TextOut( ) が繰り返されるから だと思いました。 どうして TextOut( ) が繰り返されるんですか? 上の方法の場合は、 ReleaseDC(hWnd,hdc); は書かなくてもいいですか?
- ベストアンサー
- C・C++・C#
- リサイズで文字が消えちゃう
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; char *str; switch (msg) { case WM_KEYDOWN: hdc = GetDC(hWnd); str = "キーダウンした"; TextOut(hdc,1,1,str,strlen(str)); ReleaseDC(hWnd,hdc); break; キーを押すと、LRESULT CALLBACK でウインドウに文字が 表示されるようにしました。 でも、この文字は別のウインドウに隠れて、再びウインドウが 表示された場合とかには消えています。 消えないようにするためにはどうしたらいいですか? void Swit(HWND hWnd) { HDC hdc; char *str; if (キーダウンのフラグがあったとして、それが true なら) { hdc = GetDC(hWnd); str = "キーダウンした"; TextOut(hdc,1,1,str,strlen(str)); ReleaseDC(hWnd,hdc); } return; } if ( ウインドウ再描画 == true ){ Swit() } というのを考えました。 LRESULT CALLBACK で、キーが押された場合にフラグを true にして ウインドウが再描画された場合にフラグをチェックして文字を 表示する という方法を考えたんだけど、これを BCC32 でコンパイル するためにはどういうソースを書いたらいいか分からないし、 もっといい方法があれば教えてください。
- ベストアンサー
- C・C++・C#
- C言語で文字列バッファを消去する方法
今、C言語とWin32 APIを使ってプログラミングをしています。 wsprintf(str,TEXT("プレイヤーの攻撃!")); TextOut(hdc,0,520,bstr,lstrlen(str)); if(ehp <= 0) { wsprintf(str,TEXT("敵を倒しました")); TextOut(hdc,0,520,bstr,lstrlen(str)); } このコードを実行すると、2回目のTextOutのところで 「敵をたおしました撃!」と出てしまいます。 きっとstrに以前の文字列が残っているからだと思いますが、 この保存した文字列を消去するにはどうしたらよいのでしょうか? for文でstr[0]から'\0'までナル文字を代入し続けたり、いろいろと試したのですが駄目でした。どうかこんな自分にご助力お願いできないでしょうか? どうかお願い致します。
- ベストアンサー
- C・C++・C#
- なぜhButton1ボタンからのWM_COMMANDはフックできてクライアントエリアのWM_RBUTTONDOWNはフックできないのでしょうか?
#define STRLBUTTON TEXT("マウス左ボタンが押されました from mainProc") #define STRRBUTTON TEXT("マウス右ボタンが押されました from my_HookProc") #define STRCOMMAND TEXT("ボタンが押されました") HWND hButton1; LRESULT CALLBACK my_HookProc(int nCode, WPARAM wParam, LPARAM lParam) { CWPRETSTRUCT *pcwpRetStruct = (CWPRETSTRUCT *)lParam; HDC hDC; if(nCode==HC_ACTION) { hDC = GetDC(pcwpRetStruct->hwnd); switch(pcwpRetStruct->message) { case WM_COMMAND: TextOut(hDC, 10, 10, STRCOMMAND, strlen(STRCOMMAND)); break; case WM_RBUTTONDOWN: TextOut(hDC, 10, 10, STRRBUTTON, strlen(STRRBUTTON)); break; } ReleaseDC(pcwpRetStruct->hwnd, hDC); } return CallNextHookEx(NULL, nCode, wParam, lParam); } LRESULT CALLBACK mainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HHOOK hHook; HDC hDC; switch(uMsg) { case WM_DESTROY: UnhookWindowsHookEx(hHook); PostQuitMessage(0); return 0; case WM_CREATE: hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, my_HookProc, NULL, GetCurrentThreadId() ); if(!hHook) MessageBox(NULL, "hooking failed", NULL, MB_OK); hButton1 = CreateWindow( "BUTTON", "hButton1", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 40, 100, 20, hWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL ); return 0; case WM_LBUTTONDOWN: hDC = GetDC(hWnd); TextOut(hDC, 10, 10, STRLBUTTON, strlen(STRLBUTTON)); ReleaseDC(hWnd, hDC); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
- ベストアンサー
- C・C++・C#
- wsprintf( ポインタ , "%d" , "123" );
char str[100]; char *ptr; wsprintf(str, "%d", "1234567"); と wsprintf(ptr, "%d", "1234567"); について、 TextOut(hDC,0,10,str,lstrlen(str)); TextOut(hDC,0,30,ptr,lstrlen(ptr)); で出力したいんだけど、str ならできたけど、 ptr の方が文字化けしていました。 lstrlen(ptr); がいけないのかと思って、 その値を調べたら 0 でした。 strlen( ) はポインタに対応していると思いました。 #include <iostream.h> main(){ char *p = "あいう"; cout << strlen(p); } で 6 だったから。 Win32 の lstrlen( ) はポインタに対応していないんですか?
- ベストアンサー
- C・C++・C#
- 猫でもわかるWindowsプログラミングの5.2タイピングソフトのプログラムについて
猫でもわかるWindowsプログラミング第3版の5.2タイピングソフトのプログラムなのですが、 本のプログラムをそのまま書くと、タイプミス!の分岐にはいらないんですが、これは本が間違ってるんでしょうか? 付属のCD-ROMのプログラム(本の方とは少し違う)は正しく動いているようですが、 本に書いてある方がなぜ上手くいかないのかが理解できません。 もし本が間違えているなら、どこが間違っているのか教えていただけると助かります。 下のコードは本に書いてあった方のウィンドウプロージャ部を写したものです。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc; PAINTSTRUCT ps; MMTIME mm; switch (msg) { case WM_CREATE: srand((unsigned)time(NULL)); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); TextOut(hdc, 0, 0, szMondai, lstrlen(szMondai)); TextOut(hdc, 0, 40, szInput, lstrlen(szInput)); if(bSeikai) SetTextColor(hdc, RGB(0,0,0)); else SetTextColor(hdc, RGB(255,0,0)); TextOut(hdc,0,80,szCheck,lstrlen(szCheck)); EndPaint(hWnd, &ps); break; case WM_CHAR: if(wp == VK_SPACE && !bStart) { bStart = TRUE; TypeStart(hWnd); break; } if(bStart == FALSE) return DefWindowProc(hWnd, msg, wp, lp); if(wp == VK_ESCAPE) { lstrcpy(szMondai, TEXT("")); lstrcpy(szInput, TEXT("")); lstrcpy(szCheck, TEXT("")); InvalidateRect(hWnd, NULL, TRUE); bStart = FALSE; break; } wsprintf(szInput, TEXT("あなたの入力=\"%c\""), (int)wp); if(szMondai[6] == szInput[14]) { bSeikai = TRUE; mm.wType = TIME_MS; timeGetSystemTime(&mm, sizeof(MMTIME)); dwEnd = mm.u.ms; wsprintf(szCheck, TEXT("反応時間[%dミリ秒]"), dwEnd - dwStart); TypeStart(hWnd); } else { bSeikai = FALSE; MessageBeep(MB_OK); lstrcpy(szCheck, TEXT("タイプミス!")); } InvalidateRect(hWnd, NULL, TRUE); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp,lp)); } return 0; } int TypeStart(HWND hWnd) { int n; MMTIME mm; n = rand() % 26; wsprintf(szMondai, TEXT("問題=\"%c\""), 'a' + n); mm.wType = TIME_MS; timeGetSystemTime(&mm, sizeof(MMTIME)); dwStart = mm.u.ms; InvalidateRect(hWnd, NULL, TRUE); return 0; }
- ベストアンサー
- C・C++・C#
- VOID型をSTRUCTのように
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ HDC hDC; PAINTSTRUCT ps; static void *v = "abcdefg"; switch(msg){ case WM_PAINT: hDC = GetDC(hWnd); TextOut(hDC, 0, 0, (char*)v, strlen((char *)v)); ReleaseDC(hWnd, hDC); ValidateRect(hWnd, NULL); break; これで abcdefg が表示されるけど、defg を表示される方法が 分かりません。 abcdefg の文字列の長さは不明です。 char buf[1000]; のように大きく確保すればいいんだけど、そういうのをせず、 動的にやろうと考えています。 TextOut(hDC, 0, 0, &(((char*)v)+3), strlen((char *)v)-3); だと、メモリ上に配置されなければならない というエラーになります。 よい方法があったら教えてください。
- ベストアンサー
- C・C++・C#
お礼
回答ありがとうございます! 完璧な回答どうもです! すごい参考になりました!ありがとうございます!