• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:メッセージボックスが何度も表示される理由は?)

メッセージボックスが何度も表示される理由は?

このQ&Aのポイント
  • スクロールバーを作り下のプログラムのようにSB_LINEDOWN:の所でメッセージボックスを表示するとなぜかメッセージボックスが何個も表示されてしまいます(20個ぐらい)。
  • メッセージボックスを表示する行を消し、実行される回数をカウントする変数を記入してデバッグしてみると正常に1回実行されているようです。
  • SB_ENDSCROLLの中で表示した場合も正常に1回だけ表示されます。どうしてこうなるのでしょうか?

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

  • ベストアンサー
回答No.3

スクロールバーのメッセージ生成の特殊性と、MessageBoxの弊害が組み合わさって起こる現象のようです。 通常のウィンドウをクリックした場合、メッセージは1回(というか一組)しか送信されませんが、スクロールバーの場合はマウスのボタンを押し続けることでメッセージが連続して発生するようになっています。通常の状態であれば、マウスのボタンを離すことでメッセージの生成は止まるですが、MessageBoxを生成することによって別のメッセージループがメッセージ処理を行うことになり、その際にスクロールバーにボタンが離されたことが通知されなくなってしまいます(生成されたメッセージボックスがアクティブウィンドウになり、ボタンを離したメッセージがそちらに送信されるためだと思います)。そのため、スクロールバーのボタンの上にマウスカーソルがある状態だと、スクロールバーがメッセージを送信し続けてしまうようです。

nazoda
質問者

お礼

回答ありがとうございました。

その他の回答 (2)

  • MSZ006
  • ベストアンサー率38% (390/1011)
回答No.2

垂直スクロールバーの下矢印▽を押すとそのようになるのですよね。 下矢印を押している間は継続してSB_LINEDOWNがmsgから発せられているので、 ボタンを離すまでの僅かな時間の間でも数回case SB_LINEDOWN:の部分が実行されるのではないでしょうか。

nazoda
質問者

お礼

回答ありがとうございました。 いろいろ試してみましたがcase SB_LINEDOWN:の部分でメッセージボックスを表示しようとするとcase SB_LINEDOWN:の中でのプログラムは正常に動作しなかったです。 なぜだか全く分かりませんがこれはMessageBox関数との相性が悪いと考えるしかなさそうですね。

回答No.1

この部分だけ抜き出されても、原因はわからないですよ。 メッセージループが正しく処理されていなくて、何度も同じメッセージを処理していたり、他のメッセージの処理に問題があるような場合には、その部分のソースがわからないと原因が突き止められません。

nazoda
質問者

補足

これがすべてのソースですがどこかおかしいところがあるでしょうか? #include<windows.h> LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); TCHAR szWinName[] = TEXT("MyWin"); int WINAPI WinMain(HINSTANCE hThisInst,HINSTANCE hPrevInst, LPSTR lpszArgs,int nWinMode) { HWND hwnd; MSG msg; WNDCLASS wcl; wcl.hInstance = hThisInst; wcl.lpszClassName = szWinName; wcl.lpfnWndProc = WndProc;//ウィンドウプロシージャ wcl.style = 0; wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcl.hCursor = LoadCursor(NULL,IDC_ARROW); wcl.lpszMenuName = NULL; wcl.cbClsExtra = 0; wcl.cbWndExtra = 0; wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); if(!RegisterClass (&wcl)) return 0; hwnd =CreateWindow( szWinName, TEXT("スクロールバーのテスト"), WS_OVERLAPPEDWINDOW | WS_HSCROLL |WS_VSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hThisInst, NULL ); ShowWindow(hwnd,nWinMode); UpdateWindow(hwnd); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd,UINT message, WPARAM wParam,LPARAM lParam) { switch(message){ case WM_VSCROLL: switch(LOWORD(wParam)){ case SB_LINEDOWN: MessageBox(NULL,TEXT("スクロールバーのテスト中"),TEXT("メッセージボックス"),MB_OK); break; } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,message,wParam,lParam); } return 0; }