15天学习C语言Windows程序设计.docx
- 文档编号:30702457
- 上传时间:2023-08-19
- 格式:DOCX
- 页数:224
- 大小:1.58MB
15天学习C语言Windows程序设计.docx
《15天学习C语言Windows程序设计.docx》由会员分享,可在线阅读,更多相关《15天学习C语言Windows程序设计.docx(224页珍藏版)》请在冰豆网上搜索。
15天学习C语言Windows程序设计
C语言Windows程序设计->第一天->第一个Windows程序
在《Windows程序设计》(第五版)第一章的起步中,作者介绍了学习Windows程序设计的一些基本要求:
1.能够从用户角度熟练的使用Windows;
2.懂得如何使用C语言;
3.安装好了Windows的开发环境.
看起来要求并不算高(怎么样?
一起来尝试下?
)。
笔者在这里决定使用VisualC++6.0作为开发环境,虽说在VisualStudio这个大家族中,VC++6早已被长江后浪推前浪,把VC++6推成了一个将近淘汰的环境,但是作者的机器实在是有点不够给力,启动VS2010时相对比较慢。
总之,既然CharlesPetzold也假定我会用VisualC++6.0,那么我就用VC++6好了。
·介绍Windows
*Windows的历史:
是的,你不用惊讶,Windows在这里就是指的微软(Microsoft)的那个操作系统,Windows的历史如果要详细介绍的话,我觉得可能要单开个随笔分类才行,所以这里就简略的介绍下,不过我还是建议你去搜索引擎查找下关于Windows的历史(如果你认为有必要的话)。
1>.1985年11月,Windows1.0正式推出;
IBM与Microsoft共同开发,基于DOS系统,通过DOS来进行文件操作,当然,2.0、3.0也都是基于DOS的,直到Windows2000的发布,Windows才彻底的摆脱了DOS,成为真正独立的操作系统。
2>.1987年11月,Windows2.0推向市场;相对于1.0,2.0在界面上做了些改动,采用了重叠窗口。
3>.1990年5月,Windows3.0推向市场;支持Intel286、386、486微处理器的16位保护模式。
4>.1993年7月,WindowsNT投放市场;Windows家族中第一个支持Intel386、486、奔腾微处理器32位模式的版本。
5>.1995年8月,Windows95发布;一个混合的16位/32位Windows系统。
6.>1998年6月,Windows98进入市场;基于Windows95编写,对Windows95的改进。
书的作者就将Windows介绍到这里(没办法,人家这本书就是1998年写好的),后来的Windows就更猛了,横扫桌面,Windows2000/2003/XP/Vista/2008/7/8...,都懂得。
*Windows的优点:
更加人性化?
操作更简单?
一定还有其他的优点。
*工作原理的中心思想:
"动态链接"概念即为Windows工作原理的中心思想,通过调用Windows自带的函数来实现在屏幕上显示文本与图形。
函数通过动态链接库实现,.dll以及.exe的文件,在Windows98中,这些文件在\Windows\System子目录下,NT的在\WinNT\System或\WinNT\System32,NT以上放在\Windows\System32。
·关于Windows编程
*WindowsAPI:
API,ApplicationProgrammingInterface,应用程序编程接口,WindowsAPI实际上也就是Windows提供的一些函数,通过对这些函数的调用完成应用程序的开发。
*API文档:
这份文档里介绍了Windows提供的已公开的所有API,你可以下载份离线的,或者去MSDN在线图书馆(MSDNLibraryOnline)查阅这份文档.上午的随笔暂时写到这里,感觉写的有点短,其实书上写了很多,仔细品味了好几遍,越品味越有种找不到重点的感觉,要是比着书上的句子抄,这博文岂不是太无味了,我想,这些Windows的背景知识对编程影响或许也不是很大,所以在这里就不啰嗦这些了。
下午学习"你的第一个Windows程序"。
*我的第一个Windows程序,Hello,world!
在CharlesPetzold的书中,作者首先回顾了下C语言在控制台下通过标准输入输出函数输出"Hello,world!
"的程序,代码如下:
#include
intmain()
{printf("Hello,world!
\n");
return0;}
同样,CharlesPetzold也给出了Windows版的"Hello,world!
"(其实他给出的是Hello,windows98!
),代码如下:
#include
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,PSTRszCmdLine,intiCmdShow)
{
MessageBox(NULL,TEXT("Hello,world!
"),TEXT("MessageBox"),0);
return0;
}
通过VisualC++6.0的"文件"-->"新建"-->"工程",选择"Win32Application"创建一个空的项目,再在这个项目中新建一个"文件",文件类型为"C++SourceFile",文件以.c为扩展名,将上面的代码敲入或者复制粘贴到这个文件内容中,经过编译运行就可以得到一个对话框了,赶紧截图留念吧!
在这个对话框中,有标题栏,标题栏的内容是"MessageBox",对话框的内容为"Hello,world!
",还有一个"确定"按钮,而且,没有那个黑框框窗口,一切看起来都是那么美好,来一起看看这段Windows版的Hello,world!
吧!
*Windows版的Hello,world!
代码注释*
*第一行
#include
稍微有点C语音基础的都能明白,这是要包含"windows.h"这个头文件,也就说明,在下面的代码中,要用到这个头文件,如果我们将#include
Compiling...
HelloWorld.c
d:
\project\lwinc\helloworld\helloworld.c(3):
errorC2061:
syntaxerror:
identifier'WinMain'd:
\project\lwinc\helloworld\helloworld.c(3):
errorC2059:
syntaxerror:
';'d:
\project\lwinc\helloworld\helloworld.c(3):
errorC2146:
syntaxerror:
missing')'beforeidentifier'hInstance'd:
\project\lwinc\helloworld\helloworld.c(3):
errorC2061:
syntaxerror:
identifier'hInstance'd:
\project\lwinc\helloworld\helloworld.c(3):
errorC2059:
syntaxerror:
','d:
\project\lwinc\helloworld\helloworld.c(3):
errorC2059:
syntaxerror:
')'执行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控制台程序(Win32ConsoleApplication)中,应用程序的入口为main()函数,windows程序的程序入口和win32控制台程序的入口类似,为WinMain()函数.
程序的入口函数在WINBASE.H作出了声明,声明如下:
intWINAPIWinMain(
HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPSTRlpCmdLine,
intnShowCmd
);
其中由声明可以看出,WinMain函数的返回值被定义为int型;
WINAPI为WinMain函数的调用规则,在WINDEF.H对"WINAPI"作出了如下宏定义:
#defineWINAPI__stdcall
说明,WinMain函数的调用规则为"__stdcall"方式,对于"__stdcall"调用规则,现在暂时先不去深究,知道有这么回事就行,以后会详细了解到的,现在如果深究"__stdcall"就偏离了这篇博文的主题。
*WinMain函数的参数:
1>.WinMain的第一个参数HINSTANCEhInstance,用书上的解释为"实例句柄",由于第一次接触C语言Windows程序设计,对这个句柄的概念也不是很了解,去百科了下,句柄的解释为"一个句柄是指使用的一个唯一的整数值,即一个四字节长的数值,来标志应用程序中的不同对象和同类对象中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。
"——引用自XX百科->句柄。
笔者是这样对句柄进行理解的,在一个应用程序中,通常创建了很多的窗口、按钮、标签,或者使用了一个文件等,在程序的任何地方,只要能够获得这个被称为句柄的东西,就能够找到该控件或者窗口在内存中的位置,从而对其进行操作。
感觉有点像带参数的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函数:
MessageBox(),名如其"人",不用猜也知道这个就是显示一个对话框的函数,打开API文档,MSDNLibrary通过索引找到MessageBox函数,发现其声明如下:
intMessageBox(
HWNDhWnd,//handleofownerwindow,窗口的一个句柄
LPCTSTRlpText,//addressoftextinmessagebox,一个文本(字符串)的指针
LPCTSTRlpCaption,//addressoftitleofmessagebox,标题字符串的指针
UINTuType//styleofmessagebox,对话框的风格
);
在上面示例中对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>.对话框按钮类型:
#defineMB_OK0x00000000L//仅有一个"确定"按钮
#defineMB_OKCANCEL0x00000001L//"确定"+"取消"
#defineMB_ABORTRETRYIGNORE0x00000002L//"终止"+"重试"+"忽略"
#defineMB_YESNOCANCEL0x00000003L//"是"+"否"+"取消"
#defineMB_YESNO0x00000004L//"是"+"否"
#defineMB_RETRYCANCEL0x00000005L//"重试"+"取消
2>.对话框中的图标类型:
#defineMB_ICONHAND0x00000010L//一个红X的错误/停止图标
#defineMB_ICONQUESTION0x00000020L//一个问号的询问图标
#defineMB_ICONEXCLAMATION0x00000030L//一个黄色感叹号的警告图标
#defineMB_ICONASTERISK0x00000040L//一个带有i的信息提示图标
同时,在这些图标中有的还可以用其他名称代替,这些别名在WINUSER.H的定义如下:
#defineMB_ICONWARNINGMB_ICONEXCLAMATION//警告
#defineMB_ICONERRORMB_ICONHAND//错误
#defineMB_ICONINFORMATIONMB_ICONASTERISK//信息
#defineMB_ICONSTOPMB_ICONHAND//停止
下午的学习暂时就到这里,在学习的过程中出现了几个疑问,在这里对疑问进行下总结:
疑问一:
在书中介绍WinMain函数的参数时讲到"因此WinMain的第二个参数通常总是NULL",那么第一个呢?
WinMain的第一个参数也可以是NULL吗?
疑问二:
WinMain函数的参数从何而来?
是操作系统么?
疑问三:
使用TEXT()函数的作用是什么呢?
C语言Windows程序设计->第二天->ASCII与Unicode
一、ASCⅡ
1>.关于ASCⅡ
ASCII(AmericanStandardCodeforInformationInterchange,美国信息互换标准代码)
ASCII一共包含128个字符,包括:
33个控制符号,1个空格,32个符号,10个数字,26个小写字母和26个大写字母。
每个ASCII字符采用7位二进制编码的方式。
ASCII的优点:
十分可靠,普遍扎根在我们的键盘、显示器、系统硬件、打印机、操作系统等,用途十分广泛。
ASCII的缺点:
ASCII,美国信息互换标准代码,美国原生,不能满足其他国家文字的需求,例如,中国的汉字?
英国的英镑符号(£)?
等,这些在ASCII都是找不到的。
2>.对ASCII的扩展
由于ASCII不能很好的满足其他国家文字的需求,所以人们迫切希望能对ASCII进行改进。
①.国际化标准组织的扩展方案
1967年,国际化标准组织(ISO,InternationalOrganizationforStandardization)推荐了ASCII的一个变种,改动内容包括:
从ASCII中,拿出0x40('@'),、0x5B('[')、0x5C('\')、0x5D(']')、0x5E('^')、0x60(''')、0x7B('{')、0x7C('¦')、0x7D('}')、0x7E('~')这10个符号保留给各个国家单独使用。
这显然不是解决ASCII国际化的好方法,首先,其他国家将这些保留字符重新定义为自己国家需要的字符后,那么国际上的一致性将不能得到保证,此外,10个保留字符远远不能满足美国的东方的一些国家使用的象形文字需求,比如我们中国的汉字。
②.IBM公司的扩展方案
IBM公司采用了使用8位二进制编码方式来表示ASCII,使用一个字节来储存字符,这样,相对于7位的ASCII就可以多出128个额外字符空位来补充ASCII。
IBM对ASCII的主要扩展为:
补充了一些重音字符、小写希腊字母、块图字符和线图字符。
同时,还将一些补充的字符分配到ASCII的一些不必要的控制字符上。
(注:
在操作系统还是字符模式的年代,块图字符和线图字符常用来被应用软件装饰自己的程序显示)
③.微软公司的扩展方案
1985年11月,Windows1.0发布,微软采用了自己定义的一套字符集,这套字符集被称为"ANSI字符集",是基于ANSI和ISO标准的一个草案。
在MS-DOS3.3时代(1987年4月),微软为了使不同国家的计算机都能正常的显示字符,微软采用了代码页概念,不同国家的字符被规定在不同的代码页上,例如代码页第437页为美国英语,850页为拉丁语-1。
用户只要将代码页设置到自己所在的国家就能正常的进行工作,但是如果用户尝试着将自己的文档拿到与另外一个使用不同代码页的用户的计算机上进行修改时,自己的文档的某些字符将会显示成其他字符,这还算好,有解决方案,应用软件可以通过将代码页信息储存到文件中,使用时再进行一些代码页的转换。
但在后来,随着代码页数量的剧增,Windows版本的不断升级,代码页的混淆问题开始日益凸显,DS-DOS的代码页和Windows的代码页以及其他Windows版本的系统发生了不兼容,例如MS-DOS代码页第855页西里尔语在Windows中的1251页西里尔语或者Macintosh的第10007页西里尔语还都不一样。
微软为了解决东方一些国家使用的象形文字问题,使用了双字节字符集,这些字符集同样在不同的代码页,代码页936(简体中文)、949(韩文)、950(繁体中文)以及932(日文)。
微软的这个双字节字符集和你象形的可能有所不同,在这个双字节字符集中,前128个字符仍然是ASCII(1字节),较高的128个扩展字符以跟随第二个字节的方式用来表示象形文字(这两个字节被称为前导字节和尾随字节)。
所以在这个代码页中,有一个字节的字符,还有2个字节的字符,这就导致了两个严重的问题:
1>.在一段字符串中,字符串的长度不能根据字节的个数确定,要想确定字符串的长度必须检查每个字节是不是双字节字符的前导字节。
2>.通过任意指向字符串中的一个指针,无法知道前一个字符的地址,通常要回到字符串的开始,一直解析到指针所在的位置。
二、Unicode
对ASCII扩展的过程中,没有能够找到一个彻底解决世界上所有书面文字的表示方法,很显然,1个字节,256个字符是无法表示世界上所有的书面文字的,因此,Unicode诞生了。
Unicode使用16位(2字节)的二进制编码方式来表示字符,我们知道,16位最多能够表示65536个字符,65536个字符对于世界上的所有书面文字以及一些特殊符号来说已经足够用了。
在Unicode中,不同国家使用不同的代码段,例如,0x0530-0x058F为亚美尼亚语(Armenian)、0x0600-0x06FF为阿拉伯文(Arabic)、0x0E00-0x0E7F为泰文(Thai)、0x2700-0x27BF为印刷符号(Dingbats)、0x4E00-0x9FBF为中文。
Unicode的优点:
只有一个字符集,避免了二义性,能够满足跨语言、跨平台进行文本转换、处理的要求。
Unicode的缺点:
Unicode字符的字符串比ASCII字符串占用的内存大两倍。
(笔者认为,随着计算机性能的不断提高,内存和外存容量的不断增加,Unicode这一缺点可以慢慢忽略)。
C语言Windows程序设计->第二天->宽字符和C语言
一、回顾C语言中的char数据类型
1>.在C语言中,首先我们来声明一个字符型变量:
charc;
我们也可以在声明时对其进行初始化:
charc='A';
这时,字符型变量c就会被值0x41进行初始化,0x41也就是ASCII码中的'A'字符;
2>.我们还可以定义一个指向一个字符型数据的指针,例如:
char*p;
同样我们再让指针p初始化时指向一个字符串:
char*p="Hello,world!
";
3>.我们再声明一个字符数组:
chara[10];
也可以在声
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 15 学习 语言 Windows 程序设计