Windows简单窗口的创建

来源:互联网 发布:windows安全性弹窗 编辑:程序博客网 时间:2024/06/05 02:48

Windows窗口的创建主要需要两个部分,一个是窗口类,一个就是处理你窗口类消息的窗口过程,可以简单理解窗口过程是用于处理Windows传递到窗口的消息,例如这消息可以是鼠标的输入。

Windows对于窗口的处理是通过它对窗口发送消息,然后借由这个消息进行窗口的窗口过程从而影响窗口。

Windows通过消息队列和非消息队列对窗口进行维护,在Windows程序开始执行时,Windows首先会为程序创建一个消息队列,该消息队列存放这应用程序可能创建的所有窗口的消息。然后通过名为“消息循环”的代码,从消息队列中检索消息,并将其发给相应的窗口过程,其他消息则不通过消息队列发给窗口过程。


下面是具体的实现代码,由Charles Petzold大师所编写,然后添加了我的注释:

编译环境:win7 64位 IDE:vs2010

/*------------------------------------------------------------   HELLOWIN.C -- Displays "Hello, Windows 98!" in client area                 (c) Charles Petzold, 1998  ------------------------------------------------------------*/#include <windows.h>using namespace std; 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 ;//HWND是窗口句柄,类似的有HDC(设备环境句柄),HINSTANCE(实例句柄——程序本身)     MSG          msg ;//MSG是消息结构,可以传递鼠标,键盘之类操作的消息     WNDCLASS     wndclass ;//WNDCLASS是窗口类,这里定义了一个叫wndclass的窗口 /*------------------------------------------------------------   窗口类的结构   typedef struct   {       UINT       style;//窗口的风格   WNDPROC    lpfnWndProc;//用于基于该窗口类的所有窗口的窗口过程的地址   int        cbClsExtra;//Windows系统应该预留分配给类的额外内存数量   int        cbWndExtra;//Windows系统应该预留分配给窗口的额外内存数量   HINSTANCE  hInstance;//   HICON      hIcon;//窗口图标   HCURSOR    hCursor;//窗口上鼠标样式   HBRUSH     hbrBackground;//窗口背景色   LPCTSTR    lpszMenuName;//窗口类的菜单   LPCTSTR    lpszClassName;//窗口类的名称}WNDCLASS,* PWNDCLASS;------------------------------------------------------------*/     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;//定义窗口的风格,CS_HREDRAW(窗口的水平尺寸),CS_VREDRAW(窗口的垂直尺寸)                                                   //这里表示当窗口的水平尺寸或垂直尺寸改变时,基于该窗口类的所有窗口都将被重新绘制     wndclass.lpfnWndProc   = WndProc ;//定义该窗口类的窗口过程     wndclass.cbClsExtra    = 0 ;//这个窗口不需要额外的空间     wndclass.cbWndExtra    = 0 ;//这个窗口不需要额外的空间     wndclass.hInstance     = hInstance ;//应用程序的实例句柄     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;//使用LoadIcon函数创建窗口的图标                                                            //这里使用的是预定义的图标,所以第一个参数是NULL                                                            //如果是保存在磁盘里的应用程序中的可执行文件加载自定义图标,该参数必须为hInstance     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;//使用LoadCursor函数创建窗口上鼠标图标,如IDC_ARROW是个箭头,IDC_HAND是只手     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;//使用GetStockObject取得窗口背景色,这里WHITE_BRUSH是白色,BLACK_BRUSH是黑色     wndclass.lpszMenuName  = NULL ;//这里没使用菜单,设为NULL     wndclass.lpszClassName = szAppName ;//定义类的名称     if (!RegisterClass (&wndclass))//注册一个窗口类     {          MessageBox (NULL, TEXT ("This program requires Windows NT!"),                       szAppName, MB_ICONERROR) ;//MessageBox有ASCALL码和Unicode编码形式,当时windows1998的MessageBox似乎不支持Unicode形式的这个函数          return 0 ;     }          hwnd = CreateWindow (szAppName,                  // 窗口类的名称                          TEXT ("The Hello Program"), // 窗口的标题                          WS_OVERLAPPEDWINDOW,        // 窗口的风格,overlapped是层叠窗口                          CW_USEDEFAULT,              // 初始x坐标,指定窗口左上角相对于屏幕左上角的初始位置,这里取默认值                          CW_USEDEFAULT,              // 初始y坐标,指定窗口左上角相对于屏幕左上角的初始位置,这里取默认值                          CW_USEDEFAULT,              // 初始x方向尺寸                          CW_USEDEFAULT,              // 初始y方向尺寸                          NULL,                       // 其父窗口的句柄,这里是顶级窗口,所以为NULL                          NULL,                       // 窗口菜单句柄,由于没有菜单,所以为NULL                          hInstance,                  // 程序实例句柄,这里用的是WinMain传入的程序实例句柄                          NULL) ;                     // 创建参数,这个还不懂          ShowWindow (hwnd, iCmdShow) ;//显示窗口,第一个参数是所需窗口的句柄                              //第二个参数决定窗口在屏幕中的初始显示位置                              //如SW_SHOWNORMAL是窗口正常显示,SW_SHOWMAXIMIZED是最大化,SW_SHOWMINNOACTIVE是显示在任务栏     UpdateWindow (hwnd) ;//这里需要绘制窗口     /*------------------------------------------------------------   MSG类的结构   typedef struct tagMSG   {       HWND      hwnd;//消息所指向的窗口句柄   UINT      message;//消息标识符,比如将鼠标放置在窗口的客户区按下鼠标左键就是一个消息   WPARAM    wParam;//消息参数   LPARAM    lParam;//另一个消息参数   DWORD     time;//消息进入消息队列的时间   POINT     pt;//消息进入消息队列时鼠标所在位置坐标}MSG,* PMSG;POINT是另一种结构typedef struct tagPOINT{   LONG x;   LONG y;}POINT,* PPOINT;------------------------------------------------------------*/     while (GetMessage (&msg, NULL, 0, 0))//当得到的消息并不是关闭窗口时,继续进行     {          TranslateMessage (&msg) ;//将msg结构返还给Windows进行某些键盘消息的转换          DispatchMessage (&msg) ;//将msg结构再次返还给Windows     }//这里执行一段名为消息循环的代码,可以用于接受键盘输入和鼠标输入     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) ;//BeginPaint函数的第一个参数为程序的窗口句柄,第二个参数为指向PAINTSTRUCT结构的指针                                        //当该函数调用时,如果客户区的背景尚未擦出,Windows会对其擦除                                //所使用的画刷是注册窗口类的WNDCLASS结构中的hbrBackground字段中指定的          GetClientRect (hwnd, &rect) ;//该函数第二个参数是指向类型为RECT的举行结构的指针                               //RECT结构有四个类型为LONG的字段,名称为left,top,right,bottom,该函数会根据窗口尺寸对这四个字段进行设置                    DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,                    DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;//绘制文本,第一个参数是由BeginPaint函数返回的设备环境句柄                                                     //第二个参数是所要绘制的文本,第三个参数设为-1,表示该文本字符串以0结尾                                                     //第四个参数为位参数,如DT_VCENTER是将字体垂直居中                    EndPaint (hwnd, &ps) ;//释放环境句柄,以使其无效          return 0 ;               case WM_DESTROY://窗口的破坏          PostQuitMessage (0) ;          return 0 ;     }     return DefWindowProc (hwnd, message, wParam, lParam) ;//DefWindowProc函数用于对所有窗口过程没有处理的消息进行默认处理                                                       //如果缺少该函数,窗口的其他正常行为(如结束程序)将无法进行}//窗口过程对消息进行处理后,应返还0

实现效果,图片适当的调了大小:


0 0