[英]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.