在MFC中,修改應用程序的外觀可以通過CMainFrame類中的兩個函數來實現;即PreCreateWindow(CREATESTRUCT& cs)和OnCreate(LPCREATESTRUCT lpCreateStruct);下面逐一介紹這兩個函數;
1:PreCreateWindow(CREATESTRUCT& cs)
顧名思義可以看出該函數是在創建窗口之前修改的外觀和大小,而且該函數是一個虛函數,也就是說,調用該函數時,實際上就是調用子對象的函數,對子對象的窗口進行修改;參數CREATESTRUCT& cs是一個引用結構體的形式,這樣我們可以通過修改CREATESTRUCT結構體的參數來修改窗口特徵。通過查看定義可以看出CREATESTRUCT結構體的成員以及作用;
typedef struct tagCREATESTRUCTW {
LPVOID lpCreateParams;
HINSTANCE hInstance; // 應用程序的實例句柄
HMENU hMenu; //窗口菜單句柄
HWND hwndParent; //父窗口句柄
int cy; //指定新窗口的高和寬,像素爲單位
int cx;
int y; //指定新窗口的左上角x,y座標,像素爲單位
int x;
LONG style; //窗口風格
LPCWSTR lpszName; //窗口名稱
LPCWSTR lpszClass; //指定新窗口類
DWORD dwExStyle; //窗口擴展風格
} CREATESTRUCTW, *LPCREATESTRUCTW;
常用的窗口類型如下:
WS_POPUP:彈出式窗體,沒有標題欄!
WS_BORDER:細的黑邊框
WS_OVERLAPPED:一般的有標題欄的窗體,見多了。
WS_CHILD:子窗體,一般用於Frame裏面的窗體
WS_CAPTION:標題欄
WS_SYSMENU:系統菜單(只有設置後纔有最小化、最大化、關閉)
WS_MINIMIZEBOX :最小化按鈕
WS_MAXIMIZEBOX:最大化按鈕
WS_MINIMIZE:啓動時最小化
WS_MAXIMIZE:啓動時最大化
WS_EX_TOOLWINDOW:不在任務欄裏顯示條目
WS_EX_WINDOWEDGE:
WS_EX_CLIENTEDGE:具有凹陷感;
還可以修改frame window style來修改:
#define FWS_ADDTOTITLE 0x00008000L // 調整標題欄
#define FWS_PREFIXTITLE 0x00004000L // show document name before app name
#define FWS_SNAPTOBARS 0x00002000L // snap size to size of contained bars
但是我們如果不設置的話,就是默認的窗口類型,即WS_OVERLAPPEDWINDOW和FWS_ADDTOTITLE;如果進行了其他修改,這兩項也就發生了改變,需要重新設置;而如果需要添加其他的標題,則需要去掉FWS_ADDTOTITLE屬性,在修改cs.lpszName;
下面在PreCreateWindow(CREATESTRUCT& cs)下修改窗口看看效果;
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: 在此處通過修改
// CREATESTRUCT cs 來修改窗口類或樣式
cs.cx=500;
cs.cy=500;
cs.x=0;
cs.y=0;
cs.style&=~FWS_ADDTOTITLE;
cs.lpszName=_T("aaa");
//cs.style=FWS_PREFIXTITLE;
return TRUE;
}
2:通過OnCreate(LPCREATESTRUCT lpCreateStruct)修改窗口
創建好窗口之後,可以在在CMainFrame的函數OnCreate(LPCREATESTRUCT lpCreateStruct)中,利用SetWindowLong( _In_ HWND hWnd,_In_ int nIndex,_In_ LONG dwNewLong);進行修改;
hwnd:標識窗口,並且間接標只出該窗口的屬的窗口類。
這個函數根據nIndex的取值不同,可以實現不同的功能。
其中nInde可以取:
GWL_EXSTYLE: 設置窗口擴展風格,即CreateWindowEx的DWORD wExStyle 參數
GWL_STYLE: 設置窗口風格,即CreateWindow的DWORD dwStyle參數
GWL_WNDPROC: 設置窗口的處理函數,即RegisterClass的WNDCLASSEX的WNDPROC lpfnWndProc成員
GWL_HINSTANCE: 設置窗口所屬的應用程序句柄,即RegisterClass的WNDCLASSEX的HINSTANCE hInstance成員
GWL_ID 設置窗口的ID(對於控件,就是控件ID)
GWL_USERDATA: 設置窗口的用戶自定義數據
DWL_DLGPROC: 設置對話框處理函數
DWL_MSGRESULT: 設置對話框消息處理的結果值
DWL_USER: 設置擴展區域數據
lNewLong:要設定的值。(函數LONG GetWindowLongHWND hWnd,int nlndex)取得窗口的原屬性值,
在此基礎上進行修改。)
下面對函數SetWindowLong()的調用實現窗口最大化按鈕的無效:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
......
// TODO: 如果不需要可停靠工具欄,則刪除這三行
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE)& ~WS_MAXIMIZEBOX);
//SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);
return 0;
}
此時最大化窗口無效,其他的不變,當然也可以直接修改;
SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);
最後的結果是窗口的標題消失了。