回 帖 发 新 帖 刷新版面

主题:[讨论]《白手起家Win32SDK应用程序》第二篇 创建Win32工程和主函数

第二篇 创建Win32工程和主函数

                   白云小飞

[b]1 在D:\创建一个空的工程(工程名为MyApp)[/b]
    要编写一个程序,我们就要首先用VC6应用程序向导创建一个工程,下面我将给你创建一个空工程(也就是没有任何源文件及代码的工程)
[b]1.1 操作:[/b]
    =>文件->新建…->”工程”标签->位置:”D:\”(你可以设置你想要创建的位置)->工程名:MyApp(你可以自己指定其它名)->选择”创建新的工作空间”->确定->一个空工程->完成
[b]1.2 请查看指定位置下生成的文件:打开D:\MyApp[/b]
    我们发现,它在D:\下生成了一个MyApp文件夹。
    并在MyApp文件夹下生成了几个文件,如下:
MyApp.dsp
MyApp.dsw
MyApp.ncb
MyApp.opt
    其中,MyApp.dsp是项目文件和MyApp.dsw是工作区文件,它们是不能删除。
    [b]项目文件的作用:[/b]生成一个EXE或DLL程序的所有相关源文件、有头文件的位置信息都记录在MyApp.dsp项目文件中。
    [b]工作区文件的作用:[/b]如果一个复杂的软件工程可能是由多个EXE和多个DLL程序组成,这样每个项目文件的位置信息又记录在MyApp.dsw工作区文件中。
    当然,我们的这个工程只有一个EXE程序,所以只有一个项目,这个项目文件MyApp.dsp也同样要记录在MyApp.dsw中了。
    MyApp.ncb和MyApp.opt虽删除后会自动生成,但是还是请不要这样做哦!以后我还会说它们的作用。
    我们下次要编辑源程序时,只要打开工作区文件MyApp.dsw就可。

[b]2 在D:\MyApp下创建一个C++源文件,文件名为MyAppMain(当然你也可以自己定义一个文件名),并同时加入到MyApp工程中[/b]
[b]2.1 操作:[/b]
     =>文件->新建…->”文件”标签->选”添加到工程”->选”MyApp”->文件名:MyAppMain->”位置”默认->确定
[b]2.2 查看指定生成的文件:[/b]
    可以看到,在D:\MyApp文件夹下生成了MyAppMain.cpp源文件。

[b]3 在MyAppMain.cpp文件中输入一个主函数[/b]
[b]3.1 代码如下:[/b]
#include <windows.h>
#include<windowsx.h>

int WINAPI WinMain(HINSTANCE hinstance,
                 HINSTANCE hprevinstance,
                 LPSTR lpcmdline,
                 int ncmdshow)
{
  // 将会在这里输入主函数的代码
  return 0;
}
[b]3.2 包含必要的头文件:[/b]
    首先你只要包含下面两个头文件就可,因为它们已经包含了绝大多数的MyApp应用程序必要的头文件。
#include <windows.h>
#include<windowsx.h>
[b]3.3 主函数名:[/b]
    函数头定义的书写格式很有趣:
int WINAPI WinMain(HINSTANCE hinstance,
                 HINSTANCE hprevinstance,
                 LPSTR lpcmdline,
                 int ncmdshow)
    写成四行,其实没什么,只不过写在一行里太长了,如下:
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance,                 LPSTR lpcmdline,  int ncmdshow)
    并且写成上面的四行反而可读性更强,所以以后你会经常看到这样书写的。
    WinMain函数相当于Dos下的main函数,Windows应用程序的主函数不用main而是用WinMain。一个程序必有并只能有一个WinMain函数。这个主函数可以写在本工程中的任何一个.cpp文件中。
[b]3.4 参数:[/b]
hinstance:类型是HINSTANCE,这种类型就是前面我们可是提到过的应用程序句柄啦。hinstance的值就是你的当前应用程序进程的句柄。
    你的程序每次运行,它的hinstance值是不会一样的。不过我们并不关心hinstance的值是多少。我们只要知道hinstance里的值就是代表本应用程序进程的句柄值就可以了。
    我们等一会儿就会用到它了,请看好哦!
    [b]hprevinstance:[/b]现在已经不用了。我们可以完全不理它。
    [b]lpcmdline:[/b]这是一个命令行参数。与main(int argc,char **argv)中的命令行参数相似。由于与本题无关,我们也不可完全不理它,对此不再进一步讨论下去。
    至于它的数据类型LPSTR,我在前面已经说明了,它其实就是char *类型。
    [b]ncmdshow:[/b]一个整型值。启动过程中被传递给应用程序,带有如何打开应用程序主窗口的信息。这样,程序的使用者有了一点点的控制应用程序如何启动的能力了。作为一个程序员,如果想忽略它也可以,想使用它也行。哦,那我们这里也先忽略它了。
[b]3.5 返回值:[/b]
    是一个int值,当我们的程序正常结束退出时,一定要返回一个0值。所以我们的WinMain函数体内最后有return 0;了
[b]3.6 函数名前的WINAPI是什么?[/b]
    最后还有一个要说明的——就是WINAPI。这是什么呢?
    在VC6的Windef.h头文件中是如下定义的:
#define WINAPI      __stdcall
    也就是WINAPI等于__stdcall了。
    你知道吗,凡是提供给Windows操作系统调用的函数都得是__stdcall调用的。WinMain主函数当然是由Windows系统调用的,因此定义WinMain前要用__stdcall(即WINAPI)修饰。(你会明白函数调用方式的具体含义吗?不知道也没关系,现在只要记得WINAPI要放在WinMain前就行了。)
    另外说明一点,int 与WINAPI哪个在前哪个在后都是可以的。
    好了,我们现在对主函数定义处的各个部分有了必要的了解。你可以休息一会儿,然后回顾一下我们前面操作的过程:
    想想我们在本篇中做了哪些事?
    生成了哪些文件?
    这些文件是什么作用的?
    主函数定义的各个部分是什么作用?
    如果你已经对上面所做的感到比较清晰,那太好了,Come on!我们继续吧!


回复列表 (共1个回复)

沙发

精辟!

我来回复

您尚未登录,请登录后再回复。点此登录或注册