要在winapi无边框窗口上添加标题栏右键菜单,可以使用以下步骤:

  1. 注册一个新的窗口类,设置窗口样式为无边框(WS_POPUP)。

  2. 在窗口创建消息(WM_CREATE)中创建一个自定义菜单和一个弹出菜单。

  3. 在窗口绘制消息(WM_PAINT)中绘制标题栏,并在标题栏上绘制菜单按钮。

  4. 在鼠标消息(WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP)中处理菜单按钮的状态和显示弹出菜单。

  5. 在菜单消息(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;
}
``
winapi无边框窗口添加标题栏右键菜单

原文地址: https://www.cveoy.top/t/topic/deUY 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录