- ベストアンサー
2重Func禁止。クリセク。セマフォ。
MyFunc( ) の実行中は WM_LBUTTONDOWN を無視されるように しようと思いました。 LRESULT CALLBACK WndProc(… { static bool b = TRUE; switch(msg){ case WM_LBUTTONDOWN: if(b){ b = FALSE; MyFunc( ); // MessageBox(hWnd, "", "", MB_OK); b = TRUE; } break; でもこれでは、例えば MyFunc( ) が実行中に3回クリックすると その後に MyFunc( ) は3回実行されてしまいます。 MessageBox( ) を使えばうまくいくけと、それは使いたくありません。 できるだけ簡単なソースで、 MyFunc( ) の実行中のクリックで、後で MyFunc( ) が 実行されないようにするにはどこを直したらいいですか?
- A__
- お礼率59% (194/328)
- C・C++・C#
- 回答数5
- ありがとう数4
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
一応 terra5 さんのおっしゃっているヤツです。 --------------------------------------------- void XXFunc(HWND hwnd) // メッセージキュー削除 { MSG msg; // while(PeekMessage(&msg, hwnd, // WM_MOUSEFIRST, WM_MOUSELAST, // PM_REMOVE)); while(PeekMessage(&msg, hwnd, WM_LBUTTONDOWN, WM_LBUTTONDBLCLK, PM_REMOVE)); } --------------------------------------------- でも確かにあんまりお勧めできません。 素直にメッセージボックス出しといた方が良いような。
その他の回答 (4)
>お勧めでないのはどうしてですか? いえ、解決したんでしたら良いです。 システムのメッセージループに関わる部分自体をイジる のは避けたいという感覚があるので、というだけです。 ユーザインターフェース動作の方針そのものを変更した 解決の方が、できれば望ましいので。 その部分の動作については仕様上譲れないという状況で あるのなら、全然問題無いと思います。
お礼
ありがとうございます。
- itohh
- ベストアンサー率45% (210/459)
こんにちは。itohhといいます。 ボタンの押下を無効にしてしまうのはダメなのでしょうか? >LRESULT CALLBACK WndProc(… >{ > static bool b = TRUE; > switch(msg){ > case WM_LBUTTONDOWN: > if(b){ > b = FALSE; HWND hwBtn = GetDlgItem(hWnd, IDC_BTN_XXX ); // (1) EnableWindow(hwBtn, FALSE ); // (2) > MyFunc( ); EnableWindow(hwBtn, TRUE ); // (3) >// MessageBox(hWnd, "", "", MB_OK); > b = TRUE; > } > break; (1) ボタン(IDC_BTN_XXX)のハンドルを取得する。 (2) マウス入力とキーボード入力を無効する。 (3) マウス入力とキーボード入力を有効する。 これで、MyFunc関数が完了するまでボタンを押下することが出来なくなります。
お礼
ありがとうございます。 今回の場合はボタンは無く、マウスクリックで 関数を実行するんだけど、ボタンクリックで 関数起動だったとしたら、ボタンを非活性にする法も使えますね。
- terra5
- ベストアンサー率34% (574/1662)
>クリックの回数はストックされていて、 >その回数だけ必ず MyFunc( ) が実行されてしまうんです。 それは、未処理のメッセージがあるためでしょうね。 MyFunc()終了後、バッファにたまっているメッセージをクリアするような処理が必要でしょう。 もしくは、処理を開始した時点で一時的にクリックで メッセージが発生しないようにしておき、 終わった時点で元に戻すとか。 今手元には参考になるものが無いので、 具体的にどうするかはわかりませんが(^^;
- terra5
- ベストアンサー率34% (574/1662)
多分この程度で大丈夫でしょう。 > static bool b = TRUE; static int b = 0; > if(b){ if(!b){ > b = FALSE; b++; > b = TRUE; b--; Windowsは詳しくないんですが, 多分マルチスレッドを使わなければ、 クリティカルセクションもセマフォも不要でしょう。
お礼
ありがとうございます。 int もやってみたけど、bool と同じく、 クリックの回数はストックされていて、 その回数だけ必ず MyFunc( ) が実行されてしまうんです。
関連するQ&A
- デスクトップをサブクラス
デスクトップ以外のサブクラスなら何度もやったことがあります。 DLLを使わずにデスクトップをサブクラスにできますか? DLLを使わずにデスクトップをサブクラス化しようとしたけど、 サブクラスの対象がデスクトップだと特殊なのか、 サブクラスにできていないみたいでした。 MessageBeep(0xFFFFFFFF); が実行されなかったからそう思いました。 FARPROC Org_Proc; LRESULT CALLBACK DeskProc(HWND, UINT, WPARAM, LPARAM); OrgProc = (FARPROC)GetWindowLong(HWND_DESKTOP, GWL_WNDPROC); SetWindowLong(HWND_DESKTOP, GWL_WNDPROC, (LONG)DeskProc); LRESULT CALLBACK DeskProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { if(msg == WM_LBUTTONDOWN)MessageBeep(0xFFFFFFFF); return CallWindowProc((WNDPROC)Org_Proc, hWnd, msg, wp, lp); }
- ベストアンサー
- C・C++・C#
- wsprintf( ) でポインタに代入
wsprintf(p, "%d" , i); を書いたせいで、i の値が変わります。 wsprintf(p, "%d" , i); によってどんなことが起こっているのか詳しく知りたいです。 ポインタのことがまだよく分かってないんです。 #include <windows.h> LPCSTR szStr = "\n char c[255];\n char *p = \"\\0\";\n int i = 12345;\n\n switch (msg){\n case WM_LBUTTONDOWN:\n wsprintf(c, \"%d\" , i);\n wsprintf(p, \"%d\" , i);\n MessageBox(hWnd , c , \"\" , MB_OK);\n break;"; LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM); int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE , LPSTR , int){ 省略 return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam){ HDC hDC; PAINTSTRUCT ps; RECT rt; char c[255]; char *p = "\0"; int i = 12345; switch (msg){ case WM_LBUTTONDOWN: wsprintf(c, "%d" , i); wsprintf(p, "%d" , i); MessageBox(hWnd , c , "" , MB_OK); break; case WM_PAINT: GetClientRect(hWnd, &rt); hDC = BeginPaint(hWnd, &ps); DrawText(hDC, szStr, lstrlen(szStr), &rt, DT_WORDBREAK); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd , msg , wParam , lParam)); } return (0L); }
- ベストアンサー
- C・C++・C#
- MessageBoxについて
次のようなプログラムを作りました。 /*ウィンドウプロシージャ内*/ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ ・・・ case WM_LBUTTONDOWN: hantei(hWnd); break; ・・・ } /* 判定関数 */ void hantei(HWND hWnd){ MessageBox(hWnd,"テスト","テストです。",MB_OK); } このようになって動かしてみた(左クリックした)ところ、 ウィンドウ自体は非アクティブになったのですが、 BEEP音が鳴るだけで肝心のメッセージボックスが表示されません。 ALTキーを押すと表示されるのですが・・・ 左クリックをするとすぐにメッセージボックスを表示させるにはどうしたらよいのでしょう? 言葉足らずの説明かもしれませんがお願いします。
- ベストアンサー
- C・C++・C#
- 自作関数から WndProc( ) を止める
自作関数から WndProc( ) を止めるにはどうしたらいいんですか? LRESULT CALLBACK WndProc(…){ switch(msg){ case WM_COMMAND: if(function f( ) == "END")return 0; 処理A; break; } } function f( ){ return "END" } こんな流れにしたいけど、WndProc( ) 内からでなく、 外から WndProc( ) を止めたいんです。 LRESULT CALLBACK WndProc(…){ switch(msg){ case WM_COMMAND: function f( ); 処理A; break; } } function f( ){ ? // WndProc( ) に return 0 とさせて 処理A を実行させない }
- ベストアンサー
- C・C++・C#
- DragQueryFile()でエラー
現在、VC++2005SP1でダイアログベースのアプリを書いていますが、エディットコントールでのドラッグアンドドロップの実装で躓いています。なぜかDragQueryFile()で-1が返って来て直後にGetlastError()を呼ぶと6(無効なハンドル)が返って来ます。 現象の再現を確認しながらコードを以下のレベルまで簡略にしました。 どこかまずいところがあればご教示頂きたく思います。 #include "stdafx.h" #include <stdio.h> #include <locale.h> #include <shellapi.h> #include "Resource.h" TCHAR input_file[MAX_PATH]; void InitDialog( HWND hWnd ); LRESULT CALLBACK MyDragDropProc( HWND, unsigned, WORD, LONG ); WNDPROC lpfnOldEditProc; LRESULT CALLBACK DlgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp); int APIENTRY _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, int nCmdShow ) { _tsetlocale(LC_ALL, _T("")); INT_PTR dret = DialogBox(hInst, MAKEINTRESOURCE( IDD_DIALOG ), NULL, (DLGPROC)DlgProc ); return 0; } LRESULT CALLBACK DlgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_INITDIALOG: InitDialog( hWnd ); return TRUE; case WM_COMMAND: switch (LOWORD(wp)) { case IDOK: EndDialog(hWnd, IDOK); return TRUE; case IDCANCEL: EndDialog(hWnd, IDCANCEL); return TRUE; } } return FALSE; } void InitDialog( HWND hWnd ) { DragAcceptFiles( GetDlgItem( hWnd, IDC_EDIT_INPUT_FILE ), TRUE ); lpfnOldEditProc = (WNDPROC)SetWindowLong( GetDlgItem( hWnd, IDC_EDIT_INPUT_FILE ), GWL_WNDPROC, (LONG)MyDragDropProc ); } LRESULT CALLBACK MyDragDropProc( HWND hWnd, unsigned msg, WORD wp, LONG lp ) { UINT wFilesDropped; HDROP hDrop = (HDROP)wp; TCHAR buff[256]; int err; switch ( msg ) { case WM_DROPFILES: wFilesDropped = DragQueryFile( hDrop, (UINT)-1, NULL, 0 ); err = GetLastError(); _itot_s( err, buff, 256, 10 ); MessageBox( NULL, buff, NULL, MB_OK ); wFilesDropped = DragQueryFile( (HDROP)wp, 0, input_file, MAX_PATH ); MessageBox( hWnd, input_file, NULL, MB_OK ); DragFinish( hDrop ); break; default: return CallWindowProc( (WNDPROC)lpfnOldEditProc, hWnd, msg, wp, lp ); } return 0; }
- 締切済み
- C・C++・C#
- 子ウインドウの作成と破棄について
CALLBACK のみを書きました。 メインウインドウを破棄したら 子ウインドウも破棄したいのですが、 うまく出来ません。 どうすればよろしいでしょうか? よろしくお願いします。 #include<windows.h> #include"ChildWindow.h" char MainWindowClassName[]="mainwindow"; LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { static HWND childWnd; switch(message) { case WM_ACTIVATEAPP: childWnd=Child_CreateWindow(hWnd,message,wParam,lParam); break; case WM_DESTROY: DestroyWindow(childWnd); PostQuitMessage(0); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } } ///////////////////////////////////////////// #include<windows.h> char ChildWindowClassName[]="childwindow"; LRESULT CALLBACK ChildProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: MessageBox(NULL,"","",MB_OK); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } } ATOM Child_RegistWindow(HINSTANCE hInstance){} HWND Child_InitInstance(HWND hParentWnd,HINSTANCE hInst,int CmdShow){} HWND Child_CreateWindow(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { int CmdShow=1; Child_RegistWindow(NULL); HWND ChildWnd=Child_InitInstance(hWnd,NULL,CmdShow); MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return ChildWnd; }
- ベストアンサー
- C・C++・C#
- BCC32 右クリ イベント
LRESULT CALLBACK WinWin(HWND hwnd,UINT mess,WPARAM wParam,LPARAM lParam) { switch(mess){ case WM_LBUTTONDOWN: 処理; break; これで、ウインドウ上でクリックした時の処理が実行できたけど。 ウインドウ上で右クリックした時の処理をさせるためには どういうソースを書けばいいのか教えてください。 case WM_RBUTTONDPWN: ではコンパイルエラーになりました。
- ベストアンサー
- 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#
- 何もしないメッセージだけ表示するウィンドウ
ゲーム用に何もしないメッセージだけ表示するウィンドウを作りたいのですが、 猫でもわかるゲームプログラミングのコードが間違っているのか、 機能しません。 #include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp); int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg){ } return 0; } このように、打ち込んだのですが、どこが間違っているのか解りません。 回答お願いいたします。
- ベストアンサー
- その他([技術者向] コンピューター)
- CallNextHookEx( ) == FALSE
1つのアプリの中で、メインプロージャとフックプロージャを作りました。 フックはキーボードフックです。 HHOOK hHook; LRESULT CALLBACK MyHookProc(int nCode, WPARAM wParam, LPARAM lParam){ if(nCode < 0)return CallNextHookEx(hHook, nCode, wParam, lParam); if(wParam == 0x31)return FALSE; return TRUE; } フックしていても 「ぬ」 のキーは使えるようにしました。 if(wParam == 0x31)return FALSE; は if(wParam == 0x31)return CallNextHookEx(hHook, nCode, wParam, lParam); にしても違いが分かりませんでした。 return FALSE では、メッセージをキューから削除らしいけど、メインの プロージャで LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg){ case WM_KEYDOWN: if(wParam == 0x31)MessageBox(hWnd, "メインプロージャから", "", MB_OK); break; にしても、フックプロージヤの戻り値は CallNextHookEx( ) でも FALSE でも MessageBox() は表示されました。 CallNextHookEx( ) にした場合と FALSE にした場合、何が違うのか、 どういうソースなら違いを確かめられるのか教えてください。
- 締切済み
- C・C++・C#
補足
ありがとうございます。 その方法で解決しました。 お勧めでないのはどうしてですか?