
質問させて頂きます。
現在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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
DLLファイルの逆コンパイラにつ...
-
プログラマー達は何故、プログ...
-
C言語の関数のextern宣言
-
卒業研究でよく分からないとこ...
-
C言語 関数、変数の宣言について
-
C言語について(初心者)
-
C言語のことです。写真(見にく...
-
Windows Formアプリからコンソ...
-
DNCL(共テ用プログラミング言語...
-
C言語について。
-
visual studio 2022でのC#プロ...
-
あってる
-
DNCL(共テ用プログラミング言語...
-
C# で 数式文字列処理を処理す...
-
gccを行ってもexeファイルが生...
-
c言語
-
C言語 列挙型(enum型)変数について
-
C++でデスクトップGUIアプリ開...
-
c言語でイベントフラグを使った...
-
必ずyou bet と表示されます
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c言語
-
DLLファイルの逆コンパイラにつ...
-
Windows Formアプリからコンソ...
-
大量のデータを読み込んで表示...
-
C言語の関数のextern宣言
-
VisualStudioでC++クラスを追加...
-
【C言語】全角文字の配列を、全...
-
VisualStudio2022でC言語プログ...
-
C++でデスクトップGUIアプリ開...
-
gccを行ってもexeファイルが生...
-
C#でTreeViewのCheckBoxのサイ...
-
C#でログファイルにファイルパ...
-
プログラマー達は何故、プログ...
-
逆コンパイルと逆アセンブルの...
-
Notepad++の関数リスト表示の変...
-
C言語について。
-
Cのコンパイルでコメントアウト...
-
visual studio 2022でのC#プロ...
-
コンソールアプリを作成するの...
-
C言語 バッファについて。
おすすめ情報