一、前言:
在自绘WS_POPUP风格样式的平面窗口时,由于不需要系统默认的标题按钮,从而导致窗口默认标题菜单也无法显示(当单击左上角图标时)。所以我们需要手动为其添加上去。
二、实现方式:
'-------------------------------------------------------------------------------
' 取得标题栏区间范围
'-------------------------------------------------------------------------------
SUB GetCaptionRect ( BYVAL hWnd AS HWND, BYREF rc AS RECT )
DIM CaptionHeight AS INTEGER
DIM FrameWidth AS INTEGER
CaptionHeight = GetSystemMetrics ( SM_CYSIZE ) + GetSystemMetrics ( SM_CYFRAME ) - 1
FrameWidth = GetSystemMetrics ( SM_CXEDGE ) * 4
GetClientRect ( hWnd, @rc )
SetRect ( @rc, rc.left + FrameWidth, rc.top, rc.right - FrameWidth, rc.top + CaptionHeight )
END SUB
'-------------------------------------------------------------------------------
' 取得标题栏图标区间
'-------------------------------------------------------------------------------
SUB GetIconRect ( BYREF rc AS RECT )
rc.left = GetSystemMetrics ( SM_CXFRAME )
rc.top = GetSystemMetrics ( SM_CYFRAME ) - 2
rc.right = rc.left + 16
rc.bottom = rc.top + 16
END SUB
'------------------------------------------------------
' 鼠标单击事件下添加系统菜单
'------------------------------------------------------
CASE WM_LBUTTONDOWN
DIM pt AS POINT
DIM i AS INTEGER = 0
pt.x = LOWORD ( lParam )
pt.y = HIWORD ( lParam )
GetIconRect rcIcon
GetCaptionRect ( hWnd, rcTitle )
IF PtInRect ( @rcIcon, pt ) THEN
DIM czText AS WSTRING * 256
DIM hMenu AS HMENU = GetSystemMenu ( hWnd, FALSE )
pt.x = rcTitle.left
pt.y = rcTitle.bottom
ClientToScreen ( hWnd, @pt )
FOR i = 0 TO GetMenuItemCount ( hMenu ) - 1
EnableMenuItem ( hMenu, i, MF_BYPOSITION OR MF_ENABLED )
NEXT i
TrackPopupMenu ( hMenu, TPM_LEFTBUTTON OR TPM_LEFTALIGN, pt.x, pt.y, 0, hWnd, NULL )
PostMessage ( hWnd, WM_NULL, 0, 0 )
END IF
CASE WM_COMMAND
SELECT CASE ( LOWORD ( wParam ) )
CASE SC_CLOSE
SendMessage ( hWnd, WM_SYSCOMMAND, SC_CLOSE, NULL )
CASE SC_MAXIMIZE
SendMessage ( hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, NULL )
END SELECT
三、说明:
当标题菜单添加成功后,第一打开后菜单项为正常。如下:
但是再次点击图标后,发现部分菜单项显示为了无效状态。具体原因不详!
为了解决这个问题,所以需要用到EnableMenuItem这个函数,将无效项修改为有效状态。
EnableMenuItem ( hMenu, i, MF_BYPOSITION OR MF_ENABLED )
或
EnableMenuItem ( hMenu, GetMenuItemID ( hMenu, i ), MF_BYCOMMAND OR MF_ENABLED )
至此完成自绘弹出窗口下标题菜单的设置。
四、总结:
另如果需要自绘此系统标题菜单需要添加MF_OWNERDRAW 属性。如下:
' hMenu 菜单句柄
FOR i = 0 TO GetMenuItemCount ( hMenu ) - 1
GetMenuString ( hMenu, GetMenuItemID ( hMenu, i ), czText, 256, MF_BYCOMMAND )
ModifyMenu ( hMenu, _
GetMenuItemID ( hMenu, i ), _
MF_BYCOMMAND OR MF_OWNERDRAW, _
GetMenuItemID ( hMenu, i ), _
czText )
NEXT i
'或者如下
FOR i = 0 TO GetMenuItemCount ( hMenu ) - 1
GetMenuString ( hMenu, i, czText, 256, MF_BYPOSITION )
ModifyMenu ( hMenu, _
i, _
MF_BYPOSITION OR MF_OWNERDRAW, _
GetMenuItemID ( hMenu, i ), _
czText )
NEXT i
然后在WM_DRAWITEM消息中完成菜单项的绘制。具体实现可参考MSDN。