创建一个最简单的windows窗口

最近好久没写有用的文章了,感觉有点对不起我的博客。。。于是我决定写个以前弃坑很久的win32窗口程序的创建方法

废话就不多说了,那么创建一个win32应用程序实际上要使用的代码并不多,但是微软的IDE自动创建的代码却很复杂,新版的VS情况已经好转,至少中文注释也有了,代码也清晰了。

创建窗口在我现在的知识水平来说,需要以下几个步骤
·做消息处理方法
·定义窗口类和窗口信息
·注册窗口类
·创建窗口
·显示窗口
·写消息循环

于是下面开始我简化的代码(一下代码都在一个文件miao.cpp里)

0.头文件

windows窗口应用程序当然需要包含一个windows特有的头文件才可以创建窗口

#include

 

1.消息处理

这里用一个名叫WndProc的函数,倒腾过窗口程序的都应该对它不陌生,但是它其实不一定要叫这个名字,只是新手都不知道他是怎么调用的(特别像我这样自己没头没脑瞎自学的。。)

 

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    case   WM_DESTROY:
        // 在消息队列中插入一个[退出程序]消息
		PostQuitMessage (0) ;
        break;
	default:return DefWindowProc (hwnd, message, wParam, lParam) ;// 执行内定的消息处理
    }
    return 0;
}

没有高亮看起来必然很蛋疼。。。所以还是复制进自己的IDE看吧

现在演示的是一个没有任何功能的窗口,所以处理的消息只有一个:关闭窗口(和程序)
这个被我压缩了的处理函数是不是比生成的要可爱多了呢

 

2.定义窗口类和窗口信息

普通的C\C++程序入口应该都知道是main()【你要是这都不知道的话来看这篇文章干嘛】
win程序的入口是Winmain,很明显就是main前面加个Win,那就是win特有的了~

int PASCAL	WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)

 

为程序类名定义一个数组(我还没明白为啥是数组。。)

{
    static char szAppName[] = TEXT("喵");

 

定义俩变量

 HWND hwnd;   //窗口句柄*
    MSG msg;     //下面消息循环中传递消息用的消息变量

 

然后是一个重要的地方,因为这里关系到窗口的各种表现:定义窗口类

WNDCLASS wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;  //这里就是消息处理函数绑定的地方了,只要把这里的名字写的的消息处理函数的一样,就可以改成自己习惯的名字
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;//程序句柄
    // 加载 图标供程序使用 IDI-图示ID
    wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    // 加载 鼠标光标供程序使用  IDC-游标ID
    wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);  //光标样式
    //GetStockObject 取得一个图形对象(此例中是取得窗口背景的画刷对象)
    wndclass.hbrBackground =  (HBRUSH)GetStockObject(WHITE_BRUSH);//背景
    wndclass.lpszMenuName = NULL;  //菜单名字,没有菜单所以NULL
    wndclass.lpszClassName = szAppName;  //上面定义的类名
    // 窗口依照某一窗口类别建立,窗口类别用以标识处理窗口消息的窗口消息处理程序。

我没有打注释的是我也不知道是什么东西,装了MSDN的同学把鼠标点一下那个对象再按F1就可以查到是什么了

3.注册窗口类

这一步相当简单,只要使用一个函数就完成了,下面的代码还加了个错误处理

    // 注册窗口
    if (!RegisterClass(&wndclass))          //如果程序类没法注册的话
    {
        MessageBox(NULL, TEXT("程序无法运行"),szAppName,MB_ICONERROR);
        return 0;
    }

 

4.创建窗口

搞了那么久乱七八糟的东西终于到创建窗口了,但是做完了这一步还是不能看到窗口

  //根据窗口类别 WndClass 建立一个窗口
    hwnd = CreateWindow(szAppName,	//窗口类的名字
                        TEXT("喵~"),	// 窗口标题
                        WS_OVERLAPPEDWINDOW,	// 窗口样式
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        NULL,	// 父窗口句柄
                        NULL,	// 窗口菜单的句柄
                        hInstance,//程序窗口实例句柄
                        NULL);	//创建参数

 

hwnd就是前面声明的窗口句柄了,现在终于派上了用场,没有打注释的部分是我忘了是什么的参数,也请自己MSDN按F1吧,我暂时懒得去查了,现在写这篇文章的时候已经2:36(凌晨)了

 

5.显示窗口

终于到我们可以看得见的步骤了,这也是只要一行代码即可

 // 在屏幕上显示窗口
    ShowWindow(hwnd,iCmdShow);

 

5.5 窗口自我更新

这个函数出现的有点莫名其妙,因为虽然默认注释这么写了但是我还是不知道它到底什么时候触发和怎么工作

    // 指示窗口自我更新
    UpdateWindow(hwnd);

我也忍不住去MSDN查了一下这个函数到底是什么情况,然后它告诉我这个结果

The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window’s update region is not empty. The function sends a WM_PAINT message directly to the window procedure of the specified window, bypassing the application queue. If the update region is empty, no message is sent.

它会给消息队列发送WM_PAINT消息,这个消息在默认生成的代码里是有的,但是由于现阶段没有任何用处所以被我去掉了

 

6.写消息循环

 

这是最后一步了,消息循环用来不断的获取消息并且按照你写的来处理

    // 从消息队列中取得消息
    while (GetMessage(&msg,NULL,0,0))//while循环不停地让GetMessage函数获取消息
    {
        TranslateMessage(&msg);//翻译消息?
        DispatchMessage(&msg);//处理消息
    }
    return msg.wParam;
}

OK,那么到这里程序也已经封口了,以上所有代码串起来编译可以出现一个窗口标题为“喵~”的空白窗口。

困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了困死了

如果你觉得我说的时间和文章发布时间不一样的话那时因为我趴在床上写好了到白天才发布的。。。



本文发布于 https://luojia.me

本站文章未经文下加注授权不得拷贝发布。

本博客使用Disqus评论系统,如果看不到评论框,请尝试爬墙。