wndows程序设计之书籍知识与代码摘录-封装一个类似printf的messagebox

//-----------------------------------------
//本程序展示了如何实现MessageBoxPrintf函数
//本函数能像printf那样格式化输出
//摘录自:《windows程序设计第五版》
//-----------------------------------------
#include<windows.h>
#include<tchar.h>
#include<stdio.h>

int CDECL MessageBoxPrintf(TCHAR * szCaption, TCHAR * szFormat, ...)
{
    TCHAR szBuffer[1024];
    
    va_list pArgList;
    
    va_start (pArgList, szFormat);
    
    _vsntprintf_s(szBuffer,sizeof(szBuffer)/sizeof(TCHAR), sizeof(szBuffer) / sizeof(TCHAR),szFormat, pArgList);
    //---------------------------------------------------------------------------------------------------------------------------------
    //原文使用_vsntprintf(szBuffer, sizeof(szBuffer) / sizeof(TCHAR),szFormat, pArgList); vs认为此函数具有安全性问题 因此我替换成上边的函数
    //---------------------------------------------------------------------------------------------------------------------------------
    
    va_end(pArgList);
    return MessageBox(NULL,szBuffer,szCaption,0);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    int cxScreen;
    int cyScreen;
    cxScreen = GetSystemMetrics(SM_CXSCREEN);
    cyScreen = GetSystemMetrics(SM_CYSCREEN);
    MessageBoxPrintf(TEXT("SCREEN SIZE"),TEXT("您的视屏显示器:\nWIDE:%i\nHIGH: %i"),cxScreen,cyScreen);
    
    return 0;
}

这个函数使用了可变参数 这样就出现了一些陌生的东西,解释如下

CDECL

__cdecl __fastcall与__stdcall,三者都是调用约定(Calling convention),它决定以下内容:1)函数参数的压栈顺序,2)由调用者还是被调用者把参数弹出栈,3)以及产生函数修饰名的方法。
1、__stdcall调用约定:函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈。
2、_cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。注意:对于可变参数的成员函数,始终使用__cdecl的转换方式。
3、__fastcall调用约定:它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈)。

 va_start va_end等

函数名称,读取可变参数的过程其实就是在堆栈中,使用指针,遍历堆栈段中的参数列表,从低地址到高地址一个一个地把参数内容读出来的过程

#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //第一个可选参数地址
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数地址
#define va_end(ap) ( ap = (va_list)0 ) // 将指针置为无效

 

在学习windows程序设计时此函数可以给c/c++程序员一份熟悉感。。。。。。。。。。。

 

posted @ 2015-09-19 15:04 Smalldy 阅读(...) 评论(...) 编辑 收藏