Windows 编程基础(三)

本文介绍了Windows编程基础,包括WinMain主函数,使用GetSystemMetrics获取系统尺寸,cdecl调用约定的原理,以及如何处理可变参数列表。重点讲解了如何实现类似printf功能的MessageBoxPrintf函数,利用va_list、va_start、va_arg和va_end等宏进行参数的获取和处理。
摘要由CSDN通过智能技术生成

实现MessageBoxPrintf函数,该函数有许多参数并能像 printf 那样编排它们的格式。

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

int CDECL MessageBoxPrintf(TCHAR * szCaption, TCHAR * szFormat, ...)
{
	TCHAR szBuffer[1024] = { 0 };
	va_list pArgList;

	va_start(pArgList, szFormat);

	_vsntprintf(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), szFormat, pArgList);

	va_end(pArgList);
	return MessageBox(NULL, szBuffer, szCaption, 0);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	PSTR szCmdLine, int iCmdShow)
{
	int cxScreen = 0, cyScreen = 0;
	cxScreen = GetSystemMetrics(SM_CXSCREEN);
	cyScreen = GetSystemMetrics(SM_CXSCREEN);

	MessageBoxPrintf(TEXT("ScrnSize"),
		TEXT("The screen is %i pixels wide by %i pixels high."), cxScreen, cyScreen);
	return 0;
}

1)WinMain 主函数

2)GetSystemMetrics函数只有一个参数,称之为【索引】,这个索引有75个标识符,通过设置不同的标识符就可以获取系统分辨率、窗体显示区域的宽度和高度、滚动条的宽度和高度。
用GetSystemMetrics获取屏幕的宽度和高度
int x, y;
x = GetSystemMetrics(SM_CXSCREEN); //屏幕宽度
y = GetSystemMetrics(SM_CYSCREEN); //屏幕高度

3)cdecl 调用约定
函数实参在线程栈上按照从右至左的顺序依次压栈。
函数结果保存在寄存器EAX/AX/AL中
浮点型结果存放在寄存器ST0中
编译后的函数名前缀以一个下划线字符
调用者负责从线程栈中弹出实参(即清栈)
8比特或者16比特长的整形实参提升为32比特长。
受到函数调用影响的寄存器(volatile registers):EAX, ECX, EDX, ST0 - ST7, ES, GS
不受函数调用影响的寄存器: EBX, EBP, ESP, EDI, ESI, CS, DS
RET指令从函数被调用者返回到调用者(实质上是读取寄存器EBP所指的线程栈之处保存的函数返回地址并加载到IP寄存器)

4)当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表

5)va_list 是一个字符指针,可以理解为指向当前参数的一个指针,取参必须通过这个指针进行。
<Step 1> 在调用参数表之前,定义一个 va_list 类型的变量,(假设va_list 类型变量被定义为ap);
<Step 2> 然后应该对ap 进行初始化,让它指向可变参数表里面的第一个参数,这是通过 va_start 来实现的,第一个参数是 ap 本身,第二个参数是在变参表前面紧挨着的一个变量,即“…”之前的那个参数;
<Step 3> 然后是获取参数,调用va_arg,它的第一个参数是ap,第二个参数是要获取的参数的指定类型,然后返回这个指定类型的值,并且把 ap 的位置指向变参表的下一个变量位置;
<Step 4> 获取所有的参数之后,我们有必要将这个 ap 指针关掉,以免发生危险,方法是调用 va_end,他是输入的参数 ap 置为 NULL,应该养成获取完参数表之后关闭指针的习惯。说白了,就是让我们的程序具有健壮性。通常va_start和va_end是成对出现。
va_arg 获取可变参数的当前参数,返回指定类型并将指针指向下一参数。

6)_vsntprintf 与sprintf类似
不通:可以读取函数省略的参数,设置到第一个参数指定的空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值