刚开端读书Windows程序设计,磕磕碰碰,先做个小笔记缓缓神经,紧假若将MessageBox那一个Windows
API函数的。

率先想起下C语言在决定台下通过正式输入输出函数输出”Hello,world!”的先后,
代码如下

目录

在编排窗口程序的时候,日常须求使用messagebox函数,不管是调剂输入也好,查看变量也罢。那时如果是全字符串的还好,可是一旦须求浮现数值的始末时,用那一个函数就相比麻烦了。须求先使用wsprintf函数执行两次,然后在使用messagebox函数。远没有在指令行下的printf方便,假若是亟需多量弹窗时就更麻烦了。所以决定将那多个函数封装起来,那样messagebox就可以和printf函数一样方便使用了。最后通过两日时间,完结了这几个Unicode编码的函数,时期遇到了好多题目,通过一回次单步调试,查看汇编代码最后化解掉了颇具问题,函数能正常使用了。

  MessageBox函数是恒河沙数人刚起初读书Windows程序设计如故是Windows
API蒙受的首先个放置函数,这一个函数使用的措施是:

#include <stdio.h>

int main()
{
    printf( "Hello,world!\n" ) ;
    return 0 ;
}

2.1       Windows数据类型.. 1

澳门金沙国际 1

  MessageBox(NULL, TEXT(“弹出框内容”),
TEXT(“标题”), MB_OK);

然后明天上了第一趟VC++课后,学会了Windows版Hello,world!,代码如下:

2.1.1       Windows数据类型示例.. 1

源码

  初次之外,它还有多少个姐妹:

#include<windows.h>

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
{
    MessageBox( NULL, TEXT("Hello,world!"), TEXT("MessageBox"), 0 );

    return 0;
}

2.1.2       Windows 数据类型与规范C 数据类型的关系.. 5

/*——————————————————-*/

  MessageBoxA(NULL, “弹出框内容”,
“标题”, MB_OK);   // TEXT可有可无

在VC6.0环境下,新建WIN32
Application,选中C++Sources文件,添加cpp文件后,敲出如上代码,编译,运行,出现下边窗口:

2.1.3       Windows 数据类型与Windows API 5

/* 函数名称: 御坂高级弹窗新闻 – 限长2000限参100 Unicode

  MessageBoxW(NULL, L””, L””, MB_OK);  
                    // 那一个L用来代表Unicode,不得以概括

澳门金沙国际 2

2.1.4       Windows 中的数据结构.. 6

仿printf的messagebox弹窗函数,格式化对话框的安插。/* 函数参数: 第二个是字符串,和printf一样,不定参数个数

  其实之所以有那多个是因为微软索要知足Windows
98之后对汉字等其余语言编码的急需,那种必要通过Unicode已毕,但是微软本意不是要我们运用Unicode来编程,而是经过行使“通用”方式,也就是MessageBox();函数,完成不一样的编码主要如故经过IDE集成开发条件下转移分化的编码方式。回到MessageBox();,后天比较胃痛的是,怎么在MessageBox();中完毕变量的打印呢?

其一对话框中, 有标题栏, 标题栏的始末是”HELLO”,
对话框的内容为”Hello,world!”, 还有一个”确定”按钮, 而且,
没有非凡黑框框窗口, 一切看起来都是那么美好,
来一起探访那段Windows版的Hello,world!吧!

2.2       Windows API 的机能分类.. 7

/* 使用表明: 弹窗的情节可以利用任意多个参数,类型暂时只协助 %d 和 %s

  如同C语言中时常利用printf函数,这几个函数挺有趣的,应为函数输入的参数是绝非界定个数的,约等于是随机改变的。例如:

*关于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

2.2.1       系统主题服务.. 7

/*——————————————————-*/

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int main(){
 5
 6     int x=100, y=200, z=300;    
 7     
 8     printf("%d %d %d.\n", x, y, z);
 9     system("pause");
10     return 0;
11 }

*程序的进口
在Win32控制台程序(Win32 Console Application)中,
应用程序的入口为main()函数,
windows程序的顺序入口和win32控制台程序的输入类似, 为WinMain()函数.
次第的入口函数在WINBASE.H作出了声称, 注明如下:

2.2.2       系统管理.. 9

VOID MSKMessageBox(PTSTR string, …){

 

int
WINAPI
WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nShowCmd
    );

2.2.3       用户界面.. 9

UINT num = 0;

  那么些printf函数不仅能够使用多少个参数打印,仍能用来一贯打印变量,不过MessageBox却无法平昔打印,这一个引起自己的第一手思考。我先想到的是赤手空拳一个缓冲区,利用这几个缓冲区取打印字符数量。当然打印的函数得利用sprintf了

里面由注明可以看看, WinMain函数的再次来到值被定义为int型;
WINAPI为WinMain函数的调用规则, 在WINDEF.H对”WINAPI”作出了如下宏定义:

2.2.4       图像和多媒体.. 15

__asm{//获取字符串的长度,Unicode版本

  

#define WINAPI __stdcall

2.2.5       网络.. 15

//int 3

 1 int main(){
 2     
 3     int a = 12;
 4     char szBuffer[100];             // 使用一个字符数组来做缓冲区
 5 
 6     sprintf(szBuffer, "helloworld %d.\n", a);
 7     _snprintf(szBuffer, 100, "helloworld %d.\n", a);
 8         // 使用_snprintf函数比较安全,因为可以输入限定字符的个数  
 9 
10     printf("%s.\n", szBuffer);
11     puts(szBuffer);                            // 可以使用printf中的%s将szBuffer打印出来,或者用puts直接输出
12     //printf("helloworld.\n");
13 
14     system("pause");
15     return 0;
16 }

表达, WinMain函数的调用规则为”__stdcall”方式,
对于”__stdcall”调用规则, 现在暂时先不去追究, 知道有这么回事就行,
未来会详细询问到的, 现在假使深究”__stdcall”就相差了那篇博文的大旨。

2.2.6       其余职能.. 15

mov eax, string//得到字符串的地址

 

 

2.3       Windows API核心DLL. 16

sss:

  这些缓冲区的法门借使用在MessageBox函数里面,就可以达成打印变量的措施,比如以下代码:

*WinMain函数的参数:
1>. WinMain的首先个参数 HINSTANCE hInstance,
用书上的分解为”实例句柄”, 由于首回接触C语言Windows程序设计,
对那一个句柄的概念也不是很明白, 去完善了下,
句柄的解释为”一个句柄是指使用的一个唯一的平头值,即一个四字节长的数值,来评释应用程序中的分歧对象和同类对象中的分裂的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。”——引用自百度百科->句柄。

2.3.1       Kerne132.dll 16

xor ebx,ebx//清零寄存器

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
    int a = 12;

    TCHAR szBuffer[100];                  // 通用版本
    _stprintf(szBuffer, TEXT("hello 通用 %d"), a);
    MessageBox(NULL, szBuffer, TEXT("通用"), MB_OK  | MB_ICONINFORMATION);

    return 0;
}

小编是这么对句柄进行通晓的, 在一个应用程序中,
平日创立了千千万万的窗口、按钮、标签, 或者使用了一个文书等,
在程序的其他地点, 只要可以得到那个被叫做句柄的东西,
就可见找到该控件或者窗口在内存中的地点,
从而对其开展操作。感觉有点像带参数的main函数,
只是此处的主函数参数为一个句柄。

2.3.2       User32.dll 16

mov bx,word ptr [eax]//获取该地方的两字节的值,赋值给bx

 

2>. WinMain函数的首个参数, 同样是个实例句柄,
但书上又尤为表明说在32位的Windows程序设计中,
WinMain函数的实例句柄概念已不再动用,
因而WinMain的第一个参数平日总是NULL。

2.3.3       Gdi32.dll 16

add num,1//计数+1

  然则每趟都写个缓冲区来存放,并且一不下心忘记行使_snprintf函数,那就GG了,很可能暴发缓冲区溢出的高危。由此,那里运用printf原先函数设计的规律,大家也来规划一个MessageBoxPrintf();函数,用这几个函数来贯彻格式化输出的法力,要落实这么些函数,首先得参考printf();函数的已毕原理。

小编的眼光: 感觉立马就要晕了, 疑问一:
“因而WinMain的第三个参数平时总是NULL”,
那么首先个呢?WinMain的第三个参数会不会也足以是NULL呢? 疑问二:
WinMain函数的参数从何而来?是操作系统么?带着疑问继续向下看。

2.3.4       标准C函数.. 17

add eax, 2//地址偏移+2

int my_printf(const char * szFormat, ...){

    int iReturn;
    va_list pArgs;

    va_start(pArgs, szFormat);
    iReturn = vprintf(szFormat, pArgs);
    va_end(pArgs);

    return iReturn;
}


int main(){

    int x=100, y=200, z=300;

    printf("hello %d, %d, %d.\n", x, y, z);        
    my_printf("test_my_printf,哈哈%d %d.\n", x, y);

    system("pause");
    return 0;
}

3>. WinMain的第八个参数是用来运作程序的命令行, PSTR:
用来针对一个字符串的指针类型, szCmdLine, sz:表示以0最终的字符串;
目标是由此命令行格局运行程序并向主函数中传出参数,
应该似乎给main函数传入参数一样;

2.3.5       其他Dll 17

test bx, bx//判断bx是或不是为0

 

4>. WinMain的第八个参数是一个int型参数,
用来指明程序(窗口)最初怎样被突显, 例如最小化?最大化?全屏?
小编的理念: 应该很有用, 平时见一些游玩一启动就是全屏的,
不过这么些参数也是担心系统传给程序的么?因为从经常运作Windows程序时都是一向双击,
并没有通过命令行给它传播参数,
在编程时应该对先后启动时的突显形式有交代才对,
这样系统再运行时再把那些交代的参数传入给程序告诉程序启动时应该怎么着突显.

2.4       Unicode和多字节.. 17

jne sss//如果不是0则循环

  …表示的情致是传播的参数是可变参数个数的,va_start(pArgs,
szFormat);表示指向szFormat之后的一个参数,那个函数的不计其数东西本身现在也还没通晓过来,之后再来补充,然则现在萧规曹随那么些函数大家得以协调写个MessageBoxPrintf();函数,具体代码如下:

*WinMain函数函数体的MessageBox函数:
MessageBox(), 名如其”人”, 不用猜也晓得那些就是显示一个对话框的函数,
打开API文档,MSDN Library通过索引找到MessageBox函数, 发现其表明如下:

2.4.1       W版本和A版本的API 21

}

// 自己做一个格式化的messageboxprintf对话框
int CDECL MessageBoxPrintf(TCHAR * szCaption, TCHAR * szFormat, ...){

    TCHAR szBuffer[1024];
    va_list pArglist;

    va_start(pArglist, szFormat);
    _vsnprintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), szFormat, pArglist);
    va_end(pArglist);

    return MessageBox(NULL, szBuffer, szCaption, MB_OK | MB_ICONINFORMATION);
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){

    int x=100, y=200, z=300;
    int cxScreen, cyScreen;

    cxScreen = GetSystemMetrics(SM_CXSCREEN);
    cyScreen = GetSystemMetrics(SM_CYSCREEN);

    // MessageBoxW(NULL, L"helloworld", L"biaoti", MB_OK);
    // MessageBoxA(NULL, TEXT("helloworld"), TEXT("biaoti"), MB_OK);
    MessageBoxPrintf(TEXT("我的标题"), TEXT("hello %d %d %d"), x, y, z);    // 把这个函数做好后,直接就可以输出
    MessageBoxPrintf(TEXT("我的屏幕大小"), TEXT("我的屏幕宽度是:%d.\n高度是:%d.\n"), cxScreen, cyScreen);


    return 0;
}

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, 对话框的作风
);

2.4.2       Unicode与ASGII的转换.. 22

TCHAR str[2001] = {0};//最多2000的字节内容,倘诺跨越2000就回去错误

  相当于自己规划出来一个看似printf的小工具,因为微软确实尚未规划MessageBox中展开格式化输出的函数。

在上头示例中对MessageBox函数的调用如下:

2.4.3       对Windows程序设计规范的指出.. 22

DWORD straddress[100] = { 0 };//字符串参数地址,最多100个

MessageBox( NULL, TEXT(“Hello,world!”), TEXT(“MessageBox”), 0 );

2.5       小结.. 23

INT param = 0;//参数个数

首个参数窗口的句柄的实参为NULL, 意思为不属于别的窗口.
其次个参数为对话框的内容, 第多少个参数为对话框的标题,
然则那多个参数都选择了一个TEXT()的函数,
书上讲使用TEXT()的目标是将那些字符串打包到TEXT宏代码里面,
小编尝试了永不这几个TEXT()函数而直白像那样:

 

INT strnum = 0;//新的字符串的计数

MessageBox( NULL, “Hello,world!”, “MessageBox”, 0 );
在VC6.0不会报错,在VS2010下会报错,这么些TEXT其实是为着帮助不一样字符编码的预编译设置,若是定义了UNICODE宏,则TEXT(“”str“”)展开为宽字符串L“str”,反之则举办为“str”。那些题目本身查了诸多材料,详细都记在台式机中。

 

INT arrnum = 0;//数组的计数

澳门金沙国际 3

 

DWORD ebpnum = 0;//先获得EBP的基址

澳门金沙国际 4

2.1    Windows数据类型

Windows API 使用了累累 Windows 自己定义的数据类型。读者或许相比熟稔 C
语言或 C++语言的数据类型。要烂熟运用 Windows API 必需要熟练 Windows
数据类型。那么些数据类型是Windows 特有的。在 SDK 的相关头文件中有定义。

在成千上万的Windows 数据类型中,最常用的有
DWORD、HANDLE、LPTSTR、WORD、BYTE、CHAR 等。在 Windows 系统中,DWORD
用于表示无符号整型的数目,意为 double word,32位。

在形似意况下 BYTE 是 8 位的,而 WORD 是 16 位,DWORD 就是 32 位的。

Windows 系统的应用程序中还有着一个有意的数据类型-HANDLE,日常 HANDLE
类型的变量用于唯一标识一个“对象”,如窗口、控件、文件等,Windows
平斯科普里存在诸多那样的对象,对象是先后操作的目的。HANDLE 也是一个 32
位的数据类型。

DWORD temp;//用来赢得数字的值的

第多个参数为对话框的作风, 一些以MB_始发的有的常量的构成,
可以选取OR(|)运算进行结合, 那几个常量定义在WINUSER.H中, 例如常用的有:

2.1.1    Windows数据类型示例

实例2-1用到了两种为主的 Windows 数据类型,演示 Windows
数据类型在程序中的使用方法。

  1. 实例2-1 常用Windows数据类型演示(DWORD/LPSTR/CHAR/INT)

本实例定义了多少个常用常量的 Windows 数据类型,包罗 DWORD,LPSTR 和
CHAR,并演示了何等行使它们举行了复制、相比较大小等操作。

/* ************************************
*《精通 Windows API》 
* 示例代码
* windata.c
* 2.1.1  常用的 Windows 数据类型
**************************************/
/* 头文件  */
#include <windows.h>
#include <stdio.h>
/* ************************************
* 功能  Windows 数据类型演示
**************************************/
int WINAPI 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 = 0x1;
//定义 INT 类型的数据
INT iMax = 0xFFFFFFFF;
INT iOne = 0x1;
//显示字符串
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 类型的数据 OxFFFFFFFF > 0x1","DWORD",MB_OK);
} 
//比较 INT 并显示结果
if(iMax<iOne)
{
MessageBox(NULL,"INT 类型的数据 OxFFFFFFFF < 0x1","INT",MB_OK);
}
return 0;
}

 

 

在那些顺序中,使用了 4 种 Windows 数据类型,分别是 LPSTR、CHAR、DWORD 和
INT。

LPSTR 类型的多寡是字符串,也就是字符指针,CHAR 是字符,DWORD 是 32
位的无符号整数,INT 是 32 位有记号整数。程序运行后会弹出 4
个对话框。那表明 dw马克斯(Max)>dwOne 是树立的。i马克斯(Max)<iOne 也是树立的。dw马克斯与 i马克斯 的数值是一样的,dwOne 与 iOne
的数值也是一律的。可是比较结实不一样,是因为两者的数据类型不雷同。

 

  1. 查阅Windows数据类型的定义

在 Visual Studio
中得以查看数据类型的概念。在数据类型的类型名(比如“DWORD”)上单击右键,选拔“转到定义”,如图
2-1 所示。

 澳门金沙国际 5

图2-1

可以从 SDK 的头文件中看到各个型的类型定义。

“INT”的定义如下:

 typedef int                 INT;

 

“DWORD”的定义如下:

 typedef unsigned long       DWORD;

 

“CHAR”的定义如下:

 typedef char CHAR;

 

    从中可以发现,这么些 Windows 数据类型都是从标准 C
的数据类型经过类型重定义而来。INT 数据类型是有号子整型,DWORD
数据类型是无符号整型。 那就表达了干吗在实例 2-1 中 INT 数据类型的变量
i马克斯 实际是“-1”,而 DWORD 类型的变量 dw马克斯实际是“4294967295”,所以会冒出如上的可比结实。

  1. 最普遍的Windows数据类型

表2.1 常用的中央Windows数据类型

类型

描述

BOOL

布尔型变量(值只能是True或False)

BYTE

字节类型(8位)

CHAR

8比特字节(ANSI)

CONST

常量,相当于标准C中的”const”关键字

DWORD

32字节无符号整型数据

DWORD32

32字节无符号整型数据

DWORD64

64字节无符号整型数据

FLOAT

浮点数据类型

HANDLE

对象的句柄,最基本的句柄类型

HICON

图标的句柄

HINSTANCE

程序实例的句柄

HKEY

注册表键的句柄

HMODULE

模块的句柄

HWND

窗口的句柄

INT

32位符号整型数据类型

INT_PTR

指向INT类型数据的指针类型

INT32

32位符号整型

INT64

64位符号整型

LONG

32位符号整型,相当于C语言的标准数据类型long

LONGLONG

64位符号整型

LONG32

32位符号整型

LONG64

64位符号整型

LPARAM

消息的L参数

WPARAM

消息的W参数

LPCSTR

Windows(ANSI)字符串常量

LPCTSTR

根据环境配置,如果定义了UNICODE宏,则是LPCWSTR类型,否则是LPCSTR类型

LPCWSTR

UNICODE字符串常量

LPDWORD

指向DWORD类型数据的指针

LPSTR

Windows(ANSIC)字符串常量

LPTSTR

根据环境配置,如果定义了UNICODE宏,则是LPTSTR类型,否则是LPSTR类型

LPWSTR

UNICODE字符串常量

SHORT

无符号短整型(16位)

SIZE_T

表示内存大小,以字节为单位,其最大值是CPU最大寻址范围

TCHAR

如果定义了UNICOD,则为WCHAR,否则为CHAR

UCHAR

无符号CHAR

UINT

无符号INT

ULONG

无符号LONG

VOID

无类型,相当于标准C语言的void

WCHAR

16位Unicode字符

WINAPI

Windows API的函数调用方式,常见于SDK头文件中对API函数的声明中,相当于__stdcall(更严格讲,不是数据类型,而是函数调用约定)

WORD

16位无符号整型数据

  1. Windows数据类型名称命名的原理

Windows 数据类型的命名都很有规律。

着力数据类型包涵 BYTE、CHAR、WORD、SHORT、DOWRD、INT 等。

指针类型的通令形式相似是在其针对性的数据类型前加“LP”或“P”,比如对准
DWORD的指针类型为“LPDWORD”和“PDWORD”。

各样句柄类型的吩咐情势一般都是在目标名前加“H”。Windows
系统中有许多对象,所有代表一个目标的数据类型都是句柄,每一种对象都对应着一种句柄类型,比如与位图(
BITMAP)对应的句柄类型为“HBITMAP”,与菜单(MENU)对应的句柄类型为“HMENU”,与窗口(WINDOW)对应的句柄类型为“HWND”。无符号类型一般是以“U”初阶,比如“INT”是符号类型,“UINT”是无符号类型,“LONG”是标志类型“ULONG”是无符号类型等。

UINT i;

1>.对话框按钮类型:

2.1.2    Windows 数据类型与专业C 数据类型的关系

查阅 Windows 数据类型的概念可以看出,所有的 Windows 数据类型都是由 C
数据类型经过类型重定义获得的。如 DWORD 实质上就是 unsigned long
数据类型,32 位的无符号整型:

typedef unsigned long       DWORD;

 

实际 VC 编译器是一个全部的 C 编译器,别的并从未过多的伸张。Windows
数据类型也不是 VC 的内建项目,而从标准 C 类型重定义获得。

for (i = 0; i< num&& i< 2000; i++){

    #define MB_OK                       0x00000000L           
//仅有一个”确定”按钮
    #define MB_OKCANCEL                 0x00000001L           
//”确定” + “取消”
    #define MB_ABORTRETRYIGNORE         0x00000002L           
//”终止” + “重试” + “忽略”
    #define MB_YESNOCANCEL              0x00000003L            //”是”

2.1.3    Windows 数据类型与Windows API

Windows API 函数的参数、再次回到值或部分至关首要的常量使用的数据类型都是 Windows
数据类型。如:

int MessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption, 
UINT uType
);

 

MessageBox 函数的重临值是 int 型的,是标准 C
数据类型,不过拥有的参数都使用了Windows 数据类型。如 HWND 是一种 W
indows 数据类型,用于表示窗口的句柄;LPCTSTR 也是Windows
数据类型,表示字符串常量;UINT 也是 Windows 数据类型,为无符号整型。

if (string[i] == ‘%’ && (string[i + 1] == ‘d’ || string[i + 1] ==
‘s’)){

  • “否” + “取消”
        #define MB_YESNO                    0x00000004L            //”是”
  • “否”
        #define MB_RETRYCANCEL              0x00000005L           
    //”重试” + “取消”

2.1.4    Windows 中的数据结构

Windows 中隐含很多种数据结构类型,在分裂档次的 API
中会使用到分歧的数据结构,由于数据结构的数量过多,将在接二连三章节具体的实例中牵线已毕每一种成效所选取的数据结构。数据结构日常会作为一些
API 的参数输入。

typedef struct _WIN32_FILE_ATTRIBUTE_DATA{
DWORD    dwFileAttributes;
FILETIME  ftCreationTime;
FILETIME  ftLastAccessTime;
FILETIME  ftLastWriteTime;
DWORD    nFileSizeHigh;
DWORD    nFileSizeLow;
} WIN32_FILE_ATTRIBUTE_DATA,*LPWIN32_FILE_ATTRIBUTE_DATA;

 

相当于:

typedef struct _WIN32_FILE_ATTRIBUTE_DATA{
DWORD    dwFileAttributes;
FILETIME  ftCreationTime;
FILETIME  ftLastAccessTime;
FILETIME  ftLastWriteTime;
DWORD    nFileSizeHigh;
DWORD    nFileSizeLow;
};
typedef _WIN32_FILE_ATTRIBUTE_DATA WIN32_FILE_ATTRIBUTE_DATA;
typedef _WIN32_FILE_ATTRIBUTE_DATA *LPWIN32_FILE_ATTRIBUTE_DATA;

 

Windows SDK 中,结构体也有协调的命名规范。一般情形下,Windows
系统中动用全大写来命名结构体、共用体,并采纳“_”来分隔单词,在协会名加“LP”或“P”表示针对数据结构的指针。

param++;

 

2.2    Windows API 的意义分类

Windows API
所能完成的成效包含广大方面,在进展应用程序的支出时,开发人士可能会利用到文件、进度、内存、权限、系统音信等系统的主题服务和连串管理类的
API,可能会用到图形用户界面、控件等函数和对象,可能须求在界面上绘制图像处理多媒体消息等,还包括举办网络通讯支出等。

__asm{

2>.对话框中的图标类型:  

2.2.1    系统基本服务

系统基本服务是 Windows API
最基本的始末,是最常使用到的程序接口。系统主题服务API 包含以下几个方面。

  1. 文件系统

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

  1. 内存管理

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

  1. 进度、线程和模块

包含经过主程序(
exe)、模块、动态链接库(dll)的编制;线程的基本概念,线程创造、遍历、同步等操作;进度与权力;线程与纤程等内容。

  1. 设施 I/O、驱动程序控制

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

  1. 调剂与错误处理

概括什么样支付调试器,程序运行错误的处理,日志的笔录、Windows
可执行文件的布局等。

  1. Windows 系统音讯

席卷注册表的操作,如打开注册表,读取、写入键值,创立、删除键;还包蕴系统大旨音讯的收获和装置,如系统目录、系统版本、统计机名等。

  1. 进度间通讯

包含运用共享文件进行进程间通信的艺术,使用音信进行进程间通讯的艺术,使用邮槽、管道等展开进度间通讯的不二法门,使用网络共享进行进度间通讯的格局。

  1. 定时器与新闻机制

音信机制是 Windows 系统中很要紧的一种体制。大致所有的 Windows
应用程序都在与音讯打交道,而 Windows
的信息机制又是借助于定时器的。所以通晓 Windows 音信机制是学习Windows
应用程序开发的机要内容。

  1. 其他

Windows
的种类大旨服务还包含性能监视、电源管理、索引与数据存储等,也将在本书中颇具关联。

  1. 实例 2-2 将系统目录音讯写入 systemroot.txt

本实例使用了 Windows 系统焦点服务中的部分
API,落成将系统目录路径写入文件中。在此间不对达成原理做过多的表明,只是使读者对
Windows 系统服务 API 有开端的打听。

/* ************************************
*《精通 Windows API》 
* 示例代码
* basic.c
* 2.2 Windows API 的功能分类
**************************************/
/* 头文件  */
#include <windows.h>
/* ************************************
* 功能  获取系统目录信息,并存储到文件中
**************************************/
int main(int argc, TCHAR 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;
}

 

运转程序,在程序所在的目录会生成文书“systemroot.txt”,文件内容为系统目录。

mov dword ptr[ebpnum], ebp

#define MB_ICONHAND                 0x00000010L           
//一个红X的错误/甘休图标
#define MB_ICONQUESTION             0x00000020L           
//一个问号的精通图标
#define MB_ICONEXCLAMATION          0x00000030L           
//一个风流惊讶号的警戒图标
#define MB_ICONASTERISK             0x00000040L           
//一个带有i的消息提示图标

2.2.2    系统管理

系统管理是 Windows 系统中很重大的始末。Windows 系统提供了以下方面的 API
供应用程序开发人员使用,包含:管理控制台接口、程序安装、系统苏醒、义务调度、Windows
运程管理。

}

同时, 在这几个图标中一些还足以用任何名目代替,
那几个别名在WINUSER.H的定义如下:

2.2.3    用户界面

用户界面开发是 Windows 应用程序开发的要害内容。Windows
用户界面首要概括七个部分,Windows Shell 和 Windows 图形用户界面。Windows
图形用户界面包涵窗口对象的有关内容,界面资源,控件、用户数据沟通(粘贴板等)和用户输入的拍卖。

  1. 窗口化

席卷部分主干数据概念和对象:窗口类、新闻对列、窗口进程(信息处理函数)、窗口属性等。
首要概括的 API
有窗口类注册的函数、窗口建立与关闭函数、窗口属性修改函数等。

  1. 资源

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

  1. 用户输入处理

席卷对话框、键盘加速器(快速键)、键盘输入、鼠标输入、原始数据输入等。这一个概念是先后通过用户界面与用户举办交互的基本概念。

  1. 数据沟通

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

  1. Windows 图形界面通用控件

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

  1. Windows Shell

Windows 桌面浏览器(explorer.exe)的作用强大,Windows Shell
应用程序能够运用WindowsShell
桌面的程序接口达到管理连串、定制图标和默许程序、增添桌面效率等目的。

  1. 实例 2-3 窗口创立以及新闻处理 basic.c

    / **《精通 Windows API》

    • 演示代码
    • window.cpp
    • 2.2 Windows API 的职能分类
      **/
      / 预处理 /
      / 头文件 /
      #include
      / 全局变量 /
      HINSTANCE hinst;
      / 函数扬言 /
      int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
      LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
      /* **
    • 功用 突显一个窗口
      **/
      int WINAPI 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
    • 功效 窗口音讯处理函数,
      对拥有的音讯都选用默许处理函数
      **/
      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);
      }
      }

 

实例中,首先注册了窗口类,然后创制了一个窗口,创立窗口时指定的窗口的属性和窗口信息的处理函数。函数信息的处理函数大多调用系统默许函数来处理。如下:

D:\002>cl window.cpp user32.lib gdi32.lib
用于 80x86 的 Microsoft (R) 32 位 C/C++ 优化编译器 15.00.21022.08 版
版权所有(C) Microsoft Corporation。保留所有权利。
window.cpp
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
/out:window.exe
window.obj 
user32.lib
gdi32.lib

 

运行效果:

 澳门金沙国际 6

if (string[i] == ‘%’ && string[i + 1] == ‘d’){

#define MB_ICONWARNING              MB_ICONEXCLAMATION        
//警告
#define MB_ICONERROR                MB_ICONHAND               
//错误
#define MB_ICONINFORMATION          MB_ICONASTERISK           
//信息
#define MB_ICONSTOP                 MB_ICONHAND               
//停止

2.2.4    图像和多媒体

Windows 的图像引擎和多媒体编程有多种接口,包罗最基本的
GDI、GDI+,以及更尖端的OpenGL、DirectX 等图像引擎编程接口。DirectX 和
OpenGL
在戏耍支付、动画制作等地方选用比较宽泛,使用它们举办应用程序开发需要特地的
SDK。本书只讲解 GDI,对一般的应用程序开发,已经够用使用。

GDI
的基本概念包涵图像(Image)、位图(Bitmaps)、笔(Pen)、画刷(Brush)、文本和字体(
Text and
Fonts)、线(Line)、区域(Regions)、形状(Shapes)等。其主干的出力是对突显设备开展支配、获取和修改相关安插,在处理器显示器上出示用户所急需出示的始末。

TCHAR number[11] = { 0 };//INT整数最多10位

 

2.2.5    网络

用户使用 Windows API 可以付出基于各类网络协议的应用程序,例如 TCP\UDP
Socket、HTTP、DHCP、RPC、QOS、蓝牙5.0,以及写真、点对点文件传输、即插即用设备管理等。
还是可以举行网络管理,包蕴网络的宗旨音讯,使用 IP helper
获取网络安排和网络新闻、举行网络监视等。
同时微软还提供了拓展网络安全编程的片段接口,紧如若防火墙 Windows、防火墙
API,以及部分 Windows 自带的网络应用程序的接口,包罗 IE、Outlook 等。

temp = ebpnum + 4 * param + 8;


2.2.6    其余功用

Windows API
能已毕的效能还有众多,限于篇幅不可能全体介绍。有局地情节本书未涉嫌,可是Windows API 也提供了有关接口。

  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
系统中自带的应用程序所提供的付出接口的聚合。

wsprintf(number, TEXT(“%d”), *(DWORD*)temp);

2.3    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
函数。

int test = 0;

2.3.1    Kerne132.dll

Keme132.dll 包涵了系统主题服务中最基本的 API
函数,如文件系统、进度与线程、内存管理等。 Windows XPSP2
系统中,Keme132.d11 有 949
个导出函数,例如,CreateFileA、CreateProcessA、OpenThread、SetFile提姆e
等。本书将在一连章节中经过实例介绍这么些 API的利用。

test = lstrlen(number);

2.3.2    User32.dll

User32.dll 是 Windows
图形用户界面的主要性辅助。一些根本的图形用户界面函数由User32.dll
函数导出。Windows XP SP2 系统中,User32.dll 有 732
个导出函数,例如CreateWindowExW、RegisterClassA 等。

memcpy(&str[strnum], number, lstrlen(number) * 2);//unicode

2.3.3    Gdi32.dll

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

strnum += lstrlen(number);

2.3.4    标准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 个导出函数,如 fopen、printf. strlen等。

i++;

2.3.5    其他Dll

理所当然,Windows 系统中的 DLL 文件远远不止这多少个,Windows
系统提供了万分充分而且功用强大的 API,上文已经介绍了 Windows API
所紧要依靠的多少个 DLL,其余的 DLL
库文件由于过于庞杂,就不一一介绍,将在继承的章节中装有涉及。读者只必要明白调用
Windows API 的基本原理就足以了。

} else{

2.4    Unicode和多字节

Windows 既可以使用 Unicode
字符集又有啥不可使用传统的字符集(如多字节编码)来落到实处对多种语言的支撑,以适应国际市场的须求。与历史观的字符集编码相比,Unicode
是社会风气通用的字符编码标准,使用 16 位数据表示一个字符,一共可以象征 65535
种字符,可以概括现代电脑中所使用的所有字符,包罗种种字母、文字、在出版业中选择的特殊符号等。
传统的字符集,如 Windows ASNI 字符集,使用 8 位数据或将附近的七个 8
位的数额整合在协同表示特其他言语字符。Windows 系统使用了 ASNI
字符的扩大形式,借使一个字节是负数,则将其持续的一个字节组合在一齐表示一个字符。那种编码情势的字符集也叫做“多字节”字符集。

在 Windows 系统中,Unicode 字符编码和多字节字符编码都足以利用。

  1. 实例 2-4 Unicode 与多字节编码演示

    / *澳门金沙国际 ,*《精通 Windows API》

    • 演示代码
    • StringCode.c
    • 2.4 Unicode 和多字节
      **/
      / 预处理 /
      / 头文件 /
      #include
      /* **
    • 效果 Unicode 与多字节编码演示
      **/
      int WINAPI WinMain(
      HINSTANCE hInstance,
      HINSTANCE hPrevInstance,
      LPSTR lpCmdLine,
      int nCmdShow
      )
      {
      //定义 LPWSTR 类型的宽字符串
      LPWSTR szUnicode = L”This is a Unicode String;”;
      //定义 LPSTR 类型的窄字符串
      LPSTR szMutliByte = “This is not 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);
      //使用自适用的 API 函数,采取相适应的字符串类型为参数。
      MessageBox(NULL,szString,TEXT(“<字符编码 3>“),MB_OK);
      return 0;
      }

 

在本实例中,一共动用了 3
种类型的字符串变量,每连串型的字符串变量的初叶化是例外的,如表 2.2
所示。

表2.2 字符串与初叶化

类型

变量类型

初始化形式

Unicode

LPWSTR

L”string”

多字节

LPSTR

”string”

根据开发环境的设置自动适应

LPTSTR

TEXT(”string”)

本实例首先应用“多字节”情势展开编译。能够利用二进制编辑器来查阅编译得到的可执行文件,上例中定义的字符串分别存储为以下形式。使用二进制编辑器查看,可以从
exe可执行文件中找到如下音讯。读者可以对照 ASCII 编码表查看。

“This is a Unicode String;”使用 Unicode 格局的十六进制编码:

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

 

 澳门金沙国际 7

“This is not a Unicode String;”使用 ASCII 形式的十六进制编码:

54 68 69 73 20 69 73 20 61 20 55 6e 69 63 6f 64 65 20 53 74 72 69 6e 67 3b

 

 澳门金沙国际 8

“This string is Unicode or not depends on the option.”的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

 

自此是“<字符编码 1>”和 Unicode 编码、“<字符编码
2>”和“<字符编码
3>”的多字节编码。对汉字字符,二种编码的措施是例外的,如“字符编码”几个字,两种编码分别为:

Unicode编码

57 5b 26 7b 16 7f 01 78

 

 澳门金沙国际 9

和多字节ASCII

d7 d6 b7 fb b1 e0 c2 eb

 

 澳门金沙国际 10

读者能够分析设置使用 Unicode
字符集后编译落成的可执行文件与安装为多字节字符集后编译得到的可执行文件有啥样差异。

 

  1. 在工程安顿中精选编码格局

设置的艺术是在Visual
Studio工程属性中选用“配置属性”→“常规”→“字符集”选项中开展接纳。

//——————————————–

2.4.1    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);
#ifdef UNICODE
#define MessageBox MessageBoxW
#else 
#define MessageBox MessageBoxA
#endif // !UNICODE

 

可以看到,在程序开展编译和延续时,假诺程序在 UNICODE 环境下,会动用
MessageBoxW,否则使用 MessageBoxA。

软件开发人士可以活动设定使用 Unicode
编码或都多字节编码文件,不影响程序的正规机能。

但万一在编写程序时,使用的字符集与代码中行使的函数分歧等、定义的字符串变量不合营,将会挑起编译错误或者运行程序突显乱码,甚至可能滋生程序运行错误,那一点亟待引起注意。

temp = ebpnum + 4 * param +
8;//取得参数的地址,然后4字节的值写入到相应地点

2.4.2    Unicode与ASGII的转换

Windows 专门提供了好三个 API
来贯彻对字符编码的转移工作。ideCharToMultiByte、MultiByteToWideChar、UnicodeToBytes
函数可以完毕那一个干活儿。

WideCharToMultiByte 函数将 Unicode 字符串转换为多字节字符串,以适应 A
版本的API,MultiByteToWideChar 函数将多字节字符串转换为了 Unicode
字符串,以适应 W 版本的 API 的参数格局需求。

straddress[arrnum] = *(DWORD*)temp;

2.4.3    对Windows程序设计规范的提出

每个程序员都有谈得来的规范化编程习惯。代码的正儿八经不是本书的紧要,所以那里只交付一些微软平常拔取代码规范,MSDN
的演示中,SDK 的头文件和例子中大概都是运用的那种格局。

变量名:平日使用所谓的“匈牙利(Hungary)命名法”,变量名由“类型缩写(小写)”+“变量描述(单词首字母大写)”构成,如字符串类型的变量可以命名为
szFileName,DWORD 类型的数量足以命名为 dwFileSize,指针类型可以命名为
lpBuffer,句柄类型的变量可以命名为 hLogFile 等。

函数名:各单词的首字母大写,如 EnumerateFilesInDrectory、ShowFileSize
等。

品种名:全大写,各单词以下划线分隔,如 WIN32_FILE_
ATTRIBUTE_DATA、DWORD、 HANDLE 等。

常量:同类型名的命名方式。

宏:多与种类名命名格局相同,有的也与函数名命有名的模特式同样。
大括号与代码段:一般大括号独立占一行,大括号内的代码段缩进。若是代码段仅一行(如
if-else 后的口舌),也提出使用大括号。

在调用或概念函数时,假如函数太长,可以分行写,将每个参数写一行。一般多于
3个参数的函数须求分行写,以精粹和方便阅读为条件。

在本书的演示中,都将尽可能使用那一个规范化的方法。

 

int testnum = 0;

2.5    小结

PDF下载:

摘自:《通晓Windows.API-函数、接口、编程实例》 人民邮电出版社

范文庆、周彬彬、安靖写作

 

__asm{//获取字符串的长度,Unicode版本

mov ecx, arrnum

mov eax, straddress

mov eax, straddress[ecx * 4]

sss2 :

xor ebx, ebx

mov bx, word ptr[eax]

add testnum, 1

add eax, 2

test bx, bx

jne sss2

dec testnum

}

memcpy(&str[strnum], straddress[arrnum], testnum * 2);//unicode

strnum += testnum;

i++;

arrnum++;

//——————————————–

}

} else{

str[strnum] = string[i];

strnum += 1;

}

}

TCHAR msg[2001] = {0};

wsprintf(msg, TEXT(“字符串:%s 长度:%d 参数:%d”), str, lstrlen(str),
param);

MessageBox(NULL, msg, TEXT(“御坂高级弹窗音信”), MB_OK);

}

相关文章