一 窗口註冊和創建
1 Win32窗口程序創建步驟
1.1 WinMain入口函數的定義
1.2 WindowProc函數的定義
1.3 註冊窗口類
RegisterClass/RegisterClassEx
1.4 創建窗口
CreateWindow/CreateWindowEx
1.5 窗口的顯示和刷新
ShowWindow/UpdateWindow
1.6 消息處理
GetMessage/DispatchMessage
1.7 窗口退出
WM_DESTROY/PostQuitMessage
2 窗口的註冊
2.1 窗口類的分類
2.1.1 系統全局的窗口類.比如按鈕("BUTTON")、
文本編輯框("EDIT")等。
2.1.2 應用程序的全局窗口類。可以在一個應用
程序中EXE、DLL等所有模塊中使用的窗口類。
2.1.3 局部窗口類。只能在本模塊中使用的
窗口類。
2.2 實現窗口類的註冊
2.2.1 系統全局的窗口類,無需註冊直接使用。
使用CreateWindow函數,在CLASSNAME中指定
系統已經定義好的窗口類型名稱即可。
2.2.2 應用程序的全局窗口類,需要用代碼實現
註冊,在註冊時需要增加CS_GLOBALCLASS定義。
實現方式:
WNDCLASS wc = {0};
wc.style = CS_GLOBALCLASS|CS_HREDRAW..;
....
RegisterClass( &wc );
2.2.3 局部窗口類,不是增加CS_GLOBALCLASS定義。
使用RegisterClass和RegisterClassEx註冊
typedef struct _WNDCLASSEX {
UINT cbSize; //結構體的大小
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HANDLE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
HICON hIconSm; //小圖標
} WNDCLASSEX;
2.2.4 窗口類風格
CS_HREDRAW 窗口水平變化,重新繪製窗口。
CS_VREDRAW 窗口垂直變化,重新繪製窗口。
CS_DBCLICK 窗口可以接收鼠標雙擊消息
CS_GLOBALCLASS 創建應用程序全局窗口類。
CS_BYTEALIGNWINDOW 窗口對齊方式,以8的倍數對齊
CS_BYTEALIGNCLIENT 窗口客戶區對齊方式,以8的倍數對齊
CS_CLASSDC 所有這種類型的窗口使用同一個DC(設備描述表,繪圖使用)
CS_OWNDC 每個窗口擁有自己的DC
CS_PARENTDC 使用父窗口的DC
CS_SAVEBITS 是用位圖保存窗口界面,可以提高
窗口界面的刷新性能
CS_NOCLOSE 禁止關閉命令.
2.2.5 窗口類的附加數據 cbClsExtra
在窗口類的數據信息中添加自己信息.
cbClsExtra 用於添加信息的內存的大小
SetClassLong 將信息保存到內存中
GetClassLong 將信息從內存中取出
DWORD SetClassLong(
HWND hWnd,//窗口的句柄
int nIndex, //值的索引號
LONG dwNewLong //值
);
DWORD GetClassLong(
HWND hWnd,//窗口的句柄
int nIndex, //值的索引號
);
cbClsExtra的長度一般是4字節的倍數
2.2.6 窗口附加數據 cbWndExtra
在窗口的數據信息中添加自己信息.
cbWndExtra 用於添加信息的內存的大小
SetWindowLong 將信息保存到內存中
GetWindowLong 將信息從內存中取出
2.3 窗口類的相關函數
RegisterClass/RegisterClassEx 註冊
UnregisterClass 註銷
GetClassInfo/GetClassInfoEx 獲取信息
GetClassName 獲取窗口的窗口類名稱
GetClassLong/SetClassLong 窗口類附加數據的設置和獲取
GetWindowLong/SetWindowLong 窗口的附加數據的設置和獲取
2.4 創建窗口時如何定位窗口類
2.4.1 查找應用程序局部的窗口類。如果找到,
執行2.4.2,否則執行2.4.3
2.4.2 如果找到名稱一致的窗口類,會比較
HISNTANCE句柄。如果相等,就使用找到
的窗口類信息創建窗口,如果不同,繼續
查找,執行2.4.3。
2.4.3 如果未找到名稱一致的窗口類,會繼續
在應用程序全局窗口類中查找。如果找到,
執行2.4.4,否則執行2.4.5
2.4.4 全局窗口類找到一致的,使用找到
的窗口類信息創建窗口。
2.4.5 系統全局窗口類中查找。如果找到,創建
窗口,否則返回失敗。
3 窗口創建
3.1 窗口創建函數
CreateWindow/CreateWindowEx
HWND CreateWindowEx(
DWORD dwExStyle,//窗口的擴展樣式
LPCTSTR lpClassName, // pointer to registered class name
LPCTSTR lpWindowName, // pointer to window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // handle to menu, or child-window identifier
HINSTANCE hInstance, // handle to application instance
LPVOID lpParam ); // pointer to window-creation data
3.2 窗口風格和擴展風格
窗口風格: WS_XXXX定義的風格,是窗口的
基本風格.
擴展風格: WS_EX_XXXXX 定義的風格,是窗口
的擴展風格.比如: ToolWindow窗口等等.
在CreateWindow可以使用基本窗口風格,擴展
的窗口風格,需要使用CreateWindowEx設置.
WS_OVERLAPPED窗口,層疊式窗口
WS_POPUP窗口,彈出式窗口
WS_CHILD窗口,子窗口
3.3 父窗口和子窗口
3.3.1 CreateWindow時,指定父窗口
3.3.2 將窗口的風格增加WS_CHILD
3.3.3 可以使用SetParent和GetParent
函數設置和獲取指定窗口的父窗口.
其他: MoveWindow 移動窗口.
3.4 MDI窗口的創建
3.4.1 創建主窗口
註冊主窗口類型,創建主窗口.
HWND hWnd = CreateWindowEx( 0,
pszClassName, "MainWnd",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, g_hInst,
NULL );
3.4.2 MDICLIENT窗口
1 添加CLIENTCREATESTRUCT結構,作爲附加數據
CLIENTCREATESTRUCT cs = { 0 };
cs.idFirstChild = 1000;//MDI第一個子窗口的ID
2 創建時,使用"MDICLIENT"窗口類型.
3 它的父窗口是主窗口
HWND hWnd = CreateWindowEx( 0,
"MDICLIENT", "MainWnd",
WS_CHILD|WS_VISIBLE, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, hParent, NULL, g_hInst,
&cs );
3.4.3 創建一個MDI子窗口
1 註冊主窗口類型,創建子窗口
2 它的父窗口爲MDICLIENT窗口
3 增加WS_EX_MDICHILD的風格
HWND hWnd =
CreateWindowEx( WS_EX_MDICHILD,
pszClassName, "ChildWnd",
WS_CHILD|WS_VISIBLE, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, hParent, NULL,
g_hInst, NULL );