C语言Windows程序设计-第一天-我的第一个Windows程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C语⾔Windows程序设计-第⼀天-我的第⼀个Windows程序
我的第⼀个Windows程序, Hello,world!
在的书中, 作者⾸先回顾了下C语⾔在控制台下通过标准输⼊输出函数输出"Hello,world!"的程序, 代码如下:
#include <stdio.h>
int main()
{
printf( "Hello,world!\n" ) ;
return0 ;
}
不过令我疑惑的是, 在我这本《Windows程序设计》(第五版) 2010年9⽉第5版的书中, 却将这段经典代码的"return 0 ;"写成了"Return 0 ;", 笔者尝试了下, "Return 0 ;"在VC6的编译器和GCC下都是报错的, 难道是我买到盗版书了?
可能是由于印刷失误, 这⾥就先不管他了。
同样, Charles Petzold也给出了Windows版的"Hello,world!"(其实他给出的是Hello,windows 98!), 代码如下:
#include<windows.h>
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
{
MessageBox( NULL, TEXT("Hello,world!"), TEXT("MessageBox"), 0 );
return0;
}
通过Visual C++ 6.0的"⽂件"-->"新建"-->"⼯程", 选择"Win32 Application"创建⼀个空的项⽬, 再在这个项⽬中新建⼀个"⽂件",⽂件类型为"C++ Source File", ⽂件以.c为扩展名, 将上⾯的代码敲⼊或者复制粘贴到这个⽂件内容中, 经过编译运⾏就可以得到⼀个对话框了, 赶紧截图留念吧!
在这个对话框中, 有标题栏, 标题栏的内容是"MessageBox", 对话框的内容为"Hello,world!", 还有⼀个"确定"按钮, ⽽且, 没有那个⿊框框窗⼝, ⼀切看起来都是那么美好, 来⼀起看看这段Windows版的Hello,world!吧!
-----------------------------------------------------------
*Windows版的Hello,world!代码注释*
*第⼀⾏
#include<windows.h>
稍微有点C语⾳基础的都能明⽩, 这是要包含"windows.h"这个头⽂件, 也就说明, 在下⾯的代码中, 要⽤到这个头⽂件, 如果我们将#include<windows.h>这句去掉再进⾏编译看看会有什么情况:
Compiling...
HelloWorld.c
d:\project\lwinc\helloworld\helloworld.c(3) : error C2061: syntax error : identifier 'WinMain'
d:\project\lwinc\helloworld\helloworld.c(3) : error C2059: syntax error : ';'
d:\project\lwinc\helloworld\helloworld.c(3) : error C2146: syntax error : missing ')' before identifier 'hInstance'
d:\project\lwinc\helloworld\helloworld.c(3) : error C2061: syntax error : identifier 'hInstance'
d:\project\lwinc\helloworld\helloworld.c(3) : error C2059: syntax error : ','
d:\project\lwinc\helloworld\helloworld.c(3) : error C2059: syntax error : ')'
执⾏ cl.exe 时出错.
意料之内的, 报错了, 第⼀条就是标识符"WinMain"错误, 具体的细节暂时就不深究了, 继续向下看。
*关于windows.h头⽂件:
在windows.h这个头⽂件中, 实际上已经包含了若⼲的其他相关的头⽂件, ⽤书上的话说, windows.h是个⾮常重要的包含⽂件, 其中包含的其他⽐较重要的头⽂件有:
■ WINDEF.H 基本数据类型定义
■ WINNT.H ⽀持Unicode的类型定义
■ WINBASE.H 内核函数
■ WINUSER.H ⽤户界⾯函数
■ WINGDI.H 图像设备接⼝函数
不过我还是好奇windows.h到底包含了那些头⽂件, 找到VC6的安装⽬录, 打开Include⽂件夹, 找到WINDOWS.H并打开, 虽说看不太懂, 但找#include关键词还是⽆压⼒的.
除去上⾯的5个还有:
■WINRESRC.H ■EXCPT.H ■STDARG.H ■WINNLS.H ■WINCON.H
■WINVER.H■WINREG.H ■WINNETWK.H ■CDERR.H ■DDE.H
■DDEML.H ■DLGS.H ■LZEXPAND.H ■MMSYSTEM.H ■NB30.H
■RPC.H ■SHELLAPI.H■WINPERF.H■WINSOCK2.H ■MSWSOCK.H
■WINSOCK.H ■WINCRYPT.H ■COMMDLG.H■WINSPOOL.H■OLE.H
■OLE2.H ■WINWLM.H■WINSVC.H ■MCX.H ■IMM.H
*程序的⼊⼝
在Win32控制台程序()中, 应⽤程序的⼊⼝为main()函数, windows程序的程序⼊⼝和win32控制台程序的⼊⼝类似, 为WinMain()函数.
程序的⼊⼝函数在WINBASE.H作出了声明, 声明如下:
int
WINAPI
WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
);
其中由声明可以看出, WinMain函数的返回值被定义为int型;
WINAPI为WinMain函数的调⽤规则, 在WINDEF.H对"WINAPI"作出了如下宏定义:
#define WINAPI __stdcall
说明, WinMain函数的调⽤规则为""⽅式, 对于"__stdcall"调⽤规则, 现在暂时先不去深究, 知道有这么回事就⾏, 以后会详细了解到的, 现在如果深究"__stdcall"就偏离了这篇博⽂的主题。
*WinMain函数的参数:
1>. WinMain的第⼀个参数 HINSTANCE hInstance, ⽤书上的解释为"实例句柄", 由于第⼀次接触C语⾔Windows程序设计, 对这个句柄的概念也不是很了解, 去百科了下, 句柄的解释为"⼀个句柄是指使⽤的⼀个唯⼀的整数值,即⼀个四字节长的数值,来标志应⽤程序中的不同对象和同类对象中的不同的实例,诸如,⼀个窗⼝,按钮,图标,滚动条,输出设备,控件或者⽂件等。
"——。
笔者是这样对句柄进⾏理解的, 在⼀个应⽤程序中, 通常创建了很多的窗⼝、按钮、标签, 或者使⽤了⼀个⽂件等, 在程序的任何地⽅, 只要能够获得这个被称为句柄的东西, 就能够找到该控件或者窗⼝在内存中的位置, 从⽽对其进⾏操作。
感觉有点像带参数的main函数, 只是这⾥的主函数参数为⼀个句柄。
2>. WinMain函数的第⼆个参数, 同样是个实例句柄, 但书上⼜进⼀步解释说在32位的Windows程序设计中, WinMain函数的实例句柄概念已不再采⽤, 因此WinMain的第⼆个参数通常总是NULL。
笔者的见解: 感觉马上就要晕了, 疑问⼀: "因此WinMain的第⼆个参数通常总是NULL", 那么第⼀个呢?WinMain的第⼀个参数会不会也可以是NULL呢?疑问⼆: WinMain函数的参数从何⽽来?是操作系统么?带着疑问继续向下看。
3>. WinMain的第三个参数是⽤来运⾏程序的命令⾏, PSTR: ⽤来指向⼀个字符串的指针类型, szCmdLine, sz:表⽰以0结尾的字符串; ⽬的是通过命令⾏⽅式运⾏程序并向主函数中传⼊参数, 应该就像给main函数传⼊参数⼀样;
4>. WinMain的第四个参数是⼀个int型参数, ⽤来指明程序(窗⼝)最初如何被显⽰, 例如最⼩化?最⼤化?全屏?
笔者的见解: 应该很有⽤, 经常见⼀些游戏⼀启动就是全屏的, 但是这个参数也是操⼼系统传给程序的么?因为从平时运⾏Windows程序时都是直接双击, 并没有通过命令⾏给它传⼊参数, 在编程时应该对程序启动时的显⽰⽅式有交代才对, 这样系统再运⾏时再把这个交代的参数传⼊给程序告诉程序启动时应该如何显⽰.
(在"笔者的见解"部分的观点均为笔者个⼈的见解, 如果有误肯定指正, 我会及时更正, 避免误导其他读者。
)
*WinMain函数函数体的MessageBox函数:
, 名如其"⼈", 不⽤猜也知道这个就是显⽰⼀个对话框的函数, 打开API⽂档,MSDN Library通过索引找到MessageBox函数, 发现其声明如下:
int MessageBox(
HWND hWnd, // handle of owner window, 窗⼝的⼀个句柄
LPCTSTR lpText, // address of text in message box, ⼀个⽂本(字符串)的指针
LPCTSTR lpCaption, // address of title of message box, 标题字符串的指针
UINT uType // style of message box, 对话框的风格
);
在上⾯⽰例中对MessageBox函数的调⽤如下:
MessageBox( NULL, TEXT("Hello,world!"), TEXT("MessageBox"), 0 );
第⼀个参数窗⼝的句柄的实参为NULL, 意思为不属于任何窗⼝.
第⼆个参数为对话框的内容, 第三个参数为对话框的标题, 但是这两个参数都使⽤了⼀个TEXT()的函数, 书上讲使⽤TEXT()的⽬的是将这些字符串打包到TEXT宏代码⾥⾯, 笔者尝试了不⽤这个TEXT()函数⽽直接像这样:
MessageBox( NULL, "Hello,world!", "MessageBox", 0 );
调⽤并没有出现警告或者报错信息, 具体使⽤TEXT()函数的详细原因还不太清楚, 暂时先在这⾥画个圈。
第四个参数为对话框的风格, ⼀些以MB_开头的⼀些常量的组合, 可以使⽤OR(|)运算进⾏组合, 这些常量定义在WINUSER.H 中, 例如常⽤的有:
1>.对话框按钮类型:
#define MB_OK 0x00000000L //仅有⼀个"确定"按钮
#define MB_OKCANCEL 0x00000001L //"确定" + "取消"
#define MB_ABORTRETRYIGNORE 0x00000002L //"终⽌" + "重试" + "忽略"
#define MB_YESNOCANCEL 0x00000003L //"是" + "否" + "取消"
#define MB_YESNO 0x00000004L //"是" + "否"
#define MB_RETRYCANCEL 0x00000005L //"重试" + "取消"
2>.对话框中的图标类型:
#define MB_ICONHAND 0x00000010L //⼀个红X的错误/停⽌图标
#define MB_ICONQUESTION 0x00000020L //⼀个问号的询问图标
#define MB_ICONEXCLAMATION 0x00000030L //⼀个黄⾊感叹号的警告图标
#define MB_ICONASTERISK 0x00000040L //⼀个带有i的信息提⽰图标
同时, 在这些图标中有的还可以⽤其他名称代替, 这些别名在WINUSER.H的定义如下:
#define MB_ICONWARNING MB_ICONEXCLAMATION //警告
#define MB_ICONERROR MB_ICONHAND //错误
#define MB_ICONINFORMATION MB_ICONASTERISK //信息
#define MB_ICONSTOP MB_ICONHAND //停⽌
------------------------------------------------------------------
下午的学习暂时就到这⾥, 在学习的过程中出现了⼏个疑问, 在这⾥对疑问进⾏下总结:
疑问⼀: 在书中介绍WinMain函数的参数时讲到 "因此WinMain的第⼆个参数通常总是NULL", 那么第⼀个呢?WinMain的第⼀个参数也可以是NULL吗?
疑问⼆: WinMain函数的参数从何⽽来?是操作系统么?
疑问三: 使⽤TEXT()函数的作⽤是什么呢?
在这篇博⽂中笔者表达可⼏个个⼈的见解(也可以说是猜测), 如果有错误或者不妥之处恳请指出, 笔者将⽴即更正, 避免误导其他读者。
Wid, 2012.10.06。