• 締切済み

ウィンドウ非表示に時に表示したポップアップメニューを閉じるには?

質問させて頂きます。 現在C++にてWin32SDKを使用し開発を行っております そこで、メインウィンドウが非表示の時にポップアップメニューを表示するようにしているのですが 非表示の際、ホットキーを起因にポップアップメニューを表示すると ポップアップメニュー以外をクリックしても消えますが WM_TIMER等、一定時間経過時に表示した場合 ポップアップメニュー以外をクリックしても消えません 下記が一部コードを抜粋した物です case WM_CREATE: hMenu = CreatePopupMenu( ); AppendMenu( hMenu, MF_STRING, 0x01, TEXT("HOGE1") ); AppendMenu( hMenu, MF_STRING, 0x02, TEXT("HOGE2") ); return 0; case WM_HOTKEY: GetCursorPos( &pos ); SetForegroundWindow( hWnd ); TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN, pos.x, pos.y, 0, hWnd, NULL ); return 0; case WM_TIMER: GetCursorPos( &pos ); SetForegroundWindow( hWnd ); TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN, pos.x, pos.y, 0, hWnd, NULL ); return 0; ホットキーの設定と、タイマーの設定の処理を付随しておりませんが ホットキー、タイマーの処理は同じものです ポップアップメニューを表示の際、WM_INITMENUPOPUPからポップアップメニューをサブクラス化し WM_KILLFOCUS等のメッセージが来た際に破棄する処理を試しても上手く行きません この場合、マウスをグローバルフックしなければならないでしょうか? 極力フックは避けて解決したいと思っております。 ご教授の程よろしくお願いします。

みんなの回答

回答No.1

 こんにちは。  DirectInputとスレッドで出来ると言えば出来ます。ただ、マウスもキーボードもするとなるとグローバルフックの方が楽かもしれません。  以下はマウスだけですが、ポップアップは確かに消えます。ただ、大分アラもあるとは思うので、参考程度でお願いします。 #define DIRECTINPUT_VERSION 0x0800 #include<windows.h> #include<dinput.h> #include<commctrl.h> #include"resource.h" #pragma comment(lib, "comctl32.lib") #pragma comment(lib, "dinput8.lib") #pragma comment(lib, "dxguid.lib") const DWORD dwTIMER_OPEN = 1000; LPDIRECTINPUT8 g_pDI; LPDIRECTINPUTDEVICE8 g_pMouse; //スレッド DWORD WINAPI ThreadProc(LPVOID p) { HWND hWnd = (HWND)p; while(::IsWindow(hWnd)) { DIMOUSESTATE2 dims; HRESULT hr = g_pMouse->GetDeviceState(sizeof(DIMOUSESTATE2), &dims); if(SUCCEEDED(hr)) { //マウス左or中央or右クリック if(dims.rgbButtons[0] || dims.rgbButtons[1] || dims.rgbButtons[2]) { //ポップアップがあれば消す HWND hWndPopup = FindWindow("#32768", NULL); if(hWndPopup && IsWindowVisible( hWndPopup ) ) { SendMessage(hWndPopup, WM_KEYDOWN, VK_ESCAPE, 0); } } } } return 0; } //DirectInput初期化 static BOOL DI_Init(HWND hWnd, HINSTANCE hInst) { HRESULT hr = DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_pDI, NULL); if(FAILED(hr)) return FALSE; hr = g_pDI->CreateDevice(GUID_SysMouse, &g_pMouse, NULL); if(FAILED(hr)) return FALSE; hr = g_pMouse->SetDataFormat(&c_dfDIMouse2); if(FAILED(hr)) return FALSE; //バックグラウンドモードで全てのマウスを拾う hr = g_pMouse->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); if(FAILED(hr)) return FALSE; //軸モードを設定(相対値モードに設定) DIPROPDWORD diprop = {sizeof(DIPROPDWORD)}; diprop.diph.dwHeaderSize= sizeof(diprop.diph); diprop.diph.dwObj = 0; diprop.diph.dwHow = DIPH_DEVICE; diprop.dwData = DIPROPAXISMODE_REL; g_pMouse->SetProperty(DIPROP_AXISMODE, &diprop.diph); return SUCCEEDED(hr); } //ウィンドウクラス登録 static ATOM Regist(LPCTSTR szClassName, WNDPROC wndProc) { WNDCLASSEX wndclass = {sizeof(wndclass)}; wndclass.hCursor = ::LoadCursor(NULL,IDC_ARROW); wndclass.hIcon = NULL; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szClassName; wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH); wndclass.hInstance = ::GetModuleHandle(NULL); wndclass.style = 0; wndclass.lpfnWndProc = wndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; return ::RegisterClassEx(&wndclass); } //ウィンドウを作成して開く static HWND OpenWindow(LPCTSTR szClassName, LPCTSTR szTitleName, INT w, INT h) { HINSTANCE hInst = ::GetModuleHandle(NULL); HWND hWnd = ::CreateWindowEx(WS_EX_TOOLWINDOW, szClassName, szTitleName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT, w, h, NULL, NULL, hInst, NULL); return hWnd; } LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HMENU hMenu = CreatePopupMenu(); POINT pos; switch(uMsg) { case WM_CREATE: AppendMenu( hMenu, MF_STRING, 0x01, TEXT("HOGE1") ); AppendMenu( hMenu, MF_STRING, 0x02, TEXT("HOGE2") ); SetTimer(hWnd, dwTIMER_OPEN, 1000, NULL); ::DI_Init(hWnd, ::GetModuleHandle(NULL)); g_pMouse->Acquire(); break; case WM_HOTKEY: GetCursorPos( &pos ); SetForegroundWindow( hWnd ); TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN, pos.x, pos.y, 0, hWnd, NULL ); break; case WM_CLOSE: ::DestroyWindow(hWnd); break; case WM_NCDESTROY: ::PostQuitMessage(0); break; case WM_COMMAND: switch(LOWORD(wParam)) { case 0x01: ::MessageBox(hWnd, "0x01", "0x01", IDOK); break; case 0x02: ::MessageBox(hWnd, "0x02", "0x02", IDOK); break; } break; case WM_TIMER: switch(wParam) { case dwTIMER_OPEN: KillTimer(hWnd, wParam); GetCursorPos( &pos ); SetActiveWindow( hWnd ); SetForegroundWindow( hWnd ); TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN, pos.x, pos.y, 0, hWnd, NULL ); SetTimer(hWnd, wParam, 1000, NULL); break; } break; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hInstancePrev, LPSTR lpCmdLine, int nShowCmd) { MSG msg; const TCHAR tstrClassName[] = TEXT("test resize frame"); const TCHAR tstrTitleName[] = TEXT("title"); ::InitCommonControls(); //ウィンドウクラスの登録 ::Regist(tstrClassName, &::WndProc); //ウィンドウを作成して開く HWND hWnd = ::OpenWindow(tstrClassName, tstrTitleName, 800, 600); //ウィンドウの表示 ::ShowWindow(hWnd, SW_SHOW); //スレッドを回す DWORD id = 0; HANDLE hThread = ::CreateThread(NULL, 0, ThreadProc, hWnd, 0, &id); ::SetThreadPriority(hThread, THREAD_PRIORITY_LOWEST); //メッセージ回転 while(::GetMessage(&msg, NULL, 0, 0) == TRUE) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } //到着を待つ ::WaitForSingleObject(hThread, INFINITE); ::CloseHandle(hThread); //DirectInputの解放 g_pMouse->Release(); g_pDI->Release(); //終了 return msg.wParam; }

minomino_a
質問者

お礼

machongola様 ソース迄載せて頂き、丁寧なご回答有難うございます。 DirectInputで監視出来る事は知りませんでしたので DirectInputを調べて試して見たいと思います。 本当に有難うございました。

関連するQ&A

  • ポップアップメニュー

    NotifyIconでタスクバーに呼び出したアイコンの上で右クリックをしたら、ポップアップメニューが表示させるように作りたいのですが、作り方が分かりません。(サイトなどを見たりしました。) 出きれば教えて頂きたいと思います。 *何をしたいのか↓ タスクトレイで表示されたアイコンを右クリックをするとポップアップメニューが出る。 ・環境 Microsoft Visual C++ SDK HINSTANCE hInst; POINT point; static HMENU hMenu,hSubMenu; /////////////////省略/////////////////// case WM_RBUTTONDOWN:  hMenu = LoadMenu(hInst,"MENUDATA");  hSubMenu = GetSubMenu(hMenu,0);  point.x = LOWORD(lParam);  point.y = LOWORD(lParam);  TrackPopupMenu(hSubMenu,TPM_LEFTALIGN,point.x,point.y,0,hWnd,NULL); break; これではうまくいかないのでご助言お願いします。

  • WM_TIMERからポップアップメニューを閉じるには?

    質問させて頂きます。 現在C++にてWin32SDKを使用し開発を行っております そこで、メインウィンドウが非表示の時にもポップアップメニューを表示するようにしているのですが 非表示の際、ホットキーからポップアップメニューを表示すると ポップアップメニュー以外をクリックしても消えますが WM_TIMER等、一定時間経過時に表示した場合 ポップアップメニュー以外をクリックしても消えません WM_HOTKEYでは SetForegroundWindow関数でアクティブにした後に TrackPopupMenu関数でポップアップメニューを表示して 関係ない所をクリックされてもうまく消えます WM_TIMERでもWM_HOTKEYと同じ処理をしても上手くいきません タスクトレイの右クリックと同じく TrackPopupMenu関数の後にWM_NULLをポストしてもメニューは消えません 何か上手く解決出来る方法は無いでしょうか? どうぞよろしくお願いします。

  • タスクバーのメニュー表示

    Visual C++ 6.0 MFCにて質問があります。 [環境] Visual C++ 6.0 MFC [タスクバーのアイコンの処理] リソースにMenuを作成して、以下のソースを作成いたしました。しかし、タスクバーのアイコンをクリックして、Menuが表示されるはずなのですが、途中でエラーが出てしまいます。CMenu* pMenu;がうまく処理されていないみたいなのですが、ソース的に問題ないように思うのですが.... 何か問題があるのでしょうか?? [ソース] CMenu MyMenu; CMenu* pMenu; POINT pt; // 現在のカーソル位置を取得 ::GetCursorPos(&pt); // フォーカスを当てる SetFocus(); // メニューのロード VERIFY(MyMenu.LoadMenu(IDR_MENU1)); // 0番目のメニューを取得 pMenu = MyMenu.GetSubMenu(0); ASSERT(pMenu != NULL); <-- ここでエラーがでる。 // メニューの表示 if(pMenu->TrackPopupMenu( TPM_LEFTALIGN| TPM_RIGHTBUTTON, pt.x, pt.y , this) == 0){ return FALSE; } // メッセージを送る PostMessage(WM_NULL); return TRUE;

  • ポップアップメニュー

    ポップアップメニューについて質問させて頂きます。 リストビュー上で右クリックしたときにポップアップメニューを表示させているのですが、このポップアップメニューの項目がクリックされた時のイベントの取り方が分かりません。 ご存知の方、宜しくお願いします。 環境はVisual Studio6.0 Windows2000です

  • ポップアップメニューで

    DreamweaverMX2004で作成しております。 そのなかでポップアップメニューを作成しました。 またFlashのファイルも挿入してあります。 ポップアップメニューがFlashに重なると、 FLASHの下に表示され、メニューが見えない状態です。 FLASHの上に表示することはできないでしょうか? よろしくお願いします。

    • ベストアンサー
    • HTML
  • Dreamweaverでポップアップメニューが・・・

     Dreamweaver8でホームページを作成しているのですが、ポップアップメニューの表示で困っています。  メニューバーにマウスポインタを合わせると下向きにポップアップメニューが表示されるようにしているのですが、メニューバーの下段にはFlashムービーがはりつけてあり、ポップアップメニューがFlashムービーの背面に表示されてしまいます。ポップアップメニューをFlashムービーの前面に表示させるいい方法がありましたら教えてください。  ちなみにポップアップメニューは「ビヘイビア→ポップアップメニューを表示ページ」にて作成。レイアウトはセンター揃えのレイアウトとなっております。  以上、どなたか解決策をご存知の方はよろしくお願いいたします。

    • ベストアンサー
    • CSS
  • ポップアップメニューがおかしいです。

    ポップアップメニューや右クリックメニューが透明に表示されています。見にくくてしょうがありません。だれか助けてください。。。。

  • Fireworksでポップアップメニュー

    FireworksMXでポップアップメニューを作りDWとかでその下にSWFを入れるとポップアップメニューの上にSWfが表示されてしまいます。 ポップアップの下に表示させていのですが、どなたかわかる方いませんか? 画像だとちゃんと表示できます。教えてください。

  • ショートカットメニューについて

    TrackPopupMenu()APIと、GetCursorPos()APIなどを使って、カーソルの位置にメニューを表示することはできたのですが、表示した後にメニュー以外の場所をクリックしたら消す動作をさせたいのですが、どうしてもできません。 だれか教えてください。

  • ポップアップメニュー

    センター寄せのホームページで、プルダウン形式のポップアップメニューを表示したいのですが、なにか解説しているホームページはないでしょうか? 通常、ポップアップメニューを作成する場合には、左上からの絶対座標を指定する形で作成しており、センター寄せでは、できないと言い切っていました。しかし、最近センター寄せのホームページでポップアップメニューのあるものを見てしまったので、実際にはできるのだと思った次第であります。 http://www.cubesystem.co.jp/ 2階層以下のページがセンター寄せのポップアップメニューになってます。

専門家に質問してみよう