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、如果找到名称一致的窗口类,
比较HINSTANCE句柄。如果一致,就使用找到的窗口类信息创建窗口,如果不同,继续查找,执行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
如果一个工作区里有多个项目,要想激活某个项目,就右键这个项目,选择set as active
3.2、窗口风格和扩展风格
窗口风格:WS_XXXX定义的风格,是窗口的基本风格。
扩展风格:WS_EX_XXXXX 定义的风格,是窗口的扩展风格。
比如:ToolWindow窗口等等。
在CreateWindow可以使用基本窗口风格,扩展的窗口风格,需要使用CreateWindowEx设置。
WS_OVERLAPED 窗口,层叠式窗口。
WS_POPUP 窗口,弹出式窗口。
WS_CHILD 窗口,子窗口。
3.3、父窗口和子窗口
3.3.1、CreateWindow时,指定父窗口。
3.3.2、将窗口的风格增加WS_CHILD。
3.3.3、可以使用SetParent和GetParent函数设置和获取指定窗口的父窗口。
其他:MoveWindow移动窗口。
//创建子窗口 #include <Windows.h> HINSTANCE g_hInst = NULL; // 父窗口的处理函数 LRESULT CALLBACK WndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) { switch( nMsg ) { case WM_DESTROY: PostQuitMessage( 0 ); return 0; } return DefWindowProc( hWnd, nMsg, wParam, lParam ); } //子窗口的处理函数 LRESULT CALLBACK ChildProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) { return DefWindowProc( hWnd, nMsg, wParam, lParam ); } //消息处理函数 void Message( ) { MSG msg = { 0 }; while( GetMessage( &msg, NULL, 0, 0 ) ) { DispatchMessage( &msg ); } } //显示窗口 void DisplayWnd( HWND hWnd ) { ShowWindow( hWnd, SW_SHOW ); UpdateWindow( hWnd ); } //创建窗口 HWND CreateWnd( LPSTR pszClassName, DWORD nStyle, HWND hParent ) { HWND hWnd = CreateWindowEx( 0, pszClassName, "MyWnd", nStyle, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hParent,NULL,g_hInst,NULL ); return hWnd; } //注册窗口 BOOL RegisterWnd( LPSTR pszClassName, WNDPROC proc, int nBrush ) { WNDCLASSEX wce = { 0 }; wce.cbSize = sizeof( wce ); wce.style = CS_HREDRAW|CS_VREDRAW; wce.cbClsExtra = 0; wce.cbWndExtra = 0; wce.lpfnWndProc = proc; wce.hIcon = NULL; wce.hCursor = NULL; wce.hbrBackground = HBRUSH( nBrush ); wce.hInstance = g_hInst; wce.lpszClassName = pszClassName; wce.lpszMenuName = NULL; wce.hIconSm = NULL; ATOM nAtom = RegisterClassEx( &wce ); if( 0 == nAtom ) { return FALSE; } return TRUE; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { g_hInst = hInstance; //注册父窗口类 RegisterWnd( "MyWnd", WndProc, COLOR_BTNFACE+1 ); //注册子窗口类 RegisterWnd( "Child", ChildProc, COLOR_WINDOW ); //创建父窗口 HWND hWnd = CreateWnd( "MyWnd", WS_OVERLAPPEDWINDOW, NULL ); //创建子窗口 HWND hChild1 = CreateWnd( "Child", WS_CHILD|WS_VISIBLE|WS_BORDER| WS_THICKFRAME|WS_CAPTION|WS_SYSMENU| WS_MINIMIZEBOX|WS_MAXIMIZEBOX, hWnd ); HWND hChild2 = CreateWnd( "Child", WS_VISIBLE|WS_POPUP| WS_THICKFRAME|WS_CAPTION|WS_SYSMENU, hWnd ); HWND hChild3 = CreateWnd( "Child", WS_CHILD|WS_VISIBLE|WS_BORDER, hWnd ); //移动窗口位置 MoveWindow( hChild1, 100, 100, 200, 200, TRUE ); MoveWindow( hChild2, 200, 200, 200, 200, TRUE ); MoveWindow( hChild3, 300, 300, 200, 200, TRUE ); //显示父窗口 DisplayWnd( hWnd ); Message( ); return 0; }
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 );
#include <Windows.h> HINSTANCE g_hInst = NULL; HWND g_hMDIClient = NULL; //主窗口的窗口处理函数 LRESULT CALLBACK MainProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { switch(nMsg) { case WM_DESTROY: PostQuitMessage(0); return 0; } return DefFrameProc(hWnd,g_hMDIClient,nMsg,wParam,lParam); } //子窗口的窗口处理函数 LRESULT CALLBACK ChildProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { return DefMDIChildProc(hWnd, nMsg, wParam, lParam); } //窗口注册函数 BOOL RegisterWnd(LPSTR pszClassName, WNDPROC Proc, int nBrush) { WNDCLASSEX wce = {0}; wce.cbSize = sizeof(wce); wce.style = CS_HREDRAW|CS_VREDRAW; wce.cbClsExtra = 0; wce.cbWndExtra = 0; wce.lpfnWndProc = Proc; wce.hInstance = g_hInst; wce.hCursor = NULL; wce.hIcon = NULL; wce.hbrBackground = HBRUSH(nBrush); wce.lpszClassName = pszClassName; wce.lpszMenuName = NULL; wce.hIconSm = NULL; ATOM nAtom = RegisterClassEx(&wce); if(nAtom == 0) { return FALSE; } return TRUE; } //显示窗口 void DisplayWnd(HWND hWnd) { ShowWindow(hWnd,SW_SHOW); UpdateWindow(hWnd); } //消息循环 void Message() { MSG msg = {0}; while(GetMessage(&msg,NULL,0,0)) { DispatchMessage(&msg); } } //创建主窗口的函数 HWND CreateMainWnd(LPSTR pszClassName) { HWND hWnd = CreateWindowEx(0, pszClassName, "MainWnd", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,NULL,NULL,g_hInst,NULL); return hWnd; } HWND CreateMDIClient(HWND hParent) { CLIENTCREATESTRUCT cs = {0}; cs.idFirstChild = 1000; HWND hWnd = CreateWindowEx(0, "MDICLIENT", "MainWnd", WS_CHILD|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,hParent,NULL,g_hInst, &cs); return hWnd; } HWND CreateClildWnd(LPSTR pszClassName, HWND hParent) { 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); return hWnd; } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdLine) { //注册主窗口 RegisterWnd("MainWnd",MainProc,COLOR_BTNFACE+1); //注册子窗口 RegisterWnd("ChildWnd",ChildProc,COLOR_WINDOW); //创建主窗口 HWND hMain = CreateMainWnd("MainWnd"); //创建MDICLIENT窗口 //创建MDICLIENT子窗口 g_hMDIClient = CreateMDIClient(hMain); MoveWindow(g_hMDIClient, 0, 0, 500, 500, TRUE); //显示和消息处理 //创建MDI子窗口 HWND hChild = CreateClildWnd("ChildWnd",g_hMDIClient); DisplayWnd(hMain); Message(); return 0; }