图片 15

你的第一个Windows程序,格式化对话框的设计

  刚开首读书Windows程序设计,磕磕碰碰,先做个小笔记缓缓神经,首要是将MessageBox那几个Windows
API函数的。

C语言是面向进程的,而C++是面向对象的

目录

  MessageBox函数是诸两个人刚起先学习Windows程序设计依旧是Windows
API碰着的首先个放置函数,这几个函数使用的办法是:

C和C++的区别:

2.1       Windows数据类型.. 1

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

C是二个结构化语言,它的严重性在于算法和数据结构。C程序的宏图入眼思索的是什么通过二个进度,对输入实行演算处理拿到输出调整卡塔 尔(阿拉伯语:قطر‎。

2.1.1       Windows数据类型示例.. 1

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

C++,首要考虑的是怎么样组织四个对象模型,让那些模型能够切合与之对应的难题域,这样就能够通过拿到对象的情事音讯获取输出或促成进度序调整制。
所以C与C++的最大差异在于它们的用来缓慢解决难题的考虑艺术不相近。之所以说C++比C更上进,是因为“
设计这些概念已经被融入到C++之中 ”。

2.1.2       Windows 数据类型与业内C 数据类型的关系.. 5

  Message博克斯A(NULL, “弹出框内容”,
“标题”, MB_OK);   // TEXT未足轻重

C与C++的最大差异:在于它们的用来减轻难点的构思格局不平等。之所以说C++比C更升高,是因为“
设计这一个概念已经被融入到C++之中
”,而就语言自己来说,在C中愈来愈多的是算法的概念。那么是否C就不重大了,错!算法是前后相继设计的根底,好的宏图若无好的算法,同样非常。并且,“C加上好的布署”也能写出分外好的事物。

2.1.3       Windows 数据类型与Windows API 5

  MessageBoxW(NULL, L””, L””, MB_OK);  
                    // 这一个L用来表示Unicode,不得以大致

图片 1

2.1.4       Windows 中的数据结构.. 6

  其实之所以有那五个是因为微软特殊必要满意Windows
98之后对汉字等任何语言编码的必要,这种须求通过Unicode实现,然而微软本意不是要咱们应用Unicode来编制程序,而是通过动用“通用”方式,也便是MessageBox();函数,完成分歧的编码首要照旧通过IDE集成开荒条件下转移差异的编码方式。回到MessageBox();,明日相比较胸口痛的是,怎么在MessageBox();中贯彻变量的打字与印刷呢?

上次咱们说了何等是windows编制程序?明白到Windows API
编制程序、Windows编制程序、Windows SDK 编制程序是二个概念。

2.2       Windows API 的法力分类.. 7

  就疑似C语言中时常利用printf函数,那些函数挺有趣的,应为函数输入的参数是从没有过约束个数的,也正是是随机改换的。举个例子:

前日我们选取C语言来贯彻您的第一个实在的Windows程序。

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 }

windows.h 头文件介绍:

2.2.2       系统管理.. 9

 

编排Windows程序,首先要满含 windows.h 头文件。windows.h
还带有了任何一些Windows头文件,比如:

2.2.3       客户分界面.. 9

  这几个printf函数不仅可以够行使八个参数打印,还是能用来直接打字与印刷变量,可是MessageBox却不可能一直打字与印刷,这么些引起小编的直接考虑。小编先想到的是独立自己作主三个缓冲区,利用那几个缓冲区取打字与印刷字符数量。当然打字与印刷的函数得利用sprintf了

windef.h:基本类型定义

2.2.4       图像和多媒体.. 15

  

winbase.h:内核函数

2.2.5       网络.. 15

 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 }

wingdi.h:客户接口函数

2.2.6       其余职能.. 15

 

winuser.h: 图形设备接口函数

2.3       Windows API核心DLL. 16

  那些缓冲区的秘籍假若用在MessageBox函数里面,就可以落成打字与印刷变量的措施,比方以下代码:

那么些头文件定义了Windows的富有数据类型、函数原型、数据结商谈符号常量,也正是说,全数的Windows
API都在这里些头文件中扬言。

2.3.1       Kerne132.dll 16

#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;
}

在C语言中,程序都以“黑屏”的,称为调控台程序(Console
Application)。这套教程要讲的是带分界面包车型大巴Windows程序(Windows
Application),也可以称作GUI程序(GUI Application)。

2.3.2       User32.dll 16

 

调整台程序以 main() 为入口函数,Windows程序以 WinMain()
为入口函数,动态链接库以 DllMain()
为入口函数,差异的入口函数决定了分裂门类的顺序。

2.3.3       Gdi32.dll 16

  不过每回都写个缓冲区来存放在,而且一不下心忘记行使_snprintf函数,这就GG了,很可能发生缓冲区溢出的义务险。由此,这里运用printf原先函数设计的法则,我们也来统筹三个MessageBoxPrintf();函数,用那个函数来兑现格式化输出的功力,要得以达成这么些函数,首先得参谋printf();函数的兑现原理。

WinMain() 函数的原型为:

2.3.4       标准C函数.. 17

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;
}

int WINAPI WinMain(

2.3.5       其他Dll 17

 

HINSTANCE hInstance, // 当前窗口句柄

2.4       Unicode和多字节.. 17

  …表示的情趣是流传的参数是可变参数个数的,va_start(pArgs,
szFormat);表示指向szFormat之后的一个参数,这么些函数的不少东西笔者现在也尚未明白过来,之后再来补充,可是以往比葫芦画瓢那么些函数我们得以团结写个MessageBoxPrintf();函数,具体代码如下:

HINSTANCE hPrevInstance, //
前三个窗口句柄,Win32下为NULL(Win16留下的污染源,近来已弃用卡塔尔

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;
}

LPST宝马7系 lpCmdLine, // 命令行参数

2.4.2       Unicode与ASGII的转换.. 22

  相当于本人两全出来五个看似printf的小工具,因为微软的确未有布署MessageBox中进行格式化输出的函数。

int nCmdShow // 窗口展现形式

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

);

2.5       小结.. 23

先不要急于求成掌握那一个参数的意思,小编先给我们写一个简单易行的不带黑屏的、真正的Windows程序:

 

#include

 

int WINAPI WinMain(

 

HINSTANCE hInstance,

2.1    Windows数据类型

Windows API 使用了成都百货上千 Windows 自个儿定义的数据类型。读者只怕较为熟练 C
语言或 C++语言的数据类型。要熟知运用 Windows API 必要求熟稔 Windows
数据类型。这么些数据类型是Windows 特有的。在 SDK 的相关头文件中有定义。

在比比较多的Windows 数据类型中,最常用的有
DWO中华VD、HANDLE、LPTST帕杰罗、WO昂科拉D、BYTE、CHA途乐 等。在 Windows 系统中,DWORubiconD
用于表示无符号整型的数量,意为 double word,叁十位。

在日常景观下 BYTE 是 8 位的,而 WO福特ExplorerD 是 16 位,DWO奥迪Q5D 就是 32 位的。

Windows 系统的应用程序中还会有着三个故意的数据类型-HANDLE,平常 HANDLE
类型的变量用于唯风度翩翩标记叁个“对象”,如窗口、控件、文件等,Windows
平高雄设有比相当多如此的靶子,对象是前后相继操作的对象。HANDLE 也是叁个 三贰拾位的数据类型。

HINSTANCE hPrevInstance,

2.1.1    Windows数据类型示例

实例2-1施用了二种为主的 Windows 数据类型,演示 Windows
数据类型在先后中的使用方法。

  1. 实例2-1 常用Windows数据类型演示(DWO帕杰罗D/LPST帕杰罗/CHA悍马H2/INT卡塔尔国

本实例定义了多少个常用常量的 Windows 数据类型,富含 DWO奥迪Q5D,LPST奇骏 和
CHAGL450,并演示了哪些使用它们举办了复制、相当的大小等操作。

/* ************************************
*《精通 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 数据类型,分别是 LPSTEscort、CHA酷威、DWO冠道D 和
INT。

LPSTXC60 类型的数额是字符串,也正是字符指针,CHA中华V 是字符,DWOPRADOD 是 三十八人的无符号整数,INT 是 32 位有暗号整数。程序运营后会弹出 4
个对话框。那评释 dw马克斯>dwOne 是白手起家的。iMax<iOne 也是白手起家的。dw马克斯与 i马克斯 的数值是同等的,dwOne 与 iOne
的数值也是平等的。可是正如结实不一样,是因为两个的数据类型分裂等。

 

  1. 查阅Windows数据类型的概念

在 Visual Studio
中能够查阅数据类型的概念。在数据类型的项目名(比方“DWOHighlanderD”卡塔 尔(英语:State of Qatar)上单击右键,选取“转到定义”,如图
2-1 所示。

 图片 2

图2-1

能够从 SDK 的头文件中看见各档次的类型定义。

“INT”的概念如下:

 typedef int                 INT;

 

“DWOTiguanD”的定义如下:

 typedef unsigned long       DWORD;

 

“CHARAV4″的定义如下:

 typedef char CHAR;

 

    从当中可以窥见,这一个 Windows 数据类型都是从标准 C
的数据类型经过类型重定义而来。INT 数据类型是有号子整型,DWO途观D
数据类型是无符号整型。 那就表明了为啥在实例 2-1 中 INT 数据类型的变量
i马克斯 实际是“-1”,而 DWO中华VD 类型的变量 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、CHA陆风X8、WO揽胜D、SHORT、DOWRD、INT 等。

指针类型的授命情势通常是在其指向性的数据类型前加“LP”或“P”,比方照准DWORD的指针类型为“LPDWO传祺D”和“PDWO哈弗D”。

各个句柄类型的下令方式相仿都以在对象名前加“H”。Windows
系统中有超多指标,全体代表二个对象的数据类型都以句柄,每风流罗曼蒂克种对象都对应着生机勃勃种句柄类型,比方与位图(
BITMAP)对应的句柄类型为“HBITMAP”,与菜单(MENU)对应的句柄类型为“HMENU”,与窗口(WINDOW)对应的句柄类型为“HWND”。无符号类型常常是以“U”初始,比方“INT”是标记类型,“UINT”是无符号类型,“LONG”是符号类型“ULONG”是无符号类型等。

LPSTR lpCmdLine,

2.1.2    Windows 数据类型与正式C 数据类型的涉及

查阅 Windows 数据类型的定义能够看看,全数的 Windows 数据类型都以由 C
数据类型经过类型重定义拿到的。如 DWO奔驰G级D 实质上就是 unsigned long
数据类型,32 位的无符号整型:

typedef unsigned long       DWORD;

 

实际 VC 编写翻译器是八个安然无事的 C 编译器,别的并未过多的恢宏。Windows
数据类型也不是 VC 的内建项目,而从规范 C 类型重定义得到。

int nCmdShow

2.1.3    Windows 数据类型与Windows API

Windows API 函数的参数、返回值或一些重要的常量使用的数据类型都以 Windows
数据类型。如:

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

 

Message博克斯 函数的重临值是 int 型的,是行业内部 C
数据类型,然而富有的参数都采用了Windows 数据类型。如 HWND 是黄金年代种 W
indows 数据类型,用于表示窗口的句柄;LPCTST中华V 也是Windows
数据类型,表示字符串常量;UINT 也是 Windows 数据类型,为无符号整型。

){

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”表示针对数据结构的指针。

// 调用API 函数MessageBox

2.2    Windows API 的功能分类

Windows API
所能完结的效果包涵过多下面,在進展应用程序的花销时,开辟人士恐怕会动用到文件、进程、内部存款和储蓄器、权限、系统音信等系统的骨干服务和种类管理类的
API,也许会用到图形顾客分界面、控件等函数和指标,恐怕要求在分界面上制图图像管理多媒体消息等,还包蕴开展网络通讯支出等。

int nSelect = MessageBox(NULL, TEXT, TEXT(), MB_OKCANCEL);

2.2.1    系统核心服务

系统基本服务是 Windows API
最宗旨的剧情,是最常使用到的程序接口。系统基本服务API 包蕴以下多少个方面。

  1. 文件系统

对文件的基本操作包括文件的创始、张开、读写、关闭、删除,文件属性的安装与收获,目录操作,以至磁盘分卷的操作,还饱含镜像文件、加密文件系统等。

  1. 内部存款和储蓄器处理

主假设内在的分红、分享、释放等剧情,富含虚构内部存款和储蓄器管理、分页机制、堆管理等。

  1. 进度、线程和模块

席卷经过主程序(
exe)、模块、动态链接库(dll)的编辑撰写;线程的基本概念,线程成立、遍历、同步等操作;进度与权力;线程与纤程等剧情。

  1. 配备 I/O、驱动程控

归纳设备对象等基本概念。加载与卸载驱动程序,调节驱动程序,与驱动程序通讯等。

  1. 调度与错误处理

包涵如何支付调节和测量试验器,程序运维错误的管理,日志的记录、Windows
可试行文件的布局等。

  1. Windows 系统消息

包涵注册表的操作,如展开注册表,读取、写入键值,创制、删除键;还包罗系统宗旨消息的收获和装置,如系统目录、系统版本、Computer名等。

  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”,文件内容为系统目录。

if(nSelect == IDOK){

2.2.2    系统一管理理

系统管理是 Windows 系统中很关键的内容。Windows 系统提供了以下方面包车型客车 API
供应用程序开荒人士使用,包罗:管理调控台接口、程序安装、系统恢复生机、职分调解、Windows
运程管理。

MessageBox(NULL, TEXT(“你点击了“鲜明”按键”), TEXT, MB_OK);

2.2.3    客商分界面

顾客分界面开采是 Windows 应用程序开垦的主要内容。Windows
顾客分界面主要不外乎七个部分,Windows Shell 和 Windows 图形客商分界面。Windows
图形顾客分界面包罗窗口对象的有关内容,分界面能源,控件、顾客数据沟通(粘贴板等卡塔尔和客商输入的管理。

  1. 窗口化

席卷部分中坚数据概念和指标:窗口类、音信对列、窗口进程(音信管理函数卡塔尔国、窗口属性等。
首要不外乎的 API
有窗口类注册的函数、窗口创设与关闭函数、窗口属性纠正函数等。

  1. 资源

财富是 Windows
应用程序中超级重大的豆蔻梢头项内容,在可实行文件中,特地有用于存款和储蓄财富的节。
这里所说的财富是分界面能源,包蕴Logo、菜单、字符串、版本消息、对话框、动态光标、插入号(Carets)等。财富的处理涉及众多
API 函数。

  1. 客商输入管理

归纳对话框、键盘加快器(急忙键卡塔 尔(阿拉伯语:قطر‎、键盘输入、鼠标输入、原始数据输入等。那个概念是前后相继通过顾客分界面与顾客张开相互影响的基本概念。

  1. 数据调换

席卷 Atom
表(包含了多少字符串和标记符卡塔尔国、粘贴板、数据复制、动态数据交接等基本概念,是客商和应用程序通过客商分界面实行数据交换的要害载体。

  1. Windows 图形分界面通用控件

Windows 系统提供了不菲于 30 种的控件供应用程序接收,在那之中最常用的两种包蕴Edit控件(文本框卡塔尔国、Button 控件(开关卡塔尔国、ListView 控件(列表卡塔 尔(阿拉伯语:قطر‎、ToolTip
控件(提示框卡塔 尔(阿拉伯语:قطر‎、ComboBox 控件(下拉选择框卡塔尔国、Tree-View
控件(树卡塔 尔(英语:State of Qatar)、Rich-Edit 控件(多功效文本框卡塔 尔(阿拉伯语:قطر‎、Tab 控件(分页卡塔 尔(阿拉伯语:قطر‎、Process
控件(进程条卡塔 尔(阿拉伯语:قطر‎等。

  1. Windows Shell

Windows 桌面浏览器(explorer.exe)的效率强盛,Windows Shell
应用程序能够采纳WindowsShell
桌面包车型地铁程序接口达到管理系列、定制Logo和暗许程序、增添桌面功效等目标。

  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,
      LPSTRAV4 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, // 小LogoMAKEINTRESOURCE(5),
      IMAGE_ICON,
      GetSystemMetrics(SM_CXSMICON),
      GetSystemMetrics(SM_CYSMICON),
      LR_DEFAULTCOLO奇骏);
      // 注册窗口类
      if(!RegisterClassEx(&wcx))
      {
      return 1;
      }
      // 创立窗口
      hwnd = CreateWindow(
      “MainWClass”, // 窗口名
      “CH 2-3”, // 窗口标题WS_OVE奇骏L应用程式EDWINDOW, // 窗口样式
      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:02>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

 

运作效果:

 图片 3

}else{

2.2.4    图像和多媒体

Windows 的图像引擎和多媒体编制程序有多样接口,包含最基本的
GDI、GDI+,以致越来越尖端的OpenGL、DirectX 等图像引擎编制程序接口。DirectX 和
OpenGL
在玩乐开荒、动漫制作等地点选择相比遍布,使用它们举办应用程序开拓要求特意的
SDK。本书只批注 GDI,对日常的应用程序开拓,已经够用使用。

GDI
的基本概念包罗图像(Image)、位图(Bitmaps卡塔尔、笔(Pen)、画刷(Brush)、文本和字体(
Text and
Fonts)、线(Line)、区域(Regions)、形状(Shapes)等。当中央的效用是对展现设备开展调节、获取和校正相关配置,在微型机荧屏上出示顾客所急需出示的内容。

MessageBox(NULL, TEXT(“你点击了“打消”按键”), TEXT, MB_OK);

2.2.5    网络

客商选拔 Windows API 能够付出基于各类网络左券的应用程序,比如 TCPUDP
Socket、HTTP、DHCP、RPC、QOS、蓝牙5.0,以至写真、点对点文件传输、即插即用设备管理等。
还能举办互连网管理,包罗网络的主干消息,使用 IP helper
获取互联网安插和互连网音讯、举办网络监视等。
同有的时候间微软还提供了扩充网络安全编制程序的片段接口,首假若防火墙 Windows、防火墙
API,以致一些 Windows 自带的网络应用程序的接口,包括 IE、Outlook 等。

}

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

return 0;

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

}

2.3.1    Kerne132.dll

Keme132.dll 富含了系统核心服务中最宗旨的 API
函数,如文件系统、进度与线程、内部存款和储蓄器管理等。 Windows XPSP2
系统中,Keme132.d11 有 9五十个导出函数,举个例子,CreateFileA、CreateProcessA、OpenThread、SetFileTime
等。本书将要持续章节中通超过实际例介绍这一个 API的应用。

运营结果:

2.3.2    User32.dll

User32.dll 是 Windows
图形客户分界面包车型客车显要支撑。一些根本的图形客商界面函数由User32.dll
函数导出。Windows XP SP2 系统中,User32.dll 有 7三11个导出函数,举个例子CreateWindowExW、RegisterClassA 等。

图片 4

2.3.3    Gdi32.dll

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

点击“明确”或“撤销”按键,又会弹出四个新的提示框。我们能够亲自运转一下,会有实在的心得。

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等。

原本未有main()函数,未有#include 的C语言程序也是可以运作的!

2.3.5    其他Dll

本来,Windows 系统中的 DLL 文件远远不唯有那多少个,Windows
系统提供了特别丰裕而且效能强大的 API,上文已经介绍了 Windows API
所重要依附的几个 DLL,别的的 DLL
库文件由于过火庞杂,就不后生可畏一介绍,将要三番七次的章节中具备关联。读者只必要精晓调用
Windows API 的基本原理就能够了。

MessageBox()
函数是无数API中的叁个,用于弹出一个钦定风格的对话框,其原型为:

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,
      LPST库罗德 lpCmdLine,
      int nCmdShow
      )
      {
      //定义 LPWSTWrangler 类型的宽字符串
      LPWST奥迪Q7 szUnicode = L”This is a Unicode String;”;
      //定义 LPSTCRUISER 类型的窄字符串
      LPSTMurano szMutliByte = “This is not a Unicode String;”;
      //定义 LPTST汉兰达 类型的自适就字符串
      LPTST科雷傲 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

 

 图片 5

“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

 

 图片 6

“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

 

 图片 7

和多字节ASCII

d7 d6 b7 fb b1 e0 c2 eb

 

 图片 8

读者可以解析设置使用 Unicode
字符集后编译完结的可推行文件与安装为多字节字符集后编写翻译拿到的可试行文件有哪些不一样。

 

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

设置的措施是在Visual
Studio工程属性中筛选“配置属性”→“常规”→“字符集”选项中举办抉择。

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

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
中,Message博克斯 函数扬言所在的头文件中发掘如下概念(以下代码来自于
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
编码或都多字节编码文件,不影响程序的正规机能。

但如若在编写程序时,使用的字符集与代码中利用的函数不一样样、定义的字符串变量不包容,将会挑起编写翻译错误只怕运路程序展现乱码,甚至大概引起程序运维错误,那或多或少内需引起注意。

WINAPI 为宏定义

2.4.2    Unicode与ASGII的转换

Windows 特地提供了若干个 API
来兑现对字符编码的改变事业。ideCharToMultiByte、MultiByteToWideChar、UnicodeToBytes
函数能够成功那些干活儿。

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

#define WINAPI
__stdcall,表示函数调用情势,一时能够不理会,不影响代码编写,只需要精通MessageBox()再次回到值为
int,表示按下的按键。

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

各样技术员都有友好的标准化编制程序习贯。代码的正规化不是本书的要害,所以这里只交付一些微软平时应用代码标准,MSDN
的现身说法中,SDK 的头文件和例子中大约都是行使的这种艺术。

变量名:常常使用所谓的“匈牙利(Hungary卡塔 尔(英语:State of Qatar)命名法”,变量名由“类型缩写(小写卡塔尔国”+“变量描述(单词首字母大写卡塔 尔(英语:State of Qatar)”构成,如字符串类型的变量能够命名叫szFileName,DWO奔驰M级D 类型的数量足以命名字为 dwFileSize,指针类型能够命名称叫lpBuffer,句柄类型的变量能够命名字为 hLogFile 等。

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

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

常量:同类型名的命名格局。

宏:多与品种名命名方式相仿,有的也与函数名命名格局相似。
大括号与代码段:日常大括号独立占风流罗曼蒂克行,大括号内的代码段缩进。如若代码段仅意气风发行(如
if-else 后的言语卡塔尔国,也建议利用大括号。

在调用或概念函数时,假诺函数太长,可以分行写,将各类参数写生龙活虎行。平日多于
3个参数的函数须求分行写,以精彩和有助于阅读为尺度。

在本书的亲自过问中,都将尽大概采纳那个规范化的法子。

 

参数表达

2.5    小结

PDF下载:

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

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

 

hWnd:该音讯框的父窗口句柄,借使此参数为NULL,则该消息框未有具备父窗口。大家不用急于精通那个参数,后续会详细讲明。

lpText:音讯框的内容。LPCTST福睿斯 是自定义数据类型,等价于 const char *。

lpCaption:新闻框的标题。

uType:对话框的按键样式和Logo。

uType 支持的按键样式:

图片 9

这几个按键都以宏定义

#define MB_OK 0x00000000L

#define MB_OKCANCEL 0x00000001L

#define MB_ABORTRETRYIGNORE 0x00000002L

#define MB_YESNOCANCEL 0x00000003L

#define MB_YESNO 0x00000004L

#define MB_RETRYCANCEL 0x00000005L

您也得以品尝用数字来表示按键,举个例子:

MessageBox(NULL, TEXT(“你好,接待源世界你!”), TEXT, 1);

也会生成与地点同样的对话框。

除此而外按键,uType 还扶助Logo(Logo对顾客有提醒成效卡塔尔国:

图片 10

这一个Logo也都以宏定义:

#define MB_ICONHAND 0x00000010L

#define MB_ICONQUESTION 0x00000020L

#define MB_ICONEXCLAMATION 0x00000030L

#define MB_ICONASTERISK 0x00000040L

大器晚成旦指望同一时候定义按键和Logo的体裁,能够应用或运算|,举个例子:

MessageBox(

NULL,

TEXT,

TEXT,

MB_OKCANCEL | MB_ICONINFORMATION

);

把上面包车型地铁MessageBox换到那一个就ok了。运行结果

与地点的对话框比较,多出了三个Logo,同不常间仍然是能够听见提醒音。是或不是多了叁个提示标记在文字的前头啊。

再看来一下MessageBox() 的重返值。

MessageBox()
重返被按下的按键,以数字代表,那么些数字都被定义成了宏,如下所示:

图片 11

相应的宏定义为:

#define IDOK 1

#define IDCANCEL 2

#define IDABORT 3

#define IDRETRY 4

#define IDIGNORE 5

#define IDYES 6

#define IDNO 7

图片 12

作者推荐二个学C语言/C++的求学裙【 七三零,风姿罗曼蒂克三零,二二生龙活虎】,无论你是大牌还是小白,是想转行依然想入行都能够来理解一同发展一同学习!裙内有开辟工具,相当多干货和技巧资料分享!

总结:

对此刚刚学完C语言的,学windows编程的,那几个都以满满的干货,应当要记住喔。从您学windows编制程序发轫,你就曾经告辞了丧权辱国的windows
do分界面,只要一步一步走,写二个出色的window程序无庸赘述。这一个都以随后学习总得调控的,先收藏吧!

这些是C/C++能做的

服务器开荒程序猿、智能AI、云计算技术员、音信安全、大数据
、数据平台、嵌入式程序员、流媒体服务器、数据控解、图像管理、音频摄像开荒程序员、游戏服务器、分布式系统、游戏协理等

图片 13图片 14图片 15

发表评论

电子邮件地址不会被公开。 必填项已用*标注