1.API和内存模式:
API包含了所有应用程序构造操作系统的函数调用,也包含了相关的数据类型和结构。
它形成了一个一个特殊的程序体系结构
Windows1.0到3.0中使用分段内存模式,在分段内存模式下,内存地址分为两部分—— 一个16位段指针和一个16为偏移指针。其中带来了long或far指针(包括段地址和偏移量地址)和short或near指针(包括带有假定段地址的偏移量地址)的区别。
WindowsNT和Windows 95开始支持使用32位模式的32位平面内存模式。32位版本Windows编写的程序使用在平面线性空间寻址的简单的32位指针。
Win32操作系统都支持Win16 API调用,但是NT和95,98的工作方式不同,NT中Win16函数调用通过一个转换层被转化为Win32函数调用,然后被操作系统处理。95和98中Win32函数调用通过转换层转换为Win16函数调用,再由操作系统处理。
API文档:MSDN提供了所有API的文档。Windows大致分为Kernel、User和GDI子系统,内核接口在/Platform/SDK/WindowsBase Services中,用户接口函数在/PlatformSDK/User Iterface Services中,GDI位于/PlatformSDK/Graphics and Multimedia Services/GDI中。
2.编写第一个Windows程序:
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
MessageBox(NULL,TEXT("Hello, Windows 98!"), TEXT("HelloMSG"), 0);
return0;
}
Windows程序都是以#include <Windows.h>开始,另外一些比较重要的基本的头文件包括:
Windef.h基本类型定义
WinNT.h支持Unicode的类型定义
WinBase.h内核函数
WinUser.h用户接口函数
WinGDI.h图形设备接口函数
Windows程序入口点是WinMain,以如下的形式出现:
intWINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
其中的WINAPI被定义为__stdcall,用于指定函数调用中在堆栈中放置函数调用参数的方式。第一个参数为实例句柄,Windows编程中句柄是一个应用程序用来识别某些事物的数字。句柄唯一标识该程序,其他的Windows函数需要用该句柄作为参数调用该程序。在Win32中废除了第二个参数,设置为NULL。第三个参数为用于运行程序的命令行,使用这个参数在程序启动时将文件加载到内存。第四个参数指出程序最初显示的方式,正常地或是最大化充满窗口,或是最小化显示在任务栏中。
程序生成过程:
CSource --> [Compiler] --> .obj --> [Linker] --> .exe
+ .lib
3. Unicode简介
Unicode是ASCII字符编码的一个扩展,严格的ASCII码中字符用7位表示,计算机上普遍使用8位表示,Unicode使用全16位字符编码。使得Unicode能够表示世界上所有的书写语言中可能用于计算机通讯的字符,象形文字和其他的符号。
对于ASCII码的扩展,使用8位表示一个字符,甚至是扩展到双字符集,都不能很好解决对所有字符编码的问题,双字符集问题不在于用两个字节表示字符,而在于一些字符是使用一个字节表示,另外的一些字符是使用两个字节表示。这样在解析字符串时要确定是单字节字符还是双字节字符。
Unicode是完全用两个字节表示一个字符,允许表示65535个字符,这就足以表示世界上的所有语言的文字,字符以及数学,符号和货币集合
宽字符:Unicode为宽字符的一种编码形式。
C中的宽字符基于wchar_t数据类型,几个头文件(WCHAR.H)中都有定义:
typedefunsigned short wchar_t;
wchar_t数据类型与无符号短整型相同,都是16位宽。wchar_t c = ‘A’; 由于Unicode字符是两个字节,因此在保存宽字符文件时应该注意,CPU的字节序不同可能会出现问题。定义宽字符串指针 wchar_t *p =L”Hello!”; 其中的L表示字符串按照宽字符保存,每个字符占用两个字节。末尾的结束符0也需要两个字节。
宽字符库函数:
直接将传统的字符串函数用于宽字符串就会出现问题,无法通过编译。各个字符串函数都提供了宽字符版本,strlen的宽字符版本为wcslen(),声明在string.h和wchar.h中都有声明。改成宽字节后,字符串的字符长度并不改变,只有所占用的字节长度改变。
Unicode也有缺点:程序中的每个字符串都将占用两倍的存储空间,再者宽字符运行库中的函数比常规的函数大。这样可能想要建立两个版本的程序——一个处理ASCII码字符串,一个处理Unicode字符串。对此问题的解决办法是维护既能按照ASCII编译又能按照Unicode编译的单一源代码文件。
维护单一源代码文件的方法是使用TCHAR.H头文件,该文件不是ANSI C标准的一部分,定义的每个函数和宏定义的前面都有一条下划线。TCHAR.H为需要字符串参数的标准运行库函数提供了一些列的替代名称,如_tprintf和_tsclen,这些名称被称为“通用”函数名,既可以指向函数的Unicode版,也可以指向非Unicode版。
例如:
如果定义了名为_UNICODE的标识符,并且程序中包含了TCHAR.H头文件,那么_tcslen就定义为wcslen:
#define_tcslen wcslen
如果没有定义UNICODE,则_tcslen定义为strlen:
#define_tcslen strlen
且对于TCHAR类型,定义了_UNICODE标识符,那么TCHAR就是wchar_t,否则TCHAR被定义为char。
typedefwchar_t TCHAR 或者 typedefchar TCHAR
对于字符串中的L问题。如果定义了_UNICODE标识符,那么就有一个__T的宏定义如下:
#define__T(x) L##x
这种语法比较晦涩,属于C预处理的ANSI C标准。一对##称为粘贴符号,将字母L添加到宏参数上。
如果没有_UNICODE定义,那么 __T被定义为 #define __T(x) x
#define_T(x) __T(x)
#define_TEXT(x) __T(x)
可以根据喜好确定使用那个宏定义。
4. Windows头文件类型
WINDEF.H中包含了Windows中使用的基本类型定义,本身也包括WINNT.H,WINNT.H中处理基本的Unicode支持。
WINNT.H包含了C的头文件CTYPE.H,C的众多头文件之一,包含了wchar_t的定义。WINNT.H定义了新的数据类型,称为CHAR和WCHAR
typedefchar CHAR
typedefwchar_t WCHAR
<