//-----------------------------------------
//本程序展示了如何实现MessageBoxPrintf函数
//本函数能像printf那样格式化输出
//摘录自:《windows程序设计第五版》
//-----------------------------------------
#include<windows.h>
#include<tchar.h>
#include<stdio.h> int CDECL MessageBoxPrintf(TCHAR * szCaption, TCHAR * szFormat, ...)
{
TCHAR szBuffer[]; 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,);
}
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 ;
}

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

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++程序员一份熟悉感。。。。。。。。。。。

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

  1. wndows程序设计之书籍知识与代码摘录-获取视屏显示器像素等参数GetsystemMetrics

    以下的代码段用于获取视屏显示器的高度宽度,以像素为单位. int sxScreen, cyScreen; cxScreen = GetSystemMetrics (SM_CXSCREEN); cySc ...

  2. 1)Linux程序设计入门--基础知识

    )Linux程序设计入门--基础知识 Linux下C语言编程基础知识 前言: 这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将 会学到以下内容: 源程序编译 Makef ...

  3. 、web前端的这么知识应该是怎样的一个知识体系架构?

    .web前端的这么知识应该是怎样的一个知识体系架构?之前我以为可以以W3C为纲要,把W3C的东西学会了就够了.后来发现我错了,W3C还不全面. 真正全面的覆盖了web前端知识体系的东西是——浏览器内核 ...

  4. delphi 线程教学第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行

    第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行     以 Ado 为例,常见的方法是拖一个 AdoConnection 在窗口上(或 DataModule 中), 再配合 AdoQ ...

  5. <p>在我们的实际软件项目中,管理团队事实上比写代码或者实现一个客户的需求更为的有挑战性。由于编程实际上是和机器打交道,而和机器打交道,仅仅要你符合机器预定的逻辑,</p>

    在我们的实际软件项目中,管理团队事实上比写代码或者实现一个客户的需求更为的有挑战性. 由于编程实际上是和机器打交道.而和机器打交道,仅仅要你符合机器预定的逻辑, 一步步迈向解决这个问题的道路上一点都不 ...

  6. 使用jq把js代码封装一个自己的插件

    为什么要把js功能封装成插件呢?我觉得有以下几点吧 1.最基本的原因就是便于代码复用. 2.便于维护和管理. 3.提升自身的能力. 4.避免各个相同功能组件的干扰,以及一些作用域会相互影响的问题. j ...

  7. iOS开发学习--纯代码 UIScrollView 无限循环的实现——代码类封装

    一个简单的利用UIScrollView 实现的无线滚动banner,下面的代码实现,因为封装问题,对两个及一下的view 支持出了一点问题(view是传参进来的,不可以生成两份),但是原理是正确的,智 ...

  8. javascript 写一段代码,判断一个字符串中出现次数最多的字符串,并统计出现的次数

    javascript 写一段代码,判断一个字符串中出现次数最多的字符串,并统计出现的次数 function test(){ var bt = document.getElementById(" ...

  9. 双缓冲绘图和窗口控件的绘制——ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 .

    双缓冲绘图和窗口控件的绘制 ---ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 cheungmine 我们通常使用ATL COM组件,生成一个带窗口的ActiveX控件,然后 ...

随机推荐

  1. JAVA线程锁lock下Condition的使用

    import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.uti ...

  2. Balsamiq Mockups 注册码

    Blacklist: Organization name: Rick DongSerial Key: eNrzzU/OLi0odswsqgnKTM5WcMnPS1eoMTQyMjexMDQyAIEa5 ...

  3. IOS开发之异步加载网络图片并缓存本地实现瀑布流(二)

    /* * @brief 图片加载通用函数 * @parma imageName 图片名 */ - (void)imageStartLoading:(NSString *)imageName{ NSUR ...

  4. Android ListView简单实用

    layout创建: activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/ ...

  5. iOS MD5加密字符串

    参考:http://stackoverflow.com/questions/1524604/md5-algorithm-in-objective-c 在线测试MD5:http://www.cmd5.c ...

  6. STM32学习笔记(五) USART异步串行口输入输出(轮询模式)

    学习是一个简单的过程,只要有善于发掘的眼睛,总能学到新知识,然而如何坚持不懈的学习却很困难,对我亦如此,生活中有太多的诱惑,最后只想说一句勿忘初心.闲话不多扯,本篇讲诉的是异步串行口的输入输出,串口在 ...

  7. STL中的查找算法

    STL中有很多算法,这些算法可以用到一个或多个STL容器(因为STL的一个设计思想是将算法和容器进行分离),也可以用到非容器序列比如数组中.众多算法中,查找算法是应用最为普遍的一类. 单个元素查找 1 ...

  8. 初识python中的类与对象

    这篇博客的路线是由深入浅,所以尽管图画的花花绿绿的很好看,但是请先关注我的文字,因为初接触类的小伙伴直接看类的实现可能会觉得难度大,只要耐着性子看下去,就会有一种“拨开迷雾看未来”的感觉了. 一.py ...

  9. Oracle job定时器的执行时间间隔学习汇总

      Oracle job 定时器的执行时间间隔也是定时器job 的关键设置,在这一设置上,开始还没掌握,总是不知道怎么写,现总结如下,其实主要是使用了TRUNC.NEXT_DAY .ADD_MONTH ...

  10. JavaWeb chapeter 5 Web应用程序状态管理

    1.  HTTP协议使用的是无状态连接,对容器而言,每一个请求都来自于一个新的客户. 2. html表单隐藏字段:对用户在网站上的访问进行会话跟踪.为服务器端程序提供预定义的输入.存储动态产生的页面上 ...