Пытаюсь написать собственное Popup окно.
По-идее, окно должно пропадать с экрана при нажатии левой кнопки мыши, когда курсор находится вне области этого окна. Для этого я использую захват мыши.
Но он ведет себя странно: Если не было нажатия мыши, когда курсор мыши находится в области окна, захватившего мышь, то все работает нормально. В противном случае захват перестает работать.
Код появления выпадающего окна
BOOL CALLBACK ColorPropertiesProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hWndPopup = NULL;
switch(uMsg)
{
case WM_INITDIALOG:
{
hWndPopup = CreateDialogParam(
(HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),
MAKEINTRESOURCE(IDD_COLORPANEL),hWnd,
ColorPanelProc,0);
break;
}
case WM_COMMAND:
{
int nID = LOWORD(wParam);
switch(nID)
{
case IDC_BTMCOLOR:
{
RECT rc, rcBtn;
rc.left = 0;
rc.top = 0;
rc.right = 96;
rc.bottom = 72;
AdjustWindowRect(&rc, GetWindowLong(hWndPopup,GWL_STYLE), FALSE);
MapDialogRect(hWndPopup,&rc);
GetWindowRect(GetDlgItem(hWnd,IDC_BTMCOLOR),&rcBtn);
rc.left = rcBtn.left-(rc.right-rcBtn.right+rcBtn.left)/2;
SetWindowPos(hWndPopup, NULL,
rc.left, rcBtn.bottom, rc.right, rc.bottom,
SWP_SHOWWINDOW | SWP_DRAWFRAME |
SWP_NOOWNERZORDER | SWP_NOZORDER);
SetCapture(GetDlgItem(hWndPopup,IDC_COLORGRID));
MSG msg;
while (IsWindowVisible(hWndPopup) &&
GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hWndPopup, &msg))
{
if((msg.hwnd == hWndPopup) ||
(msg.hwnd == GetDlgItem(hWndPopup,IDC_COLORGRID)))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
InvalidateRect(hWnd,NULL,TRUE);
break;
}
}
break;
}
case WM_DESTROY:
{
DestroyWindow(hWndPopup);
break;
}
default:
{
return FALSE;
}
}
return TRUE;
}
BOOL CALLBACK ColorPanelProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return FALSE;
}
Код события WM_LBUTTONDOWN моего собственного контролера. Больше нигде не использую функцию ReleaseCapture
void ColorPanel::OnLButtonDown(HWND hWnd, int X, int Y)
{
if(GetWindowLong(hWnd,GWL_STYLE) & CPS_POPUP)
{
RECT rc;
GetWindowRect(hWnd,&rc);
POINT pt;
pt.x = X;
pt.y = Y;
ClientToScreen(hWnd,&pt);
if(!PtInRect(&rc,pt))
{
ShowWindow(GetParent(hWnd),SW_HIDE);
ReleaseCapture();
return;
}
}
InvalidateRect(hWnd,NULL,FALSE);
}
Операционная система MS Windows 10
Здравствуйте, Melamed, Вы писали:
M>Пытаюсь написать собственное Popup окно.
M>По-идее, окно должно пропадать с экрана при нажатии левой кнопки мыши, когда курсор находится вне области этого окна. Для этого я использую захват мыши.
300 лет назад Raymond Chen был написал этот вот пример:
https://github.com/pauldotknopf/WindowsSDK7-Samples/tree/master/winui/shell/legacysamples/fakemenu
Базовая идея — просто SetCapture не хватает. Нужно еще
a) это окно показывать как ShowWindow(hwndPopup, SW_SHOWNOACTIVATE); и
b) mouse modal loop крутить :
https://github.com/pauldotknopf/WindowsSDK7-Samples/blob/master/winui/shell/legacysamples/fakemenu/fakemenu.cpp#L442