繁体   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