歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Win32開發之Format MessageBox 詳解

本文介紹在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:  %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_end

    return;

}

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;

}

完畢。^_^

Copyright © Linux教程網 All Rights Reserved