天天看點

在系統菜單中添加顯示和隐藏标題欄的方法!

      給系統菜單增加一個額外的指令Remove Title删除視窗的标題,通過再次顯示菜單并選中Restore Title指令可以還原标題欄。Restore Title出現在以前Remove Title指令所在的地方。這種技術其實很簡單,秘密就在于ModifyStyle函數。決定視窗是否有标題欄的屬性是WS_CAPTION。它包含在大多數架構視窗中使用的WS_OVERLAPPEDWINDOW樣式中。建立沒有标題欄的視窗很簡單,隻要省略WS_CAPTION即可。是以,通過清除WS_CAPTION位就可以從已存在的視窗中删除标題欄。CWnd::ModifyStyle通過簡單的函數調用就可以修改視窗樣式。

      然而切換WS_CAPTION僅僅是工作的一半。關鍵技巧在于視窗樣式修改之後怎樣重新繪制視窗的非客戶區。調用CWnd::Invalidate()不行,要用SWP_DRAWFRAME參數調用SetWindosPos才可以:

      SetWindowPos (NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);

這樣就使得整個視窗包括标題欄被重繪。其它傳遞給SetWindowPos的SWP标志儲存了視窗的位置、大小、z次序,z次序是從前向後的窗

口。

void CMyCloDlg::OnHideShowTitle()

{

CMenu* pMenu = GetSystemMenu (FALSE);

if (m_bFullWindow )

{

ModifyStyle (WS_CAPTION, 0);

//ModifyStyle (WS_CAPTION, 0,SWP_DRAWFRAME);

pMenu->ModifyMenu (IDM_SYSMENU_FULL_WINDOW, MF_STRING,IDM_SYSMENU_FULL_WINDOW, _T ("Restore &Title"));

m_bFullWindow=false;

}

else

{

ModifyStyle (0, WS_CAPTION);

//ModifyStyle (0, WS_CAPTION,SWP_DRAWFRAME);

pMenu->ModifyMenu (IDM_SYSMENU_FULL_WINDOW, MF_STRING,IDM_SYSMENU_FULL_WINDOW, _T ("Remove &Title"));

m_bFullWindow=true;

}

SetWindowPos (NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);

}

函數原型及用法如下:

CWnd::ModifyStyle

1.作用:

  調用這個函數修改視窗的風格

2.函數原型:

  BOOL ModifyStyle(DWORD dwRemove,DWORD dwAdd,UINT nFlags=0);

3.參數含義:

  dwRemove 指定修改時要删除的視窗風格。

  dwAdd 指定修改時将要增加的視窗風格。

  nFlags 該參數将被傳給SetWindowPos,預設為0

4.傳回值:

  如果該函數成功調用傳回一個非0值,否則傳回0;

5.備注

  如果nFlags不為0, ModifyStyle 将調用Windows API 函數SetWindowPos 并且結合nFlags和以下四個預先布置好的标志重畫該視窗。

  SWP_NOSIZE 保持目前大小。

  SWP_NOMOVE 保持目前位置.。

  SWP_NOZORDER 保持目前的Z次序。

  SWP_NOACTIVATE 不激活該視窗。

6.用法:

  1、修改控件的原有屬性用 ModifyStyle(1,WS_DISABLED);(實際測試時隻要是>=0的整形數就行)

  2、改回來的話要用ModifyStyle(WS_DISABLED,1);(實際測試時隻要是>=0的整形數就行)

CWnd::GetSystemMenu

CMenu* GetSystemMenu( BOOL bRevert ) const;

傳回值:

      如果bRevert為FALSE,則傳回系統菜單的一份拷貝;如果為TRUE,則傳回值沒有定義。傳回的指針可能是臨時的,不能被儲存以供将來使用。

參數:

      bRevert 指定要采取的動作。如果bRevert為FALSE,則GetSystemMenu傳回目前使用的控制菜單的一個拷貝的句柄。這個拷貝最初與控制菜單一樣,但是可以被修改。如果bRevert為TRUE,GetSystemMenu将控制菜單複位到原來的狀态。以前控制菜單可能發生的變化都被銷毀。這時傳回值沒有定義。

說明:

      這個函數允許應用程式通路控制菜單,用于拷貝和修改。任何不使用GetSystemMenu以生成它自己的控制菜單拷貝的視窗将接收标準的控制菜單。

GetSystemMenu成員函數傳回的指針可以在CMenu::AppendMenu,CMenu::InsertMenu或CMenu::ModifyMenu中使用,用于改變控制菜單。

      控制菜單中最初包含了用不同的ID辨別的項,如SC_CLOSE,SC_MOVE和SC_SIZE。控制菜單中的項産生WM_SYSCOMMAND消息。所有的預定義控制菜單項都具有大于0xF000的ID值。如果應用程式在控制菜單中加入了項,則必須使用小于F000的ID值。

Windows可能自動使标準控制菜單上的項變灰。CWnd可以通過響應WM_INITMENU消息來執行它自己的選中或變灰操作,這個消息是在任何菜單要被顯示之前發送的。

系統菜單ID的值是有範圍的通常是 0xF**0的形式,最後一位一般是0

比如:SC_CLOSE-----0xF060     SC_SIZE------0xF000等等

是以如果要讓(nID & 0xFFF0) == IDM_MYSYSITEM成立,你的菜單項ID必須是0x***0的形式

比如0x0010,否則就會出錯。至于為什麼你的nID == IDM_MYSYSTEM能執行,肯定是因為 你的IDM_MYSYSTEM定義成了101,102之類的常量整數了吧

建議:

如果要在系統菜單裡添加自定義的菜單項,那麼最好将菜單項ID定義為0x***0的形式

就目前系統菜單ID為0xF000---0xF180加上分隔條0xF00F 一共20個

為了差別你可以将最高位置零定義成0x0000,0x0010,0x0020-------