您的位置:首页 > 其它

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

2015-12-08 20:23 309 查看
本篇文章讲如何创建一个基本的窗口。

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结构。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: