
質問させて頂きます。
現在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等のメッセージが来た際に破棄する処理を試しても上手く行きません
この場合、マウスをグローバルフックしなければならないでしょうか?
極力フックは避けて解決したいと思っております。
ご教授の程よろしくお願いします。
A 回答 (1件)
- 最新から表示
- 回答順に表示
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;
LPDIRECTINPUT8g_pDI;
LPDIRECTINPUTDEVICE8g_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;
}
machongola様
ソース迄載せて頂き、丁寧なご回答有難うございます。
DirectInputで監視出来る事は知りませんでしたので
DirectInputを調べて試して見たいと思います。
本当に有難うございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) Vba LongPtrについて教えてください 2 2022/08/19 11:14
- gooブログ ブログの記事を書きだしのみに表示したい 1 2022/06/25 19:11
- Excel(エクセル) [貼り付けオプション]とは? 3 2022/04/17 08:15
- その他(IT・Webサービス) どうすればgoogleのポップアップの表示が消えますか? 3 2022/09/11 14:04
- JavaScript [Java] Edgeでのアドレスバー非表示について 3 2022/04/20 17:51
- その他(クラウドサービス・オンラインストレージ) データ保存先をOneDriveからPC本体に変えたらDocumentとPictureフォルダが消えた 1 2023/07/30 15:48
- Visual Basic(VBA) 【ExcelVBA】動的にボタン、ボタン名を生成できますか? 7 2022/04/08 12:54
- Chrome(クローム) 仕事で使っているGmailがログインできません。 ログインすると、 「組織がプロフィールの作成を求め 1 2022/06/16 08:40
- その他(Microsoft Office) Microsoft Edgeの「ニュースと関心事項」についてお聞きします。 3 2023/05/22 12:08
- ノートパソコン Onlineエクセルで右クリックが使えない 1 2023/07/01 22:07
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
cocoa objective-c の return ...
-
コンソールアプリケーションの...
-
不明なエラー
-
COMPORTマルチスレッドで例外発生
-
C言語win32api、エディットボッ...
-
エディットボックスの背景の色...
-
エラー Run-Time Check Failur...
-
Aの値からBの値を除するとは??
-
「Aに対するBの割合」と「Aに対...
-
2÷3などの余りについて
-
数字以外が入力されたらエラー...
-
Enterキーを押されたら次の処理...
-
「指定されたキャストは有効で...
-
複数桁10進数の*桁目だけを抽出...
-
C言語での引数の省略方法
-
fgetsなどのときのstdinのバッ...
-
ある商品のロス率を5%見込み、...
-
プログラムでの数字につく”f”の...
-
java初心者です。入力されたの...
-
C++/STLの動作
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エディットボックスの背景の色...
-
ダイアログプログラムでEnterキ...
-
エラー Run-Time Check Failur...
-
プログラミングでエラーが出ま...
-
ボタンの色(WINAPI)
-
Win32APIでウィンドウを中央に...
-
C言語win32api、エディットボッ...
-
C#のswitch文を簡略化したいの...
-
ウィンドウ非表示に時に表示し...
-
不明なエラー
-
COMPORTマルチスレッドで例外発生
-
WM_CREATE について
-
コンソールアプリケーションの...
-
DialogBox
-
別関数に渡す変数のポインタが...
-
作成プログラムを常にアクティ...
-
ウィンドウのサイズ変更について
-
【Windowsアプリ】ファイルのド...
-
ボタンのアイコン表示
-
オーバーレイみたいな処理がしたい
おすすめ情報