本文介绍在Windows程序开发中的MessageBox详解。

 

  我们在在Windows程序设计中经常会涉及到一个格式化消息框,其代码如下:

#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 ;//GetSystemMetrics Api function --(SM_CXSCREEN),(SM_CYSCREEN) return weight and high,in pixles,of the screencxScreen = 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 ;
}

  其中:

va_list arg_ptr:定义一个指向个数可变的参数列表指针;

  

  va_start(arg_ptr, argN):使参数列表指针arg_ptr指向函数参数列表中的第一个可选参数,说明:argN是位于第一个可选参数之前的固定参数,(或者说,最后一个固定参数;…之前的一个参数),函数参数列表中参数在内存中的顺序与函数声明时的顺序是一致的。如果有一va函数的声明是void va_test(char a, char b, char c, …),则它的固定参数依次是a,b,c,最后一个固定参数argN为c,因此就是va_start(arg_ptr, c)。

va_arg(arg_ptr, type):返回参数列表中指针arg_ptr所指的参数,返回类型为type,并使指针arg_ptr指向参数列表中下一个参数。

  va_copy(dest, src):dest,src的类型都是va_list,va_copy()用于复制参数列表指针,将dest初始化为src。

  

  va_end(arg_ptr):清空参数列表,并置参数指针arg_ptr无效。说明:指针arg_ptr被置无效后,可以通过调用va_start()、va_copy()恢复arg_ptr。每次调用va_start() / va_copy()后,必须得有相应的va_end()与之匹配。参数指针可以在参数列表中随意地来回移动,但必须在va_start() … va_end()之内。

  下面是一个示例1,让我们看下示例1代码:

func( Type para1, Type para2, Type para3, ... )
{/****** Step 1 ******/va_list ap;va_start( ap, para3 ); //一定要“...”之前的那个参数/****** Step 2 ******///此时ap指向第一个可变参数//调用va_arg取得里面的值Type xx = va_arg( ap, Type );//Type一定要相同,如://char *p = va_arg( ap, char *);//int i = va_arg( ap, int );//如果有多个参数继续调用va_arg/****** Step 3 ******/va_end(ap); //For robust!
}

  一般的用法是:va_list args; //声明变量

  va_start(args, fmt); //开始解析。args指向fmt后面的参数

  TYPE var = va_arg(args, TYPE); //取下一个参数并返回。args指向下一个参数

va_end(args); //结束解析

  

  示例2代码如下:

#include   <stdio.h>
#include   <stdarg.h>#define   SAMPLEFOOPARAM2DEFAULT   255
#define   EOL   -1int   samplefoo(int   a,   ……){int   param1,   param2,param3;va_list   num_ptr;param1   =   a;va_start(num_ptr,   a);/*   假定这里的第二个参数是int型,如果没有就用default值   */param2   =   va_arg(num_ptr,   int);if   (   param2     ==   EOL   )param2   =   SAMPLEFOOPARAM2DEFAULT;param3=va_arg(num_ptr,int);if(param3==EOL)param3=SAMPLEFOOPARAM2DEFAULT;va_end(num_ptr);printf("The   first   parameter   of   function   is:   %d\n",   param1);printf("The   first   parameter   of   function   is:   %d\n",   param2);printf("The   first   parameter   of   function   is:   %d\n",   param3);return   0;}int   main(){printf("Output   of   samplefoo(10,   20,   EOL):\n");samplefoo(10,   20,  30,  EOL);   /*   使用的不是缺省值,注意最后的EOL是一个标记值   */printf("Output   of   samplefoo(10,   EOL):\n");samplefoo(10,   EOL,EOL);   /*   使用的不是缺省值,注意最后的EOL是一个标记值   */return   0;}

  示例3代码如下:

#include <stdio.h>#include <stdlib.h>void myprintf(char* fmt, ……)        //一个简单的类似于printf的实现,//参数必须都是int 类型

{ char* pArg=NULL;               //等价于原来的va_list char c;pArg = (char*) &fmt;          //注意不要写成p = fmt !!因为这里要对//参数取址,而不是取值
pArg += sizeof(fmt);         //等价于原来的va_start          do{c =*fmt;if (c != '%'){putchar(c);            //照原样输出字符
}else{//按格式字符输出数据switch(*++fmt) {case 'd':printf("%d",*((int*)pArg));           break;case 'x':printf("%#x",*((int*)pArg));break;default:break;} pArg += sizeof(int);               //等价于原来的va_arg
}++fmt;}while (*fmt != '\0'); pArg = NULL;                               //等价于va_endreturn; }int main(int argc, char* argv[]){int i = 1234;int j = 5678;    myprintf("the first test:i=%d\n",i,j); myprintf("the secend test:i=%d; %x;j=%d;\n",i,0xabcd,j); system("pause");return 0;}

  最后,希望转载的朋友能够尊重作者的劳动成果,加上转载地址:http://www.cnblogs.com/hanyonglu/archive/2011/04/19/2020738.html  谢谢。

  完毕。^_^

转载于:https://www.cnblogs.com/hanyonglu/archive/2011/04/19/2020738.html

Win32开发之Format MessageBox 详解相关推荐

  1. iOS开发之Accounts框架详解

    2019独角兽企业重金招聘Python工程师标准>>> iOS开发之Accounts框架详解 Accounts框架是iOS原生提供的一套账户管理框架,其支持Facebook,新浪微博 ...

  2. android中oncreate方法,android开发之onCreate( )方法详解

    这里我们只关注一句话:This is where you should do all of your normal static set up.其中我们只关注normal static, normal ...

  3. Android快速开发之appBase——(4).详解com.snicesoft.Application和BaseActivity

    转载请注明本文出自JFlex的博客http://blog.csdn.net/jflex/article/details/46441571,请尊重他人的辛勤劳动成果,谢谢! Android快速开发之ap ...

  4. android idata 模式,Android快速开发之appBase——(3).详解IHolder和IData

    Android快速开发之appBase--(3).详解IHolder和IData IHolder和IData是AVLib的两个组件,在前面已经使用过了,那么这一篇将会详细说明这两个组件的用法. IHo ...

  5. android开发之onCreate( )方法详解

    android开发之onCreate( )方法详解 onCreate( )方法是android应用程序中最常见的方法之一,那么,我们在使用onCreate()方法的时候应该注意哪些问题呢? 先看看Go ...

  6. 安卓开发之IPC机制详解

    IPC(Inter-Process Communication),意为进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程.前面在学习Handler机制时提到过线程与进程的概念,在安卓中一个进 ...

  7. edtext 从右边开始输入 安卓_Android开发之EditText属性详解

    1.EditText输入的文字为密码形式的设置 (1)通过.xml里设置: 把该EditText设为:android:password="true" // 以".&quo ...

  8. iOS开发之tintColor属性详解

    详解tintColor属性 tintColor属性是iOS7之后新加的一个属性,这个属性定义了一个非默认的着色颜色值,其值的设置会影响到以视图为根视图的整个视图层次结构.它主要是改变控件的颜色,以获取 ...

  9. 浅谈嵌入式MCU软件开发之startup过程详解(从复位向量到main函数之前的准备工作)

    引言 一般工程师都怕研究MCU的startup过程,其原因可能有:1.觉得没有必要,startup的过程和启动代码在新建工程时,并且已经默认加入并配置好,能够保证MCU正常工作,只要关系main()函 ...

最新文章

  1. COALESCE在SQL拼接中的大用途
  2. hdu 4190(二分)
  3. php中的网络接口,php中的接口interface
  4. .NET Core 3.0特性初探:C# 8、WPF、Windows Forms、EF Core
  5. 数据结构与算法分析-第一章Java类(02)
  6. google 浏览器默认打开控制台_前端开发调试:浏览器console方法总结
  7. datagrid底部显示水平滚动_看完《惊奇队长》等彩蛋,我想到了一个制作PPT滚动字幕的方法...
  8. 7-6 动物 (15 分)
  9. 算法不会,尚能饭否之排序——冒泡排序(bubble sort)
  10. dell 虚拟linux,戴尔:Linux是轻松构建虚拟主机的关键
  11. java word转pdf dox4j,使用 docx4j 将 Web 页面转换为 DOCX 与 PDF 格式
  12. 封装方法-数字转大写(一)——将数字金额转换为大写金额
  13. python画钢铁侠标志图片_python可视化之matplotlib绘图--蜘蛛侠钢铁侠(组合分区绘图)...
  14. 助力NBA复赛背后,NBA与可穿戴设备的纠葛缠斗
  15. 因忘记一个约会而写的致歉函
  16. (网络)网络层:IP协议解析、地址管理(IP地址、子网掩码)、路由选择
  17. Python批量采集无水印短视频内容
  18. 设有 4道作业,它们的提交时间及执行时间如下,试计算在单道程序环境下,采用先来先服务调度算法和短作业优先调度算法时的平均周转时间和平均带权周转时间,并指出它们的调度顺序。
  19. Ubuntu或Linux下安装flash插件
  20. python矩阵操作:dot、inv、det、eig

热门文章

  1. react 开源项目_无良老板拖欠程序员工资,一怒开源冲上 GitHub TOP1
  2. java内部类gc_Java内部类持有外部类的引用详细分析与解决方案
  3. android 重启后进入安全模式_图文详细教程:台式电脑或笔记本也可以运行Android系统,凤凰OS...
  4. c# wpf listbox 高度_农村太阳能路灯厂家报价表2020(不同高度)
  5. 在 Linux 上用 dust 代替 du更直观
  6. java中有符号数和无符号数,C语言中无符号数和有符号数之间的运算
  7. 【C语言】用宏实现将一个整数的二进制位的奇数位和偶数位交换
  8. 图论(二分图构造) ---- 二分图的性质 C. Arpa’s overnight party and Mehrdad’s silent entering
  9. c++ eos智能合约开发_十分钟教你开发EOS智能合约
  10. tc溜溜865手机投屏卡_游戏物理外挂再升级!腾讯黑鲨游戏手机3S开箱体验