• ベストアンサー

(SHORT)

ウインドウプロシージャ内ですが、(SHORT)は何のためについているんでしょうか?(どんな効果がありますか) 教えてください。 case WM_MOUSEWHEEL :     wsprintf(str,TEXT("WHEEL %s"),        ((SHORT)HIWORD(wparam))>0 ? TEXT("↑"):TEXT("↓"));     hdc=GetDC(hwnd);     TextOut(hdc,0,0,str,lstrlen(str));

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.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 型へのキャストはこのような理由で必要となるのです。 ・以上。おわり。

startover
質問者

お礼

回答ありがとうございます! 完璧な回答どうもです! すごい参考になりました!ありがとうございます!

その他の回答 (3)

  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

HIWORDマクロの値はWORDでこれは16ビット符号なし整数です。 SHORTは16ビット符号つき整数です。 符号なしから符号ありへの変換を行っているようです。

startover
質問者

お礼

回答ありがとうございます! 符号なしから符号ありへの変換を行っているようです。 と言うのは、参考になりました! ありがとうございます!

  • tea_sheep
  • ベストアンサー率53% (8/15)
回答No.2

HIWORDマクロが返す値は符号なし整数(WORD型)なので これを符号つき整数であると解釈させるためにSHORTへの キャストを行っています。

startover
質問者

お礼

回答ありがとうございます! 解説どうもでした!

  • stiffels
  • ベストアンサー率34% (25/72)
回答No.1

WORDからSHORTへキャストするのを明示的にやっているのだと思いますよ。

startover
質問者

お礼

回答ありがとうございます! 参考になりました!

関連する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 }

  • 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()もつかっていないのですが。 いつシステムから送られるかご教授をお願いします。

  • 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: からのつながりが ある場合でないと実行されないんですか? ソースのおかしいところがあったら教えてください。

  • 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); は書かなくてもいいですか?

  • リサイズで文字が消えちゃう

    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言語と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'までナル文字を代入し続けたり、いろいろと試したのですが駄目でした。どうかこんな自分にご助力お願いできないでしょうか? どうかお願い致します。

  • なぜ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); }

  • 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( ) はポインタに対応していないんですか?

  • 猫でもわかる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; }

  • 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); だと、メモリ上に配置されなければならない というエラーになります。 よい方法があったら教えてください。