Win32程序标准开发流程

本文详细介绍了Windows程序的标准开发流程,从WinMain入口点开始,涵盖设计与注册窗口类、创建和显示窗口、更新窗口、消息循环、消息响应等步骤。通过实例演示了如何创建和注册窗口类,以及处理窗口消息。文章还解释了窗口句柄、消息处理、窗口类结构体初始化的重要性,以及如何在窗口关闭时退出应用程序。
摘要由CSDN通过智能技术生成

一、WinMain入口点

我们在学习标准C++的时候,都知道每个应用程序运行时都会先进入入口点函数main,而当从main函数跳出时程序就结束了。在Windows编程里面,也是一样的,只是我们的入口点函数不叫main,叫WinMain,这个函数不同于main,我们不能乱来,它的定义必须与声明保持一致。

我建议各位安装VS的时候,都顺便更新帮助文档到本地硬盘,这样我们可以方便查找。有一点要注意,目前DestTop Develop的文档基本上是英文的,做好心理准备。

WinMain函数怎么写呢,不用记的,到MSDN文档一搜,直接复制就行了。

 
int CALLBACK WinMain(
    _In_  HINSTANCE hInstance,
    _In_  HINSTANCE hPrevInstance,
    _In_  LPSTR lpCmdLine,
    _In_  int nCmdShow
  );


这个函数带了一个CALLBACK,说明它是一个回调函数,那么这个CALLBACK是啥呢。我们先不管,我们先动写一个Windows,让大家有一个更直观的认识。

1、启动你的开发工具,版本任意。

2、从菜单栏中依次【文件】【新建】【项目】,在新建项目窗口中,选择Win32-Win32应用程序。

2、点击确定后,会弹出一个向导,单击【下一步】。项目类型选择Windows应用程序,附加选项选择空项目,我们要自己编写实现代码。

3、单击完成,项目创建成功。打开【解决方案资源管理器】,在“源文件”文件夹上右击,从菜单中找到【添加】【新建项】,注意,是源文件,不要搞到头文件去了。

在新建项窗口中选C++代码文件,.cpp后缀的,不要选错了,选成头文件,不然无法编译,因为头文件是不参与编译的。文件名随便。

包含Windows.h头文件,这个是最基本的。

#include <Windows.h>


然后是入口点,这个我们直接把MSDN的声明Ctrl + C,然后Ctrl + V上去就行了。

int CALLBACK WinMain(
    _In_  HINSTANCE hInstance,
    _In_  HINSTANCE hPrevInstance,
    _In_  LPSTR lpCmdLine,
    _In_  int nCmdShow
  )
{

	return 0;
}


WinMain返回整型,返回0就行了,其实是进程的退出码,一定要0,不要写其他,因为0表示正常退出,其他值表示非正常退出。

刚才我们提到这个函数带了CALLBACK,那么,它是什么?很简单,你回到IDE,在CALLBACK上右击,选【转到定义】,看看吧。

我们看到它其实是一个宏,原型如下:

#define CALLBACK    __stdcall

这时候我们发现了,它其实就是__stdcall,那么这个__stdcall是什么呢?它是和__cdecl关键字对应的,这些资料,你网上搜一下就有了,如果你觉得不好理解,你不妨这样认为,__stdcall是专门用来调用Win API 的,反正MSDN上也是这样说的,它其实是遵循Pascal的语法调用标准,相对应地,__cdecl是C语言的调用风格,这个也是编译器选项。
打开项目属性,找到节点C/C++\高级,然后查看一下调用约定,我们看到默认是选择C风格调用的,所以,WIN API 函数才用上关键字__stdcall,如果你实在不懂,也没关系,这个东西一般不影响我们写代码,但属性窗口中的编译器选项不要乱改,改掉了可能会导致一些问题。

那么CALLBACK有什么特别呢?一句话:函数不是我们调用的,但函数只定义了模型没有具体处理,而代码处理权在被调用者手里。怎么说呢,我们完全把它理解为.NET中的委托,我想这样就好理解了,委托只声明了方法的参数和返回值,并没有具体处理代码。

WinMain是由系统调用的,而WinMain中的代码如何写,那操作系统就不管了。就好像我告诉你明天有聚会,一起去爬山,反正我是通知你了,至于去不去那是你决定了。

接下来看看入口点函数的参数。

注意,我们平时看到很多如HANDLE,HINSTANCE,HBRUSH,WPARAM。LPARAM,HICON,HWND等一大串数据类型,也许我们会说,怎么Windows开发有那么多数据类型。其实你错了,人总是被眼睛所看到的东西欺骗,Win API 中根本没有什么新的数据类型,全都是标准C++中的类型,说白了,这些东西全是数字来的。如果你不信,自己可以研究一下。

它定义这些名字,只是方便使用罢了,比如下面这样:

int hWindow;
int hIcon;
int theAppInstance;

第一个变量指的是窗口的句柄,第二个指的是一个图标的句柄,第三个是当前应用程序的实例句柄,你看看,如果我们所有的句柄都是int,我们就无法判断那些类型是专门用来表示光标资源,不知道哪些类型是专用来表示位图的句柄了,但是,如果我们这样:

#defin HBRUSH  int64

这样就很直观,我一看这名就知道是Brush Handlers,哦,我就明白它是专门用来管理内存中的画刷资源的,看,这就很明了,所以,通常这些新定义的类型或者宏,都是取有意义的名字。比如消息,它也是一个数字,如果我说115代表叫你去滚,但光是一个115谁知道你什么意思,但是,如果我们为它定义一个宏:

#define WM_GET_OUT    115

这样,只要我SendMessage(hwnd, WM_GET_OUT, NULL, NULL),你就会收到一条消息,滚到一边去。

WinMain的第一个参数是当前应用程序的实例句柄,第二个参数是前一个实例,比如我把kill.exe运行了两个实例,进程列表中会有两个kill.exe,这时候第一次运行的实例号假设为0001,就传递第一个参数hInstance,第二次运行的假设实例号为0002,就传给了hPrevInstance参数。

lpCmdLine参数从名字上就猜到了,就是命令行参数,那LPSTR是啥呢,它其实就是一个字符串,你可以跟入定义就知道了,它其实就是char*,指向char的指针,记得我上一篇文章中说的指针有创建数组的功能吗?对,其实这里传入的命令行参数应该是char[ ],这就是我在第一篇文章中要说指针的原因。

这里告诉大家一个技巧,我们怎么知道哪些参数是指针类型呢,因为不是所有参数都有 * 标识。技巧还是在命名上,以后,只要我们看到P开头的,或者LP开头的,都是指针类型

比如LPWSTR,LPCTSTR,LPRECT等等。

最后一个参数nCmdShow是主窗口的显示方式。它定义了以下宏。

Value Meaning
SW_HIDE 0

Hides the window and activates another window.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值