加入收藏 | 设为首页 | 会员中心 | 我要投稿 开发网_开封站长网 (http://www.0378zz.com/)- 科技、AI行业应用、媒体智能、低代码、办公协同!
当前位置: 首页 > 教程 > 正文

Win32开发之Format MessageBox 分析

发布时间:2021-12-10 15:23:02 所属栏目:教程 来源:互联网
导读:本文介绍在Windows程序开发中的MessageBox详解。我们在在Windows程序设计中经常会涉及到一个格式化消息框,其代码如下: #include windows.h #include tchar.h #include stdio.h int CDECL MessageBoxPrintf (TCHAR * szCaption, TCHAR * szFormat, ) { TCHA

本文介绍在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 screen
    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 ;
}
 
其中:
 
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  -1
 
  int  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:  %dn",  param1);
      printf("The  first  parameter  of  function  is:  %dn",  param2);
      printf("The  first  parameter  of  function  is:  %dn",  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 != '');
 
    pArg = NULL;                              //等价于va_end
 
    return;
 
}
 
int main(int argc, char* argv[])
 
{
 
    int i = 1234;
 
    int j = 5678;   
 
    myprintf("the first test:i=%dn",i,j);
 
    myprintf("the secend test:i=%d; %x;j=%d;n",i,0xabcd,j);
 
    system("pause");
 
    return 0;
 
}
 
完毕。^_^

(编辑:开发网_开封站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读