- ベストアンサー
メッセージボックスが何度も表示される理由は?
- スクロールバーを作り下のプログラムのようにSB_LINEDOWN:の所でメッセージボックスを表示するとなぜかメッセージボックスが何個も表示されてしまいます(20個ぐらい)。
- メッセージボックスを表示する行を消し、実行される回数をカウントする変数を記入してデバッグしてみると正常に1回実行されているようです。
- SB_ENDSCROLLの中で表示した場合も正常に1回だけ表示されます。どうしてこうなるのでしょうか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
スクロールバーのメッセージ生成の特殊性と、MessageBoxの弊害が組み合わさって起こる現象のようです。 通常のウィンドウをクリックした場合、メッセージは1回(というか一組)しか送信されませんが、スクロールバーの場合はマウスのボタンを押し続けることでメッセージが連続して発生するようになっています。通常の状態であれば、マウスのボタンを離すことでメッセージの生成は止まるですが、MessageBoxを生成することによって別のメッセージループがメッセージ処理を行うことになり、その際にスクロールバーにボタンが離されたことが通知されなくなってしまいます(生成されたメッセージボックスがアクティブウィンドウになり、ボタンを離したメッセージがそちらに送信されるためだと思います)。そのため、スクロールバーのボタンの上にマウスカーソルがある状態だと、スクロールバーがメッセージを送信し続けてしまうようです。
その他の回答 (2)
- MSZ006
- ベストアンサー率38% (390/1011)
垂直スクロールバーの下矢印▽を押すとそのようになるのですよね。 下矢印を押している間は継続してSB_LINEDOWNがmsgから発せられているので、 ボタンを離すまでの僅かな時間の間でも数回case SB_LINEDOWN:の部分が実行されるのではないでしょうか。
お礼
回答ありがとうございました。 いろいろ試してみましたがcase SB_LINEDOWN:の部分でメッセージボックスを表示しようとするとcase SB_LINEDOWN:の中でのプログラムは正常に動作しなかったです。 なぜだか全く分かりませんがこれはMessageBox関数との相性が悪いと考えるしかなさそうですね。
- m-take0220
- ベストアンサー率60% (477/782)
この部分だけ抜き出されても、原因はわからないですよ。 メッセージループが正しく処理されていなくて、何度も同じメッセージを処理していたり、他のメッセージの処理に問題があるような場合には、その部分のソースがわからないと原因が突き止められません。
補足
これがすべてのソースですがどこかおかしいところがあるでしょうか? #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; }
お礼
回答ありがとうございました。