云顶娱乐平台 16

【云顶娱乐平台】Windows程序设计:格式化对话框的设计

  刚开始学习Windows程序设计,磕磕碰碰,先做个小笔记缓缓神经,主要是将MessageBox这个Windows
API函数的。

#define MB_OK 0x00000000L

2.2    Windows API 的功能分类

Windows API
所能实现的功能包括很多方面,在进行应用程序的开发时,开发人员可能会使用到文件、进程、内存、权限、系统信息等系统的基本服务和系统管理类的
API,可能会用到图形用户界面、控件等函数和对象,可能需要在界面上绘制图像处理多媒体信息等,还包括进行网络通信开发等。

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

 

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

2.4.3    对Windows程序设计规范的建议

每个程序员都有自己的规范化编程习惯。代码的规范不是本书的重点,所以这里只给出一些微软经常使用代码规范,MSDN
的示例中,SDK 的头文件和例子中几乎都是使用的这种方法。

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

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

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

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

宏:多与类型名命名方式相同,有的也与函数名命名方式相同。
大括号与代码段:一般大括号独立占一行,大括号内的代码段缩进。如果代码段仅一行(如
if-else 后的语句),也建议使用大括号。

在调用或定义函数时,如果函数太长,可以分行写,将每个参数写一行。一般多于
3个参数的函数需要分行写,以美观和方便阅读为原则。

在本书的示例中,都将尽量使用这些规范化的方式。

 

}

  但是每次都写个缓冲区来存放,并且一不下心忘记使用_snprintf函数,那就GG了,很可能发生缓冲区溢出的危险。因此,这里利用printf原先函数设计的原理,我们也来设计一个MessageBoxPrintf();函数,用这个函数来实现格式化输出的作用,要实现这个函数,首先得参照printf();函数的实现原理。

#define MB_ICONHAND 0x00000010L

2.1.4       Windows 中的数据结构.. 6

INT param = 0;//参数个数

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

HINSTANCE hInstance,

2.2       Windows API 的功能分类.. 7

strnum += 1;

  就像C语言中经常使用printf函数,这个函数挺有趣的,应为函数输入的参数是没有限定个数的,相当于是随机改变的。例如:

HINSTANCE hPrevInstance, //
前一个窗口句柄,Win32下为NULL(Win16留下的废物,目前已弃用)

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
位的数据类型。

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

  相当于自己设计出来一个类似printf的小工具,因为微软确实没有设计MessageBox中进行格式化输出的函数。

windef.h:基本类型定义

2.3.1    Kerne132.dll

Keme132.dll 包括了系统基本服务中最基本的 API
函数,如文件系统、进程与线程、内存管理等。 Windows XPSP2
系统中,Keme132.d11 有 949
个导出函数,例如,CreateFileA、CreateProcessA、OpenThread、SetFileTime
等。本书将在后续章节中通过实例介绍这些 API的使用。

}

  这个printf函数不仅可以使用多个参数打印,还可以用来直接打印变量,但是MessageBox却不能直接打印,这个引起我的直接思考。我先想到的是建立一个缓冲区,利用这个缓冲区取打印字符数据。当然打印的函数得使用sprintf了

);

2.2.4    图像和多媒体

Windows 的图像引擎和多媒体编程有多种接口,包括最基本的
GDI、GDI+,以及更高级的OpenGL、DirectX 等图像引擎编程接口。DirectX 和
OpenGL
在游戏开发、动画制作等方面应用比较广泛,使用它们进行应用程序开发需要专门的
SDK。本书只讲解 GDI,对一般的应用程序开发,已经足够使用。

GDI
的基本概念包括图像(Image)、位图(Bitmaps)、笔(Pen)、画刷(Brush)、文本和字体(
Text and
Fonts)、线(Line)、区域(Regions)、形状(Shapes)等。其基本的功能是对显示设备进行控制、获取和修改相关配置,在计算机屏幕上显示用户所需要显示的内容。

temp = ebpnum + 4 * param + 8;

 

编写Windows程序,首先要包含 windows.h 头文件。windows.h
还包含了其他一些Windows头文件,例如:

2.3.3    Gdi32.dll

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

mov eax, straddress[ecx *云顶娱乐平台, 4]

 

也会生成与上面相同的对话框。

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
编码或都多字节编码文件,不影响程序的正常功能。

但如果在编写程序时,使用的字符集与代码中使用的函数不一致、定义的字符串变量不兼容,将会引起编译错误或者运行程序显示乱码,甚至可能引起程序运行错误,这一点需要引起注意。

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

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

#define WINAPI
__stdcall,表示函数调用方式,暂时可以不理会,不影响代码编写,只需要知道MessageBox()返回值为
int,表示按下的按钮。

【云顶娱乐平台】Windows程序设计:格式化对话框的设计。2.5       小结.. 23

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

// 自己做一个格式化的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;
}

云顶娱乐平台 1

2.2.2    系统管理

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

VOID MSKMessageBox(PTSTR string, …){

  MessageBoxW(NULL, L””, L””, MB_OK);  
                    // 这个L用来表示Unicode,不可以省略

与上面的对话框相比,多出了一个图标,同时还能听到提示音。是不是多了一个提示符号在文字的前面啊。

2.4.1       W版本和A版本的API 21

mov bx, word ptr[eax]

 

今天我们运用C语言来实现你的第一个真正的Windows程序。

2.2.1       系统基本服务.. 7

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

  MessageBox函数是许多人刚开始学习Windows程序设计或者是Windows
API遇到的第一个内置函数,这个函数使用的方式是:

C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入进行运算处理得到输出控制)。

2.2.3       用户界面.. 9

mov eax, straddress

  其实之所以有这两个是因为微软需要满足Windows
98之后对汉字等其他语言编码的需求,这种需求通过Unicode实现,但是微软本意不是要我们使用Unicode来编程,而是通过使用“通用”形式,也就是MessageBox();函数,实现不同的编码主要还是通过IDE集成开发环境下改变不同的编码形式。回到MessageBox();,今天比较头疼的是,怎么在MessageBox();中实现变量的打印呢?

#define IDIGNORE 5

 

add eax, 2

 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 }

lpCaption:消息框的标题。

2.1.3       Windows 数据类型与Windows API 5

}

  这个缓冲区的方法如果用在MessageBox函数里面,就可以实现打印变量的方式,比如以下代码:

uType:对话框的按钮样式和图标。

2.1.2    Windows 数据类型与标准C 数据类型的关系

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

typedef unsigned long       DWORD;

 

实际上 VC 编译器是一个完整的 C 编译器,此外并没有过多的扩展。Windows
数据类型也不是 VC 的内建类型,而从标准 C 类型重定义得到。

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

 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 }

#define MB_RETRYCANCEL 0x00000005L

 

UINT i;

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

点击“确定”或“取消”按钮,又会弹出一个新的提示框。大家可以亲自运行一下,会有真实的体验。

2.3.1       Kerne132.dll 16

test bx, bx

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

MessageBox(

2.3       Windows API核心DLL. 16

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

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

#include

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: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

 

运行效果:

 云顶娱乐平台 2

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

  

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

2.2.2       系统管理.. 9

/* 函数参数: 第一个是字符串,和printf一样,不定参数个数

  …表示的意思是传入的参数是可变参数个数的,va_start(pArgs,
szFormat);表示指向szFormat之后的一个参数,这个函数的许多东西我现在也还没理解过来,之后再来补充,不过现在仿照这个函数我们可以自己写个MessageBoxPrintf();函数,具体代码如下:

#define IDABORT 3

2.1.1       Windows数据类型示例.. 1

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

HINSTANCE hInstance, // 当前窗口句柄

2.3.5       其他Dll 17

strnum += testnum;

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

2.5    小结

PDF下载:

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

范文庆、周彬彬、安靖编著

 

云顶娱乐平台 3

对应的宏定义为:

2.2.4       图像和多媒体.. 15

源码

){

2.2.5       网络.. 15

}

int nCmdShow // 窗口显示方式

2.1       Windows数据类型.. 1

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

这些是C/C++能做的

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

strnum += lstrlen(number);

C和C++的区别:

2.4.2    Unicode与ASGII的转换

Windows 专门提供了若干个 API
来实现对字符编码的转换工作。ideCharToMultiByte、MultiByteToWideChar、UnicodeToBytes
函数可以完成这些工作。

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

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

小编推荐一个学C语言/C++的学习裙【 七三零,一三零,二二一
】,无论你是大牛还是小白,是想转行还是想入行都可以来了解一起进步一起学习!裙内有开发工具,很多干货和技术资料分享!

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 数据类型,为无符号整型。

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

服务器开发工程师、人工智能、云计算工程师、信息安全、大数据
、数据平台、嵌入式工程师、流媒体服务器、数据控解、图像处理、音频视频开发工程师、游戏服务器、分布式系统、游戏辅助等

2.3.2       User32.dll 16

}

#define MB_ICONASTERISK 0x00000040L

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

 

 云顶娱乐平台 4

“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

 

 云顶娱乐平台 5

“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

 

 云顶娱乐平台 6

和多字节ASCII

d7 d6 b7 fb b1 e0 c2 eb

 

 云顶娱乐平台 7

读者可以分析设置使用 Unicode
字符集后编译完成的可执行文件与设置为多字节字符集后编译得到的可执行文件有什么不同。

 

  1. 在工程配置中选择编码方式

设置的方法是在Visual
Studio工程属性中选择“配置属性”→“常规”→“字符集”选项中进行选择。

int test = 0;

#define IDCANCEL 2

2.2.6       其他功能.. 15

__asm{

LPSTR lpCmdLine, // 命令行参数

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

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

云顶娱乐平台 8

 

}

对于刚刚学完C语言的,学windows编程的,这些都是满满的干货,一定要记住喔。从你学windows编程开始,你就已经告别了难看的windows
do界面,只要一步一步走,写一个漂亮的window程序不在话下。这些都是以后学习必须掌握的,先收藏吧!

2.3.2    User32.dll

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

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

云顶娱乐平台 9云顶娱乐平台 10云顶娱乐平台 11

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

TCHAR msg[2001] = {0};

参数说明

2.2.5    网络

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

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

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

2.3.5    其他Dll

当然,Windows 系统中的 DLL 文件远远不止这几个,Windows
系统提供了非常丰富而且功能强大的 API,上文已经介绍了 Windows API
所主要依赖的几个 DLL,其他的 DLL
库文件由于过于庞杂,就不一一介绍,将在后续的章节中有所涉及。读者只需要了解调用
Windows API 的基本原理就可以了。

add testnum, 1

这些图标也都是宏定义:

2.3.4       标准C函数.. 17

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

#define IDNO 7

2.1.2       Windows 数据类型与标准C 数据类型的关系.. 5

} else{

lpText:消息框的内容。LPCTSTR 是自定义数据类型,等价于 const char *。

目录

jne sss2

}

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

dec testnum

// 调用API 函数MessageBox

2.4       Unicode和多字节.. 17

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

#define IDOK 1

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

sss:

MessageBox()
返回被按下的按钮,以数字表示,这些数字都被定义成了宏,如下所示:

2.4.2       Unicode与ASGII的转换.. 22

xor ebx, ebx

#define IDRETRY 4

2.3.3       Gdi32.dll 16

在编写窗口程序的时候,经常需要使用messagebox函数,不管是调试输入也好,查看变量也罢。这时如果是全字符串的还好,但是如果需要显示数值的内容时,用这个函数就比较麻烦了。需要先使用wsprintf函数执行一遍,然后在使用messagebox函数。远没有在命令行下的printf方便,如果是需要大量弹窗时就更麻烦了。所以决定将这两个函数封装起来,这样messagebox就可以和printf函数一样方便使用了。最终经过两天时间,完成了这个Unicode编码的函数,期间碰到了许多问题,通过一次次单步调试,查看汇编代码最终解决掉了所有问题,函数能正常使用了。

LPSTR lpCmdLine,

2.4.3       对Windows程序设计规范的建议.. 22

i++;

C与C++的最大区别:在于它们的用于解决问题的思想方法不一样。之所以说C++比C更先进,是因为“
设计这个概念已经被融入到C++之中
”,而就语言本身而言,在C中更多的是算法的概念。那么是不是C就不重要了,错!算法是程序设计的基础,好的设计如果没有好的算法,一样不行。而且,“C加上好的设计”也能写出非常好的东西。

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
个对话框。这说明 dwMax>dwOne 是成立的。iMax<iOne 也是成立的。dwMax
与 iMax 的数值是一样的,dwOne 与 iOne
的数值也是一样的。但是比较结果不同,是因为二者的数据类型不一样。

 

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

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

 云顶娱乐平台 12

图2-1

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

“INT”的定义如下:

 typedef int                 INT;

 

“DWORD”的定义如下:

 typedef unsigned long       DWORD;

 

“CHAR”的定义如下:

 typedef char CHAR;

 

    从中可以发现,这些 Windows 数据类型都是从标准 C
的数据类型经过类型重定义而来。INT 数据类型是有符号整型,DWORD
数据类型是无符号整型。 这就说明了为什么在实例 2-1 中 INT 数据类型的变量
iMax 实际是“-1”,而 DWORD 类型的变量 dwMax
实际是“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”是无符号类型等。

param++;

除了按钮,uType 还支持图标(图标对用户有提醒作用):

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

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

test = lstrlen(number);

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

sss2 :

int WINAPI WinMain(

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

TEXT,

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

MB_OKCANCEL | MB_ICONINFORMATION

mov dword ptr[ebpnum], ebp

这些按钮都是宏定义

/* 使用说明: 弹窗的内容可以使用任意多个参数,类型暂时只支持 %d 和 %s

这些头文件定义了Windows的所有数据类型、函数原型、数据结构和符号常量,也就是说,所有的Windows
API都在这些头文件中声明。

int testnum = 0;

#define MB_ICONEXCLAMATION 0x00000030L

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

把上面的MessageBox换成这个就ok了。运行结果

add num,1//计数+1

上次我们说了什么是windows编程?了解到Windows API
编程、Windows编程、Windows SDK 编程是一个概念。

xor ebx,ebx//清零寄存器

WINAPI 为宏定义

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

C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程控制。
所以C与C++的最大区别在于它们的用于解决问题的思想方法不一样。之所以说C++比C更先进,是因为“
设计这个概念已经被融入到C++之中 ”。

UINT num = 0;

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

TCHAR str[2001] = {0};//最多2000的字节内容,如果超过2000就返回错误

MessageBox(NULL, TEXT(“你好,欢迎源世界您!”), TEXT, 1);

//int 3

如果希望同时定义按钮和图标的样式,可以使用或运算|,例如:

} else{

#define MB_ABORTRETRYIGNORE 0x00000002L

DWORD temp;//用来获取数字的值的

WinMain() 函数的原型为:

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

你也可以尝试用数字来表示按钮,例如:

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

#define MB_YESNO 0x00000004L

arrnum++;

#define MB_ICONQUESTION 0x00000020L

}

#define MB_OKCANCEL 0x00000001L

mov ecx, arrnum

wingdi.h:用户接口函数

i++;

hWnd:该消息框的父窗口句柄,如果此参数为NULL,则该消息框没有拥有父窗口。大家不用急于理解这个参数,后续会详细讲解。

str[strnum] = string[i];

云顶娱乐平台 13

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

);

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

运行结果:

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

if(nSelect == IDOK){

#define MB_YESNOCANCEL 0x00000003L

云顶娱乐平台 14

总结:

原来没有main()函数,没有#include 的C语言程序也是可以运行的!

return 0;

int WINAPI WinMain(

}

NULL,

uType 支持的按钮样式:

windows.h 头文件介绍:

HINSTANCE hPrevInstance,

先不要急于理解这些参数的含义,我先给大家写一个简单的不带黑屏的、真正的Windows程序:

#define IDYES 6

在C语言中,程序都是“黑屏”的,称为控制台程序(Console
Application)。这套教程要讲的是带界面的Windows程序(Windows
Application),也称为GUI程序(GUI Application)。

云顶娱乐平台 15

int nCmdShow

控制台程序以 main() 为入口函数,Windows程序以 WinMain()
为入口函数,动态链接库以 DllMain()
为入口函数,不同的入口函数决定了不同类型的程序。

TEXT,

云顶娱乐平台 16

MessageBox(NULL, TEXT(“你点击了“确定”按钮”), TEXT, MB_OK);

winbase.h:内核函数

}else{