精通Windows API(二)Windows API概要

Windows API 概要

本节讲解 Windows 程序设计的一些基本概念。包括在 Windows 应用程序设计中所使用到的一些特有的数据类型;对Windows 众多的API进行了分类介绍;初步介绍Windows API 与动态链接的原理;Windows应用程序所使用的字符集。

Windows 数据类型

在众多的 Windows 数据类型中,最常用的有DWORDHANDLELPTSTRWORDBYTECHAR等。在Windows系统中,DWORD 用于表示无符号整型的数据,意为 dounle word,32位。
一般情况下,BYTE是8位的,WORD 是16位,DWORD是32位的。
Windows 系统的应用程序中特有的数据类型-HANDLE,通常HANDLE类型的变量用于唯一表示一个“对象”,如窗口、控件等。HANDLE也是一个32位的数据类型。

类型示例

1. 示例:

示例定义 几个常用常量的Windows数据类型,并演示如何进行复制、比较大小等操作。项目地址

/*头文件*/
#include <Windows.h>
#include <stdio.h>

/// @brief Windows应用程序入口
/// @param hInstance 数据类型HINSTANCE,此参数表示应用程序本次运行实例的句柄
/// @param hPrevInstance 数据类型HINSTANCE,表示应用程序之前运行实例的句柄,但在实际应用中,此参数始终为NULL
/// @param lpCmdLine 运行时参数,例如在cmd命令行中运行"start.exe command argumeng",那么此参数将指向字符串"command argumeng",类型 LPSTR 是Windows API中常用的字符串类型 
/// @param nCmdShow 表示应用程序窗口(如果有)的显示状态。
/// @return 
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	//定义字符串
	LPSTR szString = "Windows data type ,string";

	//定义字符数组
	CHAR lpString[120];	//要大于szString的长度

	//定义 DWORD 类型的数据
	DWORD dwMax = 0XFFFFFFFF;
	DWORD dwOne = 0X00000001;

	//定义 INT 类型的数据
	INT iMax = 0XFFFFFFFF;
	INT iOne = 0X00000001;

	//显示字符串
	MessageBox(NULL, szString, "LPSTR", MB_OK);

	//复制内容,将字符串复制到数组中(包括NULL结束符)
	CopyMemory(lpString, szString, lstrlen(szString) + 1);

	//显示复制的字符串
	MessageBox(NULL, lpString, "CHAR[]", MB_OK);

	//比较DWORD并显示结果
	if (dwMax > dwOne)
	{
		MessageBox(NULL, "DWORD 类型的数据 0XFFFFFFFF > 0X00000001", "DWORD", MB_OK);
	}

	//比较INT并显示结果
	if (iMax < iOne)
	{
		MessageBox(NULL, "INT 类型的数据 0XFFFFFFFF > 0X00000001", "INT", MB_OK);
	}

	return 0;
}

示例中:LPSTR类型的数据是字符串,也就是字符指针,CHAR是字符,DWORD 是32位的无符号整数,INT是32位有符号整数。
dwMax > dwOne是成立的,iMax < iOne也是成立的,dwMax 与 iMax 的数值是一样的,dwOne 与 iOne 的数值也是一样的。结果不同,是因为二者的数据类型不同。

2.为什么要使用Windows数据类型

Windows API 函数、数据结构等都采用Windows数据类型。比如 Windows API 函数的入口参数、返回值等都是 Windows 数据类型。

3. 查看 Windows 数据类型的定义

在 Visual Studio 中可以查看数据类型的定义。在数据类型的类型名(比如“DWORD”)
上单击右键,选择“转到定义”。
从中可以发现,这些 Windows 数据类型都是从标准 C 的数据类型经过类型重定义而来。
INT 数据类型是有符号整型,DWORD 数据类型是无符号整型。

4.最常见的 Windows 数据类型
类型描述
BOOL布尔类型变量(值只能是True或False)
BYTE字节类型(8位)
CHAR8比特字节(ANSI)
CONST常量,相当于标准 C 中的 “const” 关键字
DWORD32字节无符号整型数据
DWORD3232字节无符号整型数据
DWORD6464字节无符号整型数据
FLOAT浮点类型数据
HANDLE对象的句柄,最基本的句柄类型
HICON图标的句柄
HINSTANCE程序实例的句柄
HKEY注册表键的句柄
HIMODULE模块的句柄
HWND窗口的句柄
INT32位符号整型数据类型
INT_PTR指向INT类型数据的指针类型
INT3232位符号整型
INT6464位符号整型
LONG32位符号整型,相当于C语言标准数据类型long
LONGLONG64位符号整型
LONG3232位符号整型
LONG6464位符号整型
LPARAM消息的L参数
WPARAM消息的W参数
LPCSTRWindows(ANSI)字符串常量
LPCTSTR根据环境配置,如果定义了UNICODE 宏,则是LPCWSTR类型,否则是 LPCSTR类型
LPCWSTRUNICODE字符串常量
LPDWORD指向DWORD类型数据的指针
LPSTRWindows(ANSI)字符串变量
LPTSTR根据环境配置,如果定义了UNICODE,则是LPWSTR类型,否则是LPCSTR类型
LPWSTRUNICODE字符串变量
SHORT无符号短整型(16位)
SIZE_T表示内存大小,以字节为单位,其最大值是CPU最大寻址范围
TCHAR如果定义了UNICODE,则为 WCHAR,否则为CHAR
UCHAR无符号CHAR
UINT无符号INT
ULONG无符号LONG
VOID无类型,相当于标准 C 语言的void
WCHAR16位Unicode字符
WINAPIWindows API的函数调用方式,常见于SDK 头文件中对API函数的声明中,相当于 __stdcall(不是数据类型,是一种函数调用约定)
WORD16位无符号整型数据
5. Windows 数据类型名命名的规律

指针类型的命名方式一般是在其指向的数据类型前加 “LP” 或 “P”,比如指向 DWORD 的指针类型为“LPDWORD” 和 “PDWORD”。
各种句柄类型的命名方式一般都是在对象名前加 “H”。
无符号类型一般是以“U”开头。

Windows 中的数据结构

Windows SDK 中,结构体也有自己的命名规范。一般情况下,Windows 系统中使用全大
写来命名结构体、共用体,并使用“_”来分隔单词,在结构名加“LP”或“P”表示指向数
据结构的指针。


Windows API 的功能分类

系统基本服务

系统基本服务是 Windows API 最基本的内容,是最常使用到的程序接口。系统基本服务
API 包括以下几个方面。

1. 文件系统

对文件的基本操作包括文件的创建、打开、读写、关闭、删除,文件属性的设置与获取,
目录操作,以及磁盘分卷的操作,还包括镜像文件、加密文件系统等。

2. 内存管理

主要是内在的分配、共享、释放等内容,包括虚拟内存管理、分页机制、堆管理等。

3. 进程、线程和模块

包括进程主程序( exe)、模块、动态链接库(dll)的编写;线程的基本概念,线程创建、
遍历、同步等操作;进程与权限;线程与纤程等内容。

4. 设备I/O、驱动程序控制

包括设备对象等基本概念。加载与卸载驱动程序,控制驱动程序,与驱动程序通信等。

5. 调试与错误处理

包括如何开发调试器,程序运行错误的处理,日志的记录、Windows 可执行文件的结构
等。

6. Windows 系统信息包括注册表的操作,如打开注册表,读取、写入键值,创建、删除键;还包括系统基本

信息的获取和设置,如系统目录、系统版本、计算机名等。

7.进程间通信

包括使用共享文件进行进程间通信的方法,使用消息进行进程间通信的方法,使用邮槽、
管道等进行进程间通信的方法,使用网络共享进行进程间通信的方法。

8.定时器与消息机制

消息机制是 Windows 系统中很重要的一种机制。几乎所有的 Windows 应用程序都在与消
息打交道,而 Windows 的消息机制又是依赖于定时器的。所以了解 Windows 消息机制是学习
Windows 应用程序开发的重要内容。

9. 实例

将系统目录信息写入systemroot.text,项目地址

/*
* 获取系统目录信息,并存储到文件中
*/

#include <Windows.h>

int main(int argc, char** argv)
{
	//文件句柄
	HANDLE hFile;
	DWORD dwWritten;

	//字符数组,用于存储系统目录给
	TCHAR szSystemDir[MAX_PATH];

	//获取系统目录
	GetSystemDirectory(szSystemDir, MAX_PATH);

	//创建文件systemroot.txt
	hFile = CreateFile("systemroot.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

	//判断文件是否创建成功
	if (hFile != INVALID_HANDLE_VALUE)
	{
		//将系统目录中系统信息写入文件
		if (!WriteFile(hFile, szSystemDir, lstrlen(szSystemDir), &dwWritten, NULL))
		{
			return GetLastError();
		}
	}

	//关闭文件,返回
	CloseHandle(hFile);
	return 0;
}


//程序输出文件,内容:
//C:\WINDOWS\system32

系统管理

系统管理是 Windows 系统中很重要的内容。Windows 系统提供了以下方面的 API 供应用
程序开发人员使用,包括:管理控制台接口、程序安装、系统恢复、任务调度、Windows 运
程管理。

用户界面

用户界面开发是 Windows 应用程序开发的重要内容。Windows 用户界面主要包括两个部分,
Windows Shell 和 Windows 图形用户界面。Windows 图形用户界面包括窗口对象的相关内容,
界面资源,控件、用户数据交换(粘贴板等)和用户输入的处理。

1.窗口化

包括一些基本数据概念和对象:窗口类、消息对列、窗口过程(消息处理函数)、窗口
属性等。
主要包括的 API 有窗口类注册的函数、窗口建立与关闭函数、窗口属性修改函数等。

2.资源

资源是 Windows 应用程序中很重要的一项内容,在可执行文件中,专门有用于存储资源
的节。
这里所说的资源是界面资源,包括图标、菜单、字符串、版本信息、对话框、动态光标、插
入号(Carets)等。资源的处理涉及众多 API 函数。

3.用户输入处理

包括对话框、键盘加速器(快捷键)、键盘输入、鼠标输入、原始数据输入等。这些概
念是程序通过用户界面与用户进行交互的基本概念。

4.数据交换

包括 Atom 表(包括了若干字符串和标识符)、粘贴板、数据复制、动态数据交接等基本
概念,是用户和应用程序通过用户界面进行数据交换的主要载体。

5.Windows 图形界面通用控件

Windows 系统提供了不少于 30 种的控件供应用程序使用,其中最常用的几种包括 Edit
控件(文本框)、Button 控件(按钮)、ListView 控件(列表)、ToolTip 控件(提示框)、
ComboBox 控件(下拉选择框)、Tree-View 控件(树)、Rich-Edit 控件(多功能文本框)、
Tab 控件(分页)、Process 控件(进度条)等。

6.Windows Shell

Windows 桌面浏览器(explorer.exe)的功能强大,Windows Shell 应用程序可以利用
WindowsShell 桌面的程序接口达到管理系统、定制图标和默认程序、扩展桌面功能等目的。

7. 实例

窗口创建以及消息处理,项目地址

#include <Windows.h>

//全局变量
HINSTANCE hInst;

//函数声明
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);

//功能:显示一个窗口
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wcx;         // 窗口类
    HWND hwnd;              //  窗口句柄     
    MSG msg;                // 消息
    BOOL fGotMessage;       // 是否成功获取消息
    hInst = hInstance;      // 应用程序实例句柄,保存为全局变量

    // 填充窗口类的数据结构
    wcx.cbSize = sizeof(wcx);          // 结构体的大小
    wcx.style = CS_HREDRAW |
        CS_VREDRAW;                    // 样式:大小改变时重绘界面 
    wcx.lpfnWndProc = MainWndProc;     // 窗口消息处理函数 
    wcx.cbClsExtra = 0;                // 不使用类内存
    wcx.cbWndExtra = 0;                // 不使用窗口内存 
    wcx.hInstance = hInstance;         // 所属的应用程序实例句柄 
    wcx.hIcon = LoadIcon(NULL,
        IDI_APPLICATION);              // 图标:默认
    wcx.hCursor = LoadCursor(NULL,
        IDC_ARROW);                    // 光标:默认
    wcx.hbrBackground = (HBRUSH)GetStockObject(
        WHITE_BRUSH);                  // 背景:白色
    wcx.lpszMenuName = NULL;          // 菜单:不使用
    wcx.lpszClassName = "MainWClass";  // 窗口类名 
    wcx.hIconSm = (HICON)LoadImage(hInstance, // 小图标
        MAKEINTRESOURCE(5),
        IMAGE_ICON,
        GetSystemMetrics(SM_CXSMICON),
        GetSystemMetrics(SM_CYSMICON),
        LR_DEFAULTCOLOR);

    // 注册窗口类
    if (!RegisterClassEx(&wcx))
    {
        return 1;
    }

    // 创建窗口 
    hwnd = CreateWindow(
        "MainWClass",        // 窗口名
        "CH 2-3",            // 窗口标题 
        WS_OVERLAPPEDWINDOW, // 窗口样式  
        CW_USEDEFAULT,       // 水平位置X:默认 
        CW_USEDEFAULT,       // 垂直位置Y:默认
        CW_USEDEFAULT,       // 宽度:默认
        CW_USEDEFAULT,       // 高度:默认 
        (HWND)NULL,         // 父窗口:无 
        (HMENU)NULL,        // 菜单:使用窗口类的菜单 
        hInstance,           // 应用程序实例句柄 
        (LPVOID)NULL);      // 窗口创建时数据:无 

    if (!hwnd)
    {
        return 1;
    }

    // 显示窗口 
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 消息循环
    while (
        (fGotMessage = GetMessage(&msg, (HWND)NULL, 0, 0)) != 0
        && fGotMessage != -1)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

/* ************************************
* MainWndProc
* 功能	窗口消息处理函数,
        对所有的消息都使用默认处理函数
**************************************/

/// @brief 窗口消息处理函数,对所有的消息都使用默认处理函数
/// @param hwnd 窗口句柄
/// @param uMsg 消息
/// @param wParam w参数
/// @param lParam l参数
/// @return 
LRESULT CALLBACK MainWndProc(HWND hwnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        ExitThread(0);
        return 0;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

图像和多媒体

Windows 的图像引擎和多媒体编程有多种接口,包括最基本的 GDI、GDI+,以及更高级的
OpenGL、DirectX 等图像引擎编程接口。DirectX 和 OpenGL 在游戏开发、动画制作等方面应
用比较广泛,使用它们进行应用程序开发需要专门的 SDK。本书只讲解 GDI,对一般的应用
程序开发,已经足够使用。
GDI 的基本概念包括图像(Image)、位图(Bitmaps)、笔(Pen)、画刷(Brush)、文本和
字体( Text and Fonts)、线(Line)、区域(Regions)、形状(Shapes)等。其基本的功能是对
显示设备进行控制、获取和修改相关配置,在计算机屏幕上显示用户所需要显示的内容。

网络

用户利用 Windows API 可以开发基于各种网络协议的应用程序,例如 TCP\UDP Socket、
HTTP、DHCP、RPC、QOS、蓝牙,以及传真、点对点文件传输、即插即用设备管理等。
还可以进行网络管理,包括网络的基本信息,使用 IP helper 获取网络配置和网络信息、
进行网络监视等。
同时微软还提供了进行网络安全编程的部分接口,主要是防火墙 Windows、防火墙 API,
以及一些 Windows 自带的网络应用程序的接口,包括 IE、Outlook 等。

系统安全

包括系统的授权与认证、登录、权限管理、加密、安全管理策略等内容。本书将主要介
绍用户管理(包括用户增加、修改设置、删除等)和 Windows 安全对象(任何具有访问控制机制的对象,如文件、进程)和安全操作主体(线程)之间的安全认证机制及权限设置对程
序行为的影响。

其他功能

1.数据存储和访问、数据库

包括微软的“动态数据存取组件”技术(MDAC,包含了 ADO、ODBC)、OLE 数据库、XML
标准、微软 XML、可扩展存在引擎等多方面内容。主要是 Windows 系统内的数据库文件、
Windows.系统对数据库的访问接口等技术。

2.消息与协作

消息与协作大多是 Windows 系统自带的一些应用程序所提供的开发接口。其中最主要的
内容是“协作数据对象”( CDO)。CDO 包括了若干种 Windows 数据传输典型应用,包括 Mssager
(MSN)、邮件 SMTP (Outlook)应用接口等。

3.Web 开发

IIS(Intemet Information Server,互联网信息服务)等应用程序提供的开发接口,
使用户可以直接在 Windows 平台上进行 Web 开发,开发的程序运行于 ns 框架下。
“数据存在与访问”、“消息与协作”、“Web 开发”等都可以归为 COM 开发的范围内。
COM 是 Windows 应用程序接口的一种,具有固定的接口模式,大多是 Windows 系统中自带的
应用程序所提供的开发接口的集合。


Windows API 核心DLL

在 Windows 的系统目录中,存在着很多的动态链接库文件(DLL 文件)。这些 DLL 文件中 包括了 Windows API 函数可执行程序。DLL 将各函数“导出”,这样应用程序就可以找到 DLL中的函数地址,当应用程序调用 Windows API 时,程序会运行到 DLL 中。API 函数主要存在于几个核心的动态连接库文件中。Keme132.dll 是最重要的 DLL,Windows 系统最主要的系统服务 API 函数都存在于 Kerne132.dll 中。User32.dll 主要包括图形用户界面中所使用到
的一些函数接口。
GDI32.dll 中,主要包括 Windows 图形引擎中的接口函数。 当用户调用一个 API 时,系统会通过程序文件中的导入表结构找到需要调用的 API 函数位于哪个 DLL,确定函数的地址,以便应用程序可以成功调用 API 函数。

Kernel32.dll

Kernel32.dll 包括了系统基本服务中最基本的 API 函数,如文件系统、进程与线程、内存管理等。

User32.dll

User32.dll 是 Windows 图形用户界面的主要支持。一些重要的图形用户界面函数由 User32.dll 函数导出。

Gdi32.dll

Gd132.dll 是 Windows GDI 应用程序设计接口,Gdi32.dll 导出了与此相关的若干函数,如 GetTextColor、LineTo、TextOutA 等。

标准 C 函数

标准 C 程序是一种标准,任何支持 C 语言应用程序开发的系统都应该提供 C 语言库函数的 调用。在系统环境下使用标准 C 进行程序开发时,用户所使用的库函数实际上是由操作系统提供的。正是由于各个主流操作系统都提供了一套标准 C 库所定义的函数接口,标准 C 函数库才会有如此广泛的跨越操作系统平台。所以 C 程序仍然依赖于操作系统开发人员为其实现接口,而 C 库函数的实现仍然依赖于操作系统提供的调用接口,如标准 C 函数 fopen 函数在Windows 系统中的实现就依赖于 API CreateFile 函数(CreateFile 实现了文件的创建和打开等操作)。
Windows 系统的 C 标准库函数接口主要存在于 crtdll.dll 中。实际上,C 标准函数库必须由操作系统为其提供接口,否则使用标准 C 开发的程序无法在特定的系统上运行。 Windows XP SP2 系统中,crtdll.dll 有 526 个导出函数,如 fopenprintfstrlen等。

Unicode和多字节

Windows 既可以使用 Unicode 字符集又可以使用传统的字符集(如多字节编码)来实现对多种语言的支持,以适应国际市场的要求。与传统的字符集编码相比,Unicode 是世界通用的字符编码标准,使用 16 位数据表示一个字符,一共可以表示 65535 种字符,可以包括现代计算机中所使用的所有字符,包括各种字母、文字、在出版业中使用的特殊符号等。
传统的字符集,如 Windows ASNI 字符集,使用 8 位数据或将相邻的两个 8 位的数据组合在一起表示特殊的语言字符。Windows 系统采用了 ASNI 字符的扩展方式,如果一个字节是负数,则将其后续的一个字节组合在一起表示一个字符。这种编码方式的字符集也称作“多字节”字符集。

1. 示例

Unicode与多字节编码演示,本实例演示不同宽度的字符串的初始化,并将字符串输出进行比较。代码地址

//头文件
#include <Windows.h>

/// @brief Windows应用程序入口
/// @param hInstance 数据类型HINSTANCE,此参数表示应用程序本次运行实例的句柄
/// @param hPrevInstance 数据类型HINSTANCE,表示应用程序之前运行实例的句柄,但在实际应用中,此参数始终为NULL
/// @param lpCmdLine 运行时参数,例如在cmd命令行中运行"start.exe command argumeng",那么此参数将指向字符串"command argumeng",类型 LPSTR 是Windows API中常用的字符串类型 
/// @param nCmdShow 表示应用程序窗口(如果有)的显示状态。
/// @return 
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	//定义LPWSTR类型的宽字符串
	LPWSTR szUnicode = L"This is a Unicode String";

	//定义LPSTR类型的窄字符串
	LPSTR szMutliByte = "This is a Unicode String";

	//定义LPTSTR类型的自使用字符串
	LPTSTR szString = TEXT("This string is Unicode or not depends on the option");

	//使用W版本的API函数,以宽字符串为参数
	MessageBoxW(NULL, szUnicode, L"<字符编码1>", MB_OK);

	//使用A版本的API函数,以窄字符串为参数
	MessageBoxA(NULL, szMutliByte, "<字符编码2>", MB_OK);

	//根据编译条件自动选择A版本或W版本的API函数,采用相适应的字符串类型为参数
	MessageBox(NULL, szString, TEXT("<字符编码3>"), MB_OK);

	return 0;

}

首先使用“多字节”方式进行编译。可以使用二进制编辑器来查看编译得到的可执行文件,上例中定义的字符串分别存储为以下形式。使用二进制编辑器查看,可以从 exe可执行文件中找到如下信息。
在这里插入图片描述
可以对照 ASCII 编码表查看

“This is a Unicode String;”
54 00 68 00:69 00 73 00 20 00 69 00:73 00 20 00 61 00 20 00:55 00 6E 00 69 00 63 00:6F 00 64 00 65 00 20 00:53 00 74 00 72 00 69 00:6E 00 67 00 3B 00
正好是“This is a Unicode String;”使用 Unicode 方式的十六进制编码。

54 68 69 73:20 69 73 20 6E 6F 74 20:61 20 55 6E 69 63 6F 64:65 20 53 74 72 69 6E 67:3B
是“This is not a Unicode String;”使用 ASCII 方式的十六进制编码。

54 68 69 73:20 73 74 72 69 6E 67 20:69 73 20 55 6E 69 63 6F:64 65 20 6F 72 20 6E 6F:74 20 64 65 70 65 6E 64:73 20 6F 6E 20 74 68 65:20 6F 70 74 69 6F 6E 2E
是字符串“This string is Unicode or not depends on the option.”的 ASCII 方式的十六进制编码,说明编译配置没有使用 Unicode。之后是“<字符编码 1>”和 Unicode 编码、“<字符编码 2>”和“<字符编码 3>”的多字节编码。对汉字字符,两种编码的方式是不同的,如“字符编码”四个字,
两种编码分别为: 57 5B:26 7B 16 7F 01 7800008A70 D7 D6 B7:FB B1 E0 C2

W版本和A版本的API

Windows 支持 Unicode 和 ASCII 编码的字符。Windows 系统 API 凡是以字符串作为参数的很多具有 W 和 A 两个版本以实现两种不同编码的字符处理。
下面以 MessageBox 为例介绍两种不同版本 API 函数的使用。在 User32.dll 中导出的函数实际上没有 MessageBox,只有 MessageBoxA 和 MessageBoxW,这两者是同一个 API,实现了同样的功能。不同的是,MessageBoxA 以多字节字符串作为参数输入,MessateBoxW 以 Unicode 字符串作为参数输入。
可以从 User32.dll 的导出函数看到两个不同版本的 API 函数。在 Platform SDK 中,MessageBox 函数声明所在的头文件中发现如下定义(以下代码来自于 Microsoft Platform SDK):

WINUSERAPI
int
WINAPI
MessageBoxA(
    _In_opt_ HWND hWnd,
    _In_opt_ LPCSTR lpText,
    _In_opt_ LPCSTR lpCaption,
    _In_ UINT uType);
WINUSERAPI
int
WINAPI
MessageBoxW(
    _In_opt_ HWND hWnd,
    _In_opt_ LPCWSTR lpText,
    _In_opt_ LPCWSTR lpCaption,
    _In_ UINT uType);

可以看到,在程序进行编译和连接时,如果程序在 UNICODE 环境下,会使用 MessageBoxW,否则使用 MessageBoxA。
软件开发人员可以自行设定使用 Unicode 编码或都多字节编码文件,不影响程序的正常功能。
但如果在编写程序时,使用的字符集与代码中使用的函数不一致、定义的字符串变量不兼容,将会引起编译错误或者运行程序显示乱码,甚至可能引起程序运行错误,这一点需要引起注意。

Unicode 与 ASCII 的转换

Windows 专门提供了若干个 API 来实现对字符编码的转换工作。WideCharToMultiByteMultiByteToWideCharUnicodeToBytes 函数可以完成这些工作。
WideCharToMultiByte 函数将 Unicode 字符串转换为多字节字符串,以适应 A 版本的API,MultiByteToWideChar 函数将多字节字符串转换为了 Unicode 字符串,以适应 W 版本的 API 的参数形式要求。


对Windows程序设计规范的建议

变量名:通常采用所谓的“匈牙利命名法”,变量名由“类型缩写(小写)”+“变量描述(单词首字母大写)”构成,如字符串类型的变量可以命名为 szFileName,DWORD 类型的数据可以命名为 dwFileSize,指针类型可以命名为 lpBuffer,句柄类型的变量可以命名为 hLogFile 等。
函数名:各单词的首字母大写,如 EnumerateFilesInDrectoryShowFileSize 等。
类型名:全大写,各单词以下划线分隔,如 WIN32_FILE_ ATTRIBUTE_DATA、DWORD、 HANDLE 等。
常量:同类型名的命名方式。
:多与类型名命名方式相同,有的也与函数名命名方式相同。
大括号与代码段:一般大括号独立占一行,大括号内的代码段缩进。如果代码段仅一行(如 if-else 后的语句),也建议使用大括号。
在调用或定义函数时,如果函数太长,可以分行写,将每个参数写一行。一般多于 3个参数的函数需要分行写,以美观和方便阅读为原则。

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows API 函数参考手册 本书编写组 编著 人民邮电出版社 内容简介 内容简介 本书是关于Microsoft Win32 API 函数的完整参考手册。 本书详细介绍了每一个Win32 API 函数的使用方法,其中着重介绍其原型表示、函数说 明、参数说明、注意事项、相应头文件(.H)、链接库(.LIB 或.DLL)和典型示例。对于每 个函数本书给出了相应的示例部分,这样读者在阅读相应的Win32 API 函数时就能很快地了 解它的具体功能和使用方法,便于更快地掌握该接口函数。 本书是从事Microsoft Windows 操作系统开发和应用人员的必备参考书,也可作为大专 院校相关专业师生自学、教学参考用书。 前 言 前 言 Microsoft Win32 API 是Microsoft Windows 操作系统提供的应用程序接口函数,它基本 上概括了应用程序编程中涉及的每个方面。我们在使用MFC 编程时,所用的MFC 函数都 是封装在Win32 API 基础之上的,即MFC 是Win32 API 的一个上层架构。学习Win32 API 能更深刻的理解MFC 的运作机制,同时使用Win32 API 函数编程要比使用MFC 更灵活, 能编写出更加高效的程序。Microsoft Win32 API 也可以在VB 和Delphi 等语言中使用。 Microsoft Win32 API 函数按照功能划分为窗口处理、设备上下文——DC 、绘图函数、 位图和图标、菜单处理、文件处理、同步、处理文本和字体、硬件和系统、Windows 消息、 进程和线程。 本书按功能对Win32 API 函数进行了划分,对于每一个功能部分的函数都具体给出了它 们的函数原型、功能和用法、注意事项、所在头文件、参数调用和典型示例等信息。本书内 容如下: 第 1 章介绍了Win32 应用程序的一些基本知识,例如系统消息传递机制,图形接口编 程等,同时,它也介绍了Win32 API 函数的一些基本知识。 第2 章介绍了关于窗口处理部分的Win32 API 函数,例如窗口创建,撤销等。 第3 章介绍了设备上下文——DC ,例如创建和获取DC 、坐标变换等。 第4 章介绍了绘图函数,例如路径、图元文件等。 第5 章介绍了位图和图标,例如从DLL 中获取图标,设置DIB 的颜色表等。 第6 章介绍了菜单的处理,例如上下文菜单显示,设置位图菜单项等。 第7 章介绍了文件的处理,例如文件查找,加锁和解锁文件等。 第8 章介绍了同步,例如互斥对象,信号量对象和关键段对象等。 第9 章介绍了文本和字体的处理,例如获取系统中字体的信息,输出各种形式的文本等。 第10 章介绍了硬件和系统,例如捕获鼠标,获取各种系统信息等。 第11 章介绍了Windows 消息,例如消息的获取和发送等。 第12 章介绍了进程和线程,例如调试进程和线程,获取和设置进程和线程的各种信息, 比如优先级、工作集等。 本书为立志掌握 Windows 操作系统编程的人提供了一条有效的捷径,对于不同层次的 Windows 操作系统编程人员来说,本书都极具参考价值,是一本不可多得的参考书。 参与本书的主要编写人员有张鸿超、张宏林等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值