Windows程序设计--创建第一个窗口

来源:互联网 发布:shell 中执行 python 编辑:程序博客网 时间:2024/05/16 15:24

本篇文章讲如何创建一个基本的窗口。

MessageBox弹出来的消息框就是一个窗口,但是窗口是怎样创建的呢?其实很简单,只要几个固定的步骤就行。而只要我们的窗口创建出来之后,只要把需要的函数填进去就能得到一个有功能的窗口。所以我觉得学习Windows就是学习API函数而已,懂得如何调用,各个参数的意思就行。说到参数,其类型都是从C语言的基本数据类型演变而来的,并不难。

现在开始创建第一个窗口,该窗口并无功能,只是一个空的框架。

代码如下:

 #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 ("MyClass") ;     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, // 窗口类名                          TEXT ("MyWin"), // 窗口标题                                               WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL,//窗口风格                          CW_USEDEFAULT,  // 窗口的x坐标,相对于屏幕左上角                          CW_USEDEFAULT,  // 窗口的x坐标,相对于屏幕左上角                          CW_USEDEFAULT,  // 窗口宽度(像素为单位)                          CW_USEDEFAULT,  // 窗口高度(像素为单位)                          NULL,          // 父窗口句柄                          NULL,          // 窗口菜单                          hInstance,    // 程序实例句柄                          NULL) ;      // (请看注释1)     //在屏幕上显示窗口     ShowWindow (hwnd, iCmdShow) ;     //指示窗口自我更新。     UpdateWindow (hwnd) ;            //从消息队列中取得消息     while (GetMessage (&msg, NULL, 0, 0))     {         //转译某些键盘消息。          TranslateMessage (&msg) ;          //将消息发送给系统,系统再将消息发送给窗口过程处理消息。          DispatchMessage (&msg) ;     }    // msg.wParam 来自一条表示退出的消息,返回这个值给系统,从而退出。     return msg.wParam ;}//窗口过程函数          //窗口句柄   //窗口消息 //第一个额外附加消息 //第二个额外附加消息LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){     HDC         hdc ;//设备环境     PAINTSTRUCT ps ;//绘画结构     //通常定义为静态变量是为了在不断的调用这个函数时该值不会改变     static int cxClient,cyClient;//客户区宽和高     //筛选消息,如果没有需要关注的消息,则有系统自动处理     switch (message)     {         //窗口创建消息,创建窗口时会有此消息         //注:创建窗口之前还会有很多消息进来,可以自己在         //switc中加断点调试看看有哪些消息进来     case WM_CREATE:          return 0;          //当客户区改变的时候,也就是发生大小变化          //就会传进来这个消息,然后两个参数会被改变     case WM_SIZE:           cxClient=LOWORD(lParam);           cyClient=HIWORD(lParam);           return 0;          //垂直滚动条信息           //记得在窗口风格中添加这两个风格     case WM_VSCROLL:         return 0 ;          //水平滚动条信息     case WM_HSCROLL:           return 0;          //重绘窗口消息           //每当窗口改变大小或者移动时都会发送重绘     case WM_PAINT:          //开始绘制窗口。          hdc = BeginPaint (hwnd, &ps) ;          //获取设备环境的方法不只这一种          //结束绘制窗口。          EndPaint (hwnd, &ps) ;          return 0 ;              case WM_DESTROY:          //在消息队列中插入一个「退出程序」消息         //该消息是WM_QUIT          PostQuitMessage (0) ;          return 0 ;     }            //除了需要关注的消息,其它消息都经由系统自动处理。     return DefWindowProc (hwnd, message, wParam, lParam) ;}

总结一下创建窗口的步骤:
1.创建并初始化窗口类
看过很多好文章,里面都会把创建窗口类比作一个品牌汽车的模板
2.注册窗口类
然后去为这个品牌注册登记
3.创建窗口
再然后用这个模板来创建同样品牌不同样式的汽车
4.显示、更新窗口
造好车后就要拿出去展示,并时不时的更新车辆信息
5.从消息循环队列中获取消息
把车卖出去后(显示窗口),会有客户把用户体验或者车辆问题反馈回来(消息),这肯定是需要排队的(队列),如果很紧急也可以插队。然后公司就会获取他们反馈的信息(系统),然后叫各种部门处理(窗口过程).
如此循环就是窗口了

HWND hwnd;//窗口句柄

UINT message;//一个无符号整形消息

WPARAM wParam;//16位(双字节(在16位系统的时间))的消息参数。
//值的款式和意思取决于重要的事件消息类型。
//注:在我的VS2008编译器中定义是64位的。

LPARAM lParam;//32位(长整型)的消息参数。这个参数的值和意思取决于主事件消息类型。
//注:在我的VS2008编译器中定义是64位的。

其在头文件中的定义如下:
typedef UINT_PTR WPARAM;
typedef LONG_PTR LPARAM;
typedef LONG_PTR LRESULT;

typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;

typedef _W64 long LONG_PTR, *PLONG_PTR;

DefWindowProc:(解释转自百科)

函数功能:该函数调用缺省的窗口过程来为应用程序没有处理的任何窗口
消息提供缺省的处理。该函数确保每一个消息得到处理。
调用DefWindowProc函数时使用窗口过程接收的相同参数。

函数原型:LRESULT DefWindowProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
  参数:
  hWnd:指向接收消息的窗口过程的句柄。
  Msg:指定消息类型。
  wParam:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。
  IParam:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。
  返回值:返回值就是消息处理结果,它与发送的消息有关。

现在窗口已经创建好了,骨架搭好了就剩下五脏六腑了,只要一步步完善这个骨架,最后就能写出一个界面程序了。
这里不详细解释每个结构体的参数是什么意思,因为没用到说了也白说,用了再去了解它,这样学习负担就不会很大。
看了这个那么长的代码也只是创建出一个空白的窗口,心里可能会有些失望,感觉好像很难,这是刚开始学习Windows程序设计都会遇到的坎坷。但是以后你写多了这个框架,你就会对里面各个参数有一点的理解,并且不之不觉中闭着眼睛都能写出这100多行代码。正所谓,都没有会走怎么可能会跑?所以还是慢慢走吧,总有一天会跑得飞起。

注释1:
lpParam:
指向一个值的指针,该值传递给窗口WM_CREATE消息。该值通过在IParam参数中的CREATESTRUCT结构传递。如果应用程序调用CreateWindow创建一个MDI客户窗口,则lpParam必须指向一个CLIENTCREATESTRUCT结构。

1 0
原创粉丝点击