第一个win32程序,简单的创建窗口:
#include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("HelloWin") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, // window class name TEXT ("The Hello Program"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL) ; // creation parameters ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc ; PAINTSTRUCT ps ; RECT rect ; switch (message) { case WM_CREATE:return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; DrawText (hdc, TEXT ("Hello, Windows Program!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
窗口是由窗口类创建的即WNDCLASS,窗口类确定了处理窗口消息的窗口过程。
MSDN中是这样定义的:
typedef struct { UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; } WNDCLASS, *PWNDCLASS;
在程序中,我们一般这样定义和初始化
WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ;
wndclass.style字段表示类的风格,具体参加MSDN:
Style | Action |
---|---|
CS_BYTEALIGNCLIENT | Aligns the window's client area on a byte boundary (in the x direction). This style affects the width of the window and its horizontal placement on the display. |
CS_BYTEALIGNWINDOW | Aligns the window on a byte boundary (in the x direction). This style affects the width of the window and its horizontal placement on the display. |
CS_CLASSDC | Allocates one device context to be shared by all windows in the class. |
CS_DBLCLKS | Sends a double-click message to the window procedure when the user double-clicks the mouse while the cursor is within a window belonging to the class. |
CS_DROPSHADOW | Windows XP: Enables the drop shadow effect on a window. The effect is turned on and off through SPI_SETDROPSHADOW. |
CS_GLOBALCLASS | Specifies that the window class is an application global class. For more information, see Application Global Classes. |
CS_HREDRAW | Redraws the entire window if a movement or size adjustment changes the width of the client area. |
CS_NOCLOSE | Disables Close on the window menu. |
CS_OWNDC | Allocates a unique device context for each window in the class. |
CS_PARENTDC | Sets the clipping rectangle of the child window to that of the parent window so that the child can draw on the parent. A window with the CS_PARENTDC style bit receives a regular device context from the system's cache of device contexts. |
CS_SAVEBITS | Saves, as a bitmap, the portion of the screen image obscured by a window of this class. |
CS_VREDRAW | Redraws the entire window if a movement or size adjustment changes the height of the client area. |
我们这里选择的是CS_HREDRAW | CS_VREDRAW,表示无论垂直还是水平尺寸的改变,窗口都将重绘。
wndclass.lpfnWndProc表示窗口过程设置,指向一个函数WndProc。
wndclass.cbClsExtra和cbWndExtra用于维护内部窗口结构中一些预留的空间,可以根据需要来使用这些预留的空间。
wndclass.hInstance表示应用程序的实例句柄即WinMain第一个参数。
wndclass.hIcon为该窗口类设定图标。若要使用本地的图标,第一个参数必须为hInstance实例句柄,第二个参数为图标标示,对于预定义的图标以IDI开头。
wndclass.hCursor与上面类似,载入鼠标指针。
wndclass.hbrBackground指定背景色,这里我们用白色画刷。
wndclass.lpszMenuName即窗口菜单。
wndclass.lpszClassName为窗口类指定名字。
这样窗口类的初始化完成,使用RegisterClass注册类,下面就是窗口的创建了,
使用createWindow函数,MSDN定义如下:
HWND CreateWindow( __in LPCTSTR lpClassName, //窗口名称 __in LPCTSTR lpWindowName, //窗口标题 __in DWORD dwStyle, //窗口风格 __in int x, //x坐标 __in int y, //y坐标 __in int nWidth, //长度 __in int nHeight, //高度 __in HWND hWndParent, //父窗口句柄 __in HMENU hMenu, //窗口菜单句柄 __in HINSTANCE hInstance, //程序实例句柄 __in LPVOID lpParam //创建参数 );
CreateWindow只是在内部创建窗口,即windows分配了一片内存,要想显示窗口还要使用ShowWindow函数。
第一个参数是CreateWindow创建的窗口句柄,第二个是WinMain接受的iCmdShow值,该参数决定窗口初始显示格式。
UpdateWindow是重绘窗口,这是通过发送一条WM_PAINT消息完成的。
最后则是消息的循环,即不断接受消息,当有消息时调用WndProc函数进行处理。