沧桑不尽
无穷的沧桑,不尽的落叶

 1.2 第一个真正的窗口程序

 
(欢迎各位高手继续拍砖)
    
上一节中,我们用MessageBox函数轻松地实现了一个对话框窗口,可能你会说,那仅仅是个没有用的对话框而已,是的,只是对话框而已。我之所以以一个对话框为呢,是因为我只是想让你知道写一个有界面的程序并不是件难办的事。明白了这一点后,我们继续。今天来编写一个真正的窗口程序。

下面就该罗嗦一段了,由于大家以前并没有写过什么窗口程序,写的都是命令行下的,我们知道在命令行下的程序都有一个主函数main,这个函数也就是程序的入口函数。我们现在用VC 6.0来写,而且要写窗口类程序,VC 6.0给我们提供了一个专门用作窗口类程序的入口函数WinMain()

这个函数原型是这样的

int WINAPI WinMain(
  HINSTANCE hInstance, 
  HINSTANCE hPrevInstance, 
  LPSTRlpCmdLine, 
  
int nCmdShow
);

      

大家是不是感觉这个函数挺复杂的,有这么几个参数,而像main好像就没有参数。其实main是有参数,这个向锋和小四是知道了的。但是main函数的参数是可以省略的,而WinMain是不可以省的。这里也要对VC 6.0的编译模式改下

看下图


依次 是“工程”→“设置”→“连接”,在“工程选项”里把console改为windows就可以了。如果认真学了汇编,或是手写命令编译连接过C程序,就会知道这是干什么的。Console是控制台的意思,以前我们用mian函数写的程序都是以控制台模式连接的,所以很少会有界面的。现在我们要写有界面的程序,所以要选Windows(窗口)模式了。


我们写入以下代码,并按照上面说的方法去做,看看结果

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPreInstance,
                   LPSTR lpCmdLine,
                   
int nShowCmd)
{
    MessageBox(NULL,
"WinMain创建的窗口程序","WinMain",MB_OK);
    
return 0;
}

结果如下图:



与第一节中的这段代码代码比较下



两者比较下,后者多了个cmd窗口。可见用main写的并没有完全脱离命令行呀。所以以后我们写窗口程序就用winmain了。

 

好了,转过来,我们来看看WinMain()函数,其中有4个参数

先看下解释(看不明白得先看完):

hInstance:应用程序当前事例的句柄。

hPrelnstance:应用程序的先事例的句柄。对于同一个程序打开两次,出现两个窗口第一次打开的窗口就是先前实例的窗口。对于一个32的位程序,该参数总为NULL

lpCmdLine:指向应用程序命令行的空字符串的指针,不包括函数名。获得整个命令行,参看GetCommandLine

nCmdShow:指明窗口如何显示(是隐藏还是显示,有没有最大化按钮之类的)。取值可以参考MSDN

这里我相信有一个词大家好应该比较陌生,句柄(HANDLE)是吧。下面我就来简单的说下

句柄其实就是Windows系统中一个东西的唯一标识。就是系统中有很多运行的程序或者资源之类的,为了更好的管理使用,Windows系统给它们每人一个ID一样。懂得网页制作的人应该知道网页中各个元素的ID吧,网页的ID如果重复话可能出现错误。那么系统的句柄会不会有相同的,那是肯定不会有的了,就和我们的学号一样,系统自动分配每一个模块的句柄,是不会相同的了。

 

对于句柄大家可以先这样理解着,不用一下子搞懂得。以后学着学着就明白了。

 

估计大家对那几个参数的类型改犯迷糊了吧。其实那几个类型,并不是什么新类型,都是Windows开发人员为了自己和他人编程方便,同过基本的C语言语法定义一种新的结构体,或者是共同体,再者就是枚举类型。我知道结构体、共同体和枚举类型,很多老师是没有讲到的,因为在书的后边,很多教C的,又是很垃圾的老师,所以不会讲那么快的。其实结构体这些数据类型,就是通过我们常用的字符、整型、浮点等数据类型构造一个比较复杂的类型而已,举个例子,就是我们知道C没有一个数据类型可以描述一个人吧,那么我构造一个是不是很方便我们编程呢。我们可以这样构造一个

struct People
{
    
int age;//年龄
    char sex[2];//性别
    int height;//身高
……
}

我们这样定义以后就可以在我们以后的程序中利用这个数据类型了,People zhangsan;zhangsan的身高172放到zhangsan.height中。这样可以方便完成很多工作。所以结构体是很简单的,还有其他的复杂数据类型也是很简单的,都是有常用的简单的类型来结合到一起构造一个复杂的而已。这和JAVA定义类是很相似的,java定义个人类,不是可以这样的

public class People
{
    
public int age;
    
public string sex;
    
public height;
    ……


看起来都差不多,而且用法也很相像。唯一的差别其实就是类可以有方法,而结构体是没有的(经过特殊处理也是可以的,这里不用考虑)。

 

上面是为了让大家了解下复杂数据类型的定义,罗嗦了一大堆。下面来看下WinMain中第一个参数的类型HINSTANCE这个只是个结构体而已,实际上和HANDLE这个类型差不多,但是有一点差别,而HANDLE是这样typedef PVOID HANDLE;定义的,PVOID是什么呢,我们来看下typedef void *PVOID;说明PVOID是一个指针,初始指向空(void)。因此可以知道句柄也是个指针而已。看着这么复杂原来也只是指针。
这些都可以在微软的msdn上查得到的,而且很详细的
那个第二个LPSTR 根据字面上的意思就知道是字符串类型了。查一查果然是。

大家一定要利用好msdn,很有用的。

 

本节就到此结束了,主要是说明了一个WinMain函数和结构体的事情,东西也不算太多,大家应该能接受得了吧。下节就来点复杂点深点的东西,希望大家做好心理准备。

posted on 2009-08-05 09:10  沧桑不尽  阅读(2970)  评论(13编辑  收藏  举报