<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:新宋体; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@新宋体"; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:143665776; mso-list-type:hybrid; mso-list-template-ids:-533719436 619879022 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l0:level1 {mso-level-text:%1>; mso-level-tab-stop:60.0pt; mso-level-number-position:left; margin-left:60.0pt; text-indent:-18.0pt;} @list l1 {mso-list-id:579799790; mso-list-type:hybrid; mso-list-template-ids:-380763910 1403956662 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l1:level1 {mso-level-tab-stop:18.0pt; mso-level-number-position:left; margin-left:18.0pt; text-indent:-18.0pt;} @list l1:level2 {mso-level-number-format:alpha-lower; mso-level-text:"%2/)"; mso-level-tab-stop:42.0pt; mso-level-number-position:left; margin-left:42.0pt; text-indent:-21.0pt;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->
1. WM 的菜单比较特殊,首先要有一个放置菜单的地方,这就是 menu bar ,一个窗口,拥有窗口句柄( HWND ),可以通过 ::ShowWindow(); 来显示和隐藏
a) 系统默认会创建一个空的 menu bar ,如在 dialog 模式下, menu bar 上只显示了一个输入法图标,
// Returns menubar owned by a window
HWND WINAPI SHFindMenuBar(HWND hwnd);
可以获得当前窗口的 menu bar 句柄,这个 menu bar 是系统创建的。值得注意的是,如果需要隐藏这个 menu bar ,最好在窗口初始化的时候 SHFindMenuBar(HWND hwnd); 并保留这个句柄,以备重新 Show 出来,因为如果 menu bar 被隐藏了,再想用 SHFindMenuBar(HWND hwnd); 就不行了,返回的是 NULL 。
b) 窗口创建的过程中,可以不使用系统的 menu bar ,自己动态创建 menu bar ,创建 menu bar :
SHMENUBARINFO mbi;
ZeroMemory(&mbi, sizeof(SHMENUBARINFO));
mbi.cbSize=sizeof(SHMENUBARINFO);
mbi.hwndParent=m_hWnd; // 当前窗口的句柄
mbi.hInstRes=::AfxGetInstanceHandle();
mbi.dwFlags=SHCMBF_HMENU|SHCMBF_HIDESIPBUTTON;// 隐藏 SIP
mbi.nToolBarId=IDR_MYMENU ; // 显示的菜单资源
VERIFY(SHCreateMenuBar(&mbi)) ;
如果创建成功, mbi.hwndMB 中记录的就是 menu bar 的句柄,保留使用。因为 SHFindMenuBar(HWND hwnd) 并不能返回这个 menu bar 句柄,具体原因就不知道了。
2. 有了 menu bar ,就可以在上面放置菜单了。这里有两种情况:
a) 只有左右键菜单,即 left softkey 和 right softkey 。不包含有子菜单。在这里可以简单地理解将 menu bar 理解 toolbar , left softkey 和 right softkey 相当于 toolbar 上的两个 button 。
1> 使某个 SK(Soft Key) 不可用,但是不能改变它的显示状态。
::SHEnableSoftkey(mbi.hwndMB,0,TRUE,FALSE); // 具体参考 msdn
2> 设置 softkey 文本信息
TBBUTTONINFO tbbi ;
memset (&tbbi ,0,sizeof (TBBUTTONINFO ));
tbbi .cbSize = sizeof (TBBUTTONINFO );
tbbi .dwMask = TBIF_BYINDEX |TBIF_TEXT /*|TBIF_COMMAND*/ ;
tbbi .cchText = wcslen (text ); // 文本长度
tbbi .pszText = text ; // 文本
::SendMessage (m_hWndMB ,TB_SETBUTTONINFO ,sk ,(LPARAM )&tbbi );
3> 修改 softkey 状态
TBBUTTONINFO tbbi ;
memset (&tbbi ,0,sizeof (TBBUTTONINFO ));
tbbi .cbSize = sizeof (TBBUTTONINFO );
tbbi .dwMask = TBIF_BYINDEX |TBIF_STATE /*|TBIF_COMMAND*/ ;
// 获得当前状态
::SendMessage (m_hWndMB ,TB_GETBUTTONINFO ,sk ,(LPARAM )&tbbi );
tbbi .fsState |= stateAdd ;
tbbi .fsState &= ~stateDel ;
::SendMessage (m_hWndMB ,TB_SETBUTTONINFO ,sk ,(LPARAM )&tbbi );
fsState 的值可以是 TBSTATE_ENABLED,TBSTATE_HIDDEN
b) 左右键菜单拥有子菜单。获得左右菜单的菜单句柄(不是 menubar 句柄)
// 方法一
TBBUTTON tb ;
memset (&tb ,0,sizeof (TBBUTTON ));
::SendMessage (m_hWndMB ,TB_GETBUTTON ,sk ,(LPARAM )&tb ); //sk=0,left sk
return (HMENU )tb .dwData ; // 菜单句柄。如果没有子菜单,返回0
// 方法二
TBBUTTONINFO tbbi ;
memset (&tbbi ,0,sizeof (TBBUTTONINFO ));
tbbi .cbSize = sizeof (TBBUTTONINFO );
tbbi .dwMask = TBIF_LPARAM |TBIF_BYINDEX ;
::SendMessage (m_hWndMB ,TB_GETBUTTONINFO ,sk ,(LPARAM )&tbbi ); //sk=0,left sk
return (HMENU )tbbi .lParam ; // 菜单句柄。如果没有子菜单,返回0
有了菜单句柄,就可以对子菜单进行操作了。
1> EnableMenuItem // MF_ENABLED, MF_DISABLED, or MF_GRAYED
2> CheckMenuItem // MF_CHECKED,MF_UNCHECKED
3> GetMenuItemInfoA // MFS_CHECKED,MFS_UNCHECKED,MFS_ENABLED,MFS_HILITE,MFS_UNHILITE
4> SetMenuItemInfoA // MFS_CHECKED,MFS_UNCHECKED,MFS_ENABLED,MFS_HILITE,MFS_UNHILITE
3. 全屏窗口,隐藏输入法图标
//
只对top
window
有效,所以m_hWnd
必须是top window
句柄。如果是frame-view-document
模式,
// m_hWnd
应该是frame
的句柄,而不是view
的句柄,在dialog
模式,m_hWnd
是dialog
的句柄
SHFullScreen (m_hWnd , SHFS_HIDESIPBUTTON ));
#define SHFS_SHOWTASKBAR 0x0001
#define SHFS_HIDETASKBAR 0x0002
#define SHFS_SHOWSIPBUTTON 0x0004
#define SHFS_HIDESIPBUTTON 0x0008
#define SHFS_SHOWSTARTICON 0x0010
#define SHFS_HIDESTARTICON 0x0020
4. 隐藏ok 按键
BOOL SHDoneButton (HWND hwndRequester , DWORD dwState );
#define SHDB_SHOW 0x0001
#define SHDB_HIDE 0x0002
#define SHDB_SHOWCANCEL 0x0004