Windows简单窗口的创建

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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值