[英]How can I open and close a popup menu when I click on a window in win32 api?
我用win32 api做了一個小窗口,當我點擊窗口時想打開一個彈出菜單。 當我再次單擊它時,如果菜單仍然打開,我想關閉它。
我在WM_LBUTTONUP上打開菜單,因為我想在WM_LBUTTONDOWN上拖動窗口。
我知道WM_ENTERMENULOOP和WM_EXITMENULOOP菜單何時出現或消失。
我知道如何以編程方式關閉菜單,但不幸的是我不知道如何決定菜單是在WM_LBUTTONUP上打開還是關閉。 問題是菜單在WM_LBUTTONDOWN時自動關閉,這就是為什么我無法保存菜單的當前狀態。
如果有人提示如何解決這個問題,那就太好了。
附加信息:
整個窗口是一個無邊界的客戶區,上面畫有位圖
hWnd = CreateWindowExW(WS_EX_TOPMOST, L"MyWindow", 0, WS_POPUP, wndPosX, wndPosY, m_WndWidth, m_WndHeight, 0, 0, m_hInst, 0);
位圖在窗口的 WindowProcedure 中的WM_CREATE上加載,並在WM_PAINT上繪制
m_hBitmap = (HBITMAP)LoadImageA(NULL, "MyBitmap.bmp", IMAGE_BITMAP, m_WndWidth, m_WndHeight, LR_LOADFROMFILE);
默認情況下窗口不可拖動,因為我沒有非客戶區,這就是為什么我根據當前光標位置在WM_MOUSEMOVE 上手動移動窗口
在WM_LBUTTONUP我在窗口頂部創建彈出菜單
HMENU hPopupMenu = CreatePopupMenu(); InsertMenuW(hPopupMenu, 0, MF_BYPOSITION | MF_STRING, ID_ITEM_A, L"ItemA"); SetForegroundWindow(hWnd); RECT wndRect; GetWindowRect(hWnd, &wndRect); TrackPopupMenu(hPopupMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, wndRect.left, wndRect.top, 0, hWnd, NULL);
這是使用 WindowsHooks 進行鼠標事件的解決方案您必須在窗口客戶區中捕獲鼠標按下事件並跳過下一個鼠標按下事件
在全球范圍內
static HHOOK hMouseHook = 0;
static HWND hMainWindow = 0;
static int nSkipClick = 0;
LRESULT CALLBACK MouseProc(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
if (nCode < 0)
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
if (wParam == WM_LBUTTONDOWN) {
MOUSEHOOKSTRUCT* p = (MOUSEHOOKSTRUCT*)lParam;
if (WindowFromPoint(p->pt) == hMainWindow) {
POINT pt = p->pt;
ScreenToClient(hMainWindow, &pt);
RECT rct;
GetClientRect(hMainWindow, &rct);
if (PtInRect(&rct, pt))nSkipClick = 1;
}
}
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
在 WndProc
case WM_LBUTTONUP:
if (nSkipClick == 0) { // menu not shown before
hMouseHook = SetWindowsHookEx(WH_MOUSE, &MouseProc, NULL, GetCurrentThreadId());
hMainWindow = hWnd;
HMENU hPopupMenu = CreatePopupMenu();
InsertMenuW(hPopupMenu, 0, MF_BYPOSITION | MF_STRING, ID_ITEM_A, L"ItemA");
SetForegroundWindow(hWnd);
RECT wndRect;
GetWindowRect(hWnd, &wndRect);
TrackPopupMenu(hPopupMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, wndRect.left, wndRect.top, 0, hWnd, NULL);
UnhookWindowsHookEx(hMouseHook);
hMouseHook = 0;
}
else {
nSkipClick = 0;
}
break;
我希望這是你想做的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.