刚开始学习Windows程序设计,磕磕碰碰,先做个小笔记缓缓神经,主要是将MessageBox这个Windows API函数的。

  MessageBox函数是许多人刚开始学习Windows程序设计或者是Windows API遇到的第一个内置函数,这个函数使用的方式是:

  MessageBox(NULL, TEXT("弹出框内容"), TEXT("标题"), MB_OK);

  初次之外,它还有几个姐妹:

  MessageBoxA(NULL, "弹出框内容", "标题", MB_OK);   // TEXT可有可无

  MessageBoxW(NULL, L"", L"", MB_OK);                       // 这个L用来表示Unicode,不可以省略

  其实之所以有这两个是因为微软需要满足Windows 98之后对汉字等其他语言编码的需求,这种需求通过Unicode实现,但是微软本意不是要我们使用Unicode来编程,而是通过使用“通用”形式,也就是MessageBox();函数,实现不同的编码主要还是通过IDE集成开发环境下改变不同的编码形式。回到MessageBox();,今天比较头疼的是,怎么在MessageBox();中实现变量的打印呢?

  就像C语言中经常使用printf函数,这个函数挺有趣的,应为函数输入的参数是没有限定个数的,相当于是随机改变的。例如:

 #include <stdio.h>
#include <stdlib.h> int main(){
5
int x=, y=, z=; printf("%d %d %d.\n", x, y, z);
system("pause");
return ;
}

  这个printf函数不仅可以使用多个参数打印,还可以用来直接打印变量,但是MessageBox却不能直接打印,这个引起我的直接思考。我先想到的是建立一个缓冲区,利用这个缓冲区取打印字符数据。当然打印的函数得使用sprintf了

  

 int main(){

     int a = ;
char szBuffer[]; // 使用一个字符数组来做缓冲区 sprintf(szBuffer, "helloworld %d.\n", a);
_snprintf(szBuffer, , "helloworld %d.\n", a);
// 使用_snprintf函数比较安全,因为可以输入限定字符的个数 printf("%s.\n", szBuffer);
puts(szBuffer); // 可以使用printf中的%s将szBuffer打印出来,或者用puts直接输出
//printf("helloworld.\n"); system("pause");
return ;
}

  这个缓冲区的方法如果用在MessageBox函数里面,就可以实现打印变量的方式,比如以下代码:

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
int a = ; TCHAR szBuffer[]; // 通用版本
_stprintf(szBuffer, TEXT("hello 通用 %d"), a);
MessageBox(NULL, szBuffer, TEXT("通用"), MB_OK | MB_ICONINFORMATION); return ;
}

  但是每次都写个缓冲区来存放,并且一不下心忘记使用_snprintf函数,那就GG了,很可能发生缓冲区溢出的危险。因此,这里利用printf原先函数设计的原理,我们也来设计一个MessageBoxPrintf();函数,用这个函数来实现格式化输出的作用,要实现这个函数,首先得参照printf();函数的实现原理。

int my_printf(const char * szFormat, ...){

    int iReturn;
va_list pArgs; va_start(pArgs, szFormat);
iReturn = vprintf(szFormat, pArgs);
va_end(pArgs); return iReturn;
} int main(){ int x=, y=, z=; printf("hello %d, %d, %d.\n", x, y, z);
my_printf("test_my_printf,哈哈%d %d.\n", x, y); system("pause");
return ;
}

  ...表示的意思是传入的参数是可变参数个数的,va_start(pArgs, szFormat);表示指向szFormat之后的一个参数,这个函数的许多东西我现在也还没理解过来,之后再来补充,不过现在仿照这个函数我们可以自己写个MessageBoxPrintf();函数,具体代码如下:

// 自己做一个格式化的messageboxprintf对话框
int CDECL MessageBoxPrintf(TCHAR * szCaption, TCHAR * szFormat, ...){ TCHAR szBuffer[];
va_list pArglist; va_start(pArglist, szFormat);
_vsnprintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), szFormat, pArglist);
va_end(pArglist); return MessageBox(NULL, szBuffer, szCaption, MB_OK | MB_ICONINFORMATION);
} int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ int x=, y=, z=;
int cxScreen, cyScreen; cxScreen = GetSystemMetrics(SM_CXSCREEN);
cyScreen = GetSystemMetrics(SM_CYSCREEN); // MessageBoxW(NULL, L"helloworld", L"biaoti", MB_OK);
// MessageBoxA(NULL, TEXT("helloworld"), TEXT("biaoti"), MB_OK);
MessageBoxPrintf(TEXT("我的标题"), TEXT("hello %d %d %d"), x, y, z); // 把这个函数做好后,直接就可以输出
MessageBoxPrintf(TEXT("我的屏幕大小"), TEXT("我的屏幕宽度是:%d.\n高度是:%d.\n"), cxScreen, cyScreen); return ;
}

  相当于自己设计出来一个类似printf的小工具,因为微软确实没有设计MessageBox中进行格式化输出的函数。

05-11 11:07