#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int CDECL MessageBoxPrintf (TCHAR * szCaption, TCHAR * szFormat, ...)
{
TCHAR szBuffer [1024] ;
va_list pArgList ;
// The va_start macro (defined in STDARG.H) is usually equivalent to:
// pArgList = (char *) &szFormat + sizeof (szFormat) ;
va_start (pArgList, szFormat) ;
// The last argument to wvsprintf points to the arguments
_vsntprintf ( szBuffer, sizeof (szBuffer) / sizeof (TCHAR),
szFormat, pArgList) ;
// The va_end macro just zeroes out pArgList for no good reason
va_end (pArgList) ;
return MessageBox (NULL, szBuffer, szCaption, 0) ;
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
int cxScreen, cyScreen ;
cxScreen = GetSystemMetrics (SM_CXSCREEN) ;
cyScreen = GetSystemMetrics (SM_CYSCREEN) ;
MessageBoxPrintf ( TEXT ("ScrnSize"),
TEXT ("The screen is %i pixels wide by %i pixels high."),
cxScreen, cyScreen) ;
return 0 ;
}
是windows程序设计第二章的例子程序
remark:
vsprintf是sprintf的一个变形,它只有三个参数。vsprintf用于执行有多个参数的自订函数,类似printf格式。vsprintf的前两个参数与sprintf相同:一个用于保存结果的字符缓冲区和一个格式字符串。第三个参数是指向格式化参数数组的指针。实际上,该指针指向在堆栈中供函数呼叫的变量。va_list、va_start和va_end宏(在STDARG.H中定义)帮助我们处理堆栈指针。本章最后的SCRNSIZE程序展示了使用这些宏的方法。使用vsprintf函数,sprintf函数可以这样编写:
int sprintf (char * szBuffer, const char * szFormat, ...)
{
int iReturn ;
va_list pArgs ;
va_start (pArgs, szFormat) ;
iReturn = vsprintf (szBuffer, szFormat, pArgs) ;
va_end (pArgs) ;
return iReturn ;
}
va_start宏将pArg设置为指向一个堆栈变量,该变量地址在堆栈参数szFormat的上面。
由于许多Windows早期程序使用了sprintf和vsprintf,最终导致Microsoft向Windows API中增添了两个相似的函数。Windows的wsprintf和wvsprintf函数在功能上与sprintf和vsprintf相同,但它们不能处理浮点格式。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)