winapi无边框窗口添加标题栏右键菜单
要在winapi无边框窗口上添加标题栏右键菜单,可以使用以下步骤:
-
注册一个新的窗口类,设置窗口样式为无边框(WS_POPUP)。
-
在窗口创建消息(WM_CREATE)中创建一个自定义菜单和一个弹出菜单。
-
在窗口绘制消息(WM_PAINT)中绘制标题栏,并在标题栏上绘制菜单按钮。
-
在鼠标消息(WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP)中处理菜单按钮的状态和显示弹出菜单。
-
在菜单消息(WM_COMMAND)中处理菜单项的操作。
以下是示例代码:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
// 创建自定义菜单
HMENU hMenu = CreateMenu();
AppendMenu(hMenu, MF_STRING, ID_MENU_ITEM_1, L"Menu Item 1");
AppendMenu(hMenu, MF_STRING, ID_MENU_ITEM_2, L"Menu Item 2");
// 创建弹出菜单
HMENU hPopupMenu = CreatePopupMenu();
AppendMenu(hPopupMenu, MF_STRING, ID_MENU_ITEM_1, L"Menu Item 1");
AppendMenu(hPopupMenu, MF_STRING, ID_MENU_ITEM_2, L"Menu Item 2");
// 保存菜单句柄
SetProp(hWnd, L"CustomMenu", (HANDLE)hMenu);
SetProp(hWnd, L"PopupMenu", (HANDLE)hPopupMenu);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// 绘制标题栏
RECT rcClient;
GetClientRect(hWnd, &rcClient);
RECT rcTitle = {0, 0, rcClient.right, TITLEBAR_HEIGHT};
HBRUSH hTitleBrush = CreateSolidBrush(TITLEBAR_COLOR);
FillRect(hdc, &rcTitle, hTitleBrush);
DeleteObject(hTitleBrush);
// 绘制菜单按钮
HMENU hMenu = (HMENU)GetProp(hWnd, L"CustomMenu");
RECT rcMenu = {rcClient.right - MENU_BUTTON_WIDTH, 0, rcClient.right, TITLEBAR_HEIGHT};
DrawFrameControl(hdc, &rcMenu, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_ADJUSTRECT);
DrawMenuBar(hWnd);
EndPaint(hWnd, &ps);
}
break;
case WM_MOUSEMOVE:
{
// 在菜单按钮上显示弹出菜单
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
RECT rcMenu = {rcClient.right - MENU_BUTTON_WIDTH, 0, rcClient.right, TITLEBAR_HEIGHT};
if (PtInRect(&rcMenu, {x, y}))
{
HMENU hPopupMenu = (HMENU)GetProp(hWnd, L"PopupMenu");
TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, x, y, 0, hWnd, NULL);
}
}
break;
case WM_LBUTTONDOWN:
{
// 按下菜单按钮,改变按钮状态
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
RECT rcMenu = {rcClient.right - MENU_BUTTON_WIDTH, 0, rcClient.right, TITLEBAR_HEIGHT};
if (PtInRect(&rcMenu, {x, y}))
{
SetCapture(hWnd);
SetProp(hWnd, L"MenuPressed", (HANDLE)TRUE);
InvalidateRect(hWnd, &rcMenu, FALSE);
}
}
break;
case WM_LBUTTONUP:
{
// 释放菜单按钮,执行菜单操作
BOOL bMenuPressed = (BOOL)GetProp(hWnd, L"MenuPressed");
if (bMenuPressed)
{
ReleaseCapture();
RemoveProp(hWnd, L"MenuPressed");
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
RECT rcMenu = {rcClient.right - MENU_BUTTON_WIDTH, 0, rcClient.right, TITLEBAR_HEIGHT};
if (PtInRect(&rcMenu, {x, y}))
{
HMENU hMenu = (HMENU)GetProp(hWnd, L"CustomMenu");
TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, x, y, 0, hWnd, NULL);
}
InvalidateRect(hWnd, &rcMenu, FALSE);
}
}
break;
case WM_COMMAND:
{
// 处理菜单项操作
int nID = LOWORD(wParam);
switch (nID)
{
case ID_MENU_ITEM_1:
// ...
break;
case ID_MENU_ITEM_2:
// ...
break;
}
}
break;
case WM_DESTROY:
{
// 销毁菜单
HMENU hMenu = (HMENU)GetProp(hWnd, L"CustomMenu");
HMENU hPopupMenu = (HMENU)GetProp(hWnd, L"PopupMenu");
DestroyMenu(hMenu);
DestroyMenu(hPopupMenu);
PostQuitMessage(0);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
``
原文地址: https://www.cveoy.top/t/topic/deUY 著作权归作者所有。请勿转载和采集!