簡體   English   中英

純 Win32 C++ 中的自定義菜單邊框(無 WTL、MFC 等)

[英]Custom menu border in pure Win32 C++ (w/o WTL, MFC, etc)

僅使用 Win32 C++(沒有 WTL 或 MFC 或任何其他第三方庫),如何獲得自定義菜單邊框?

我能夠擁有這些項目,但邊界在非客戶區域,我無法找到改變它們的方法。

有辦法嗎?

無論您如何實現這一點,它都將是一個 hack。

一種選擇是忘記 HMENU 並使用自定義始終在頂部窗口構建自己的菜單。 這可能是太多的工作,你永遠不會讓一切都完美。 就在我的腦海中,您必須處理 LTR 與 RTL、可訪問性、可配置設置,如陰影和菜單動畫(滑動/淡入淡出)。 SetMenu對 HWND 所做的某些事情可能無法通過這樣的 hack 復制,但您可以通過在 rebar 中實現它來回避該問題。

如果您想繼續使用 HMENU,則必須使用SetWindowsHookEx來查找菜單 HWND。 菜單類是#32768 然后,您可以子類化窗口並覆蓋 WM_NC* 和 WM_PRINT* 消息。 此 Codeproject 文章還包含有關您需要處理的未記錄消息 (0x01e5) 的信息。

static bool isInitPopup = false;
switch (message)
{
case WM_INITMENUPOPUP:
{
    isInitPopup = true;
    break;
}
case WM_DRAWITEM:
{
    LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
    if (lpDIS->CtlType == ODT_MENU)
    {
        auto hMenuWnd = FindWindow(_T("#32768"), NULL);
        if (IsWindow(hMenuWnd)&& isInitPopup)
        {
            RECT rect;
            ::GetWindowRect(hMenuWnd, &rect);
            auto menuDc = ::GetWindowDC(hMenuWnd);
            ::OffsetRect(&rect, -rect.left, -rect.top);
            int border = 1;
            rect.left = rect.left + border;
            rect.top = rect.top + border;
            rect.bottom = rect.bottom - border;
            rect.right = rect.right - border;
            HBRUSH bg = CreateSolidBrush(RGB(255,0,0));
            //Rectangle(menuDc, rect.left, rect.top, rect.right, rect.bottom);
            int borderThiness = 3;
            ::ExcludeClipRect(menuDc, rect.left+ borderThiness, rect.top+ borderThiness, rect.right- borderThiness, rect.bottom- borderThiness);
            ::FillRect(menuDc, &rect, bg);
            DeleteObject(bg);
            isInitPopup = false;
        }
    break;
}

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM