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

//-----------------------------------------
//本程序展示了如何实现MessageBoxPrintf函数
//本函数能像printf那样格式化输出
//摘录自:《windows程序设计第五版》
//-----------------------------------------
#include<windows.h>
#include<tchar.h>
#include<stdio.h>

int CDECL MessageBoxPrintf(TCHAR * szCaption, TCHAR * szFormat, ...)
{
    TCHAR szBuffer[1024];

    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,0);
}
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 0;
}

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

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

时间: 2024-11-05 23:01:13

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

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

以下的代码段用于获取视屏显示器的高度宽度,以像素为单位. 1 int sxScreen, cyScreen; 2 cxScreen = GetSystemMetrics (SM_CXSCREEN); 3 cyScreen = GetSystemMetrics (SM_CYSCREEN); 关于本函数的其他信息可通过百度百科获取 http://baike.baidu.com/link?url=ZaNA7uLcPBpdGmkIFNkXJ_GvJ-lgwaphwjVAjaKKNT2qPeIubmYZ6

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

1)Linux程序设计入门--基础知识 Linux下C语言编程基础知识 前言: 这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将 会学到以下内容: 源程序编译 Makefile的编写 程序库的链接 程序的调试 头文件和系统求助 1.源程序的编译 在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器. 下面我们 以一个实例来说明如何使用gcc编译器. 假设我们有下面一个非常简单的源程序(hello.c): int main(int argc,

【软考】【软件设计师】【知识模块】【第2章:程序设计语言基础知识】

程序设计语言基础知识 2.1 程序设计语言概述 2.1.1  程序设计语言基本概念 低级语言,面向机器的语言,如汇编语言.机器语言: 特性:进行程序设计效率低,程序的可读性差,难以修改.维护,优势是运行速度特别快: 高级语言,面向各类应用的程序设计语言.如C.C++ .Java.Python.Delphi .Pascal.Php 语言处理程序:负责将高级语言翻译成计算机能理解的0和1的程序: 语言之间的翻译基本方式: 汇编.解释.编译: 汇编:对使用汇编语言写成的源程序进行翻译成目标程序(机器可

(十二) 完整注释的代码摘录

title: 完整注释的代码摘录 date: 2019/4/23 20:40:00 toc: true --- 完整注释的代码摘录 作者网页 #include <linux/kernel.h> #include <linux/list.h> #include <linux/module.h> #include <linux/usb.h> #include <linux/videodev2.h> #include <linux/vmalloc

知识网络模型:记忆是一个整合的过程

?记忆的重要性 ?网状图(地图)模型 ?"整合"才是记忆之道 ?"活记"和"死记" 声明:这里所讲的记忆,主要是在学习领域.  前言:很难给这篇文章起个比较好的标题,一开始起的是"记忆之道:摆脱死记硬背",但是感觉这篇文章重点不在于讲记忆的各种技巧:想要用"记忆的本质",但是一谈到本质,就是比较深刻的问题,而记忆,本质可能更多在于生物和神经领域.最后,就用 "知识网络模型:记忆是一个整合的过程&q

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

.web前端的这么知识应该是怎样的一个知识体系架构?之前我以为可以以W3C为纲要,把W3C的东西学会了就够了.后来发现我错了,W3C还不全面. 真正全面的覆盖了web前端知识体系的东西是——浏览器内核——这并不是说让你去详细了解浏览器内核.做出一个浏览器.浏览器是web前端代码运行的一个平台,浏览器内核里有哪些模块,我们就需要去学习哪些东西.详细的先不说,以后有机会再分享.

NetBeans自定义代码折叠块,类似vs中的#region

//<editor-fold defaultstate="collapsed" desc="测试代码折叠"> echo '<script type="text/javascript">'; echo "alert('当前类目下有文章,不能删除!');"; echo "history.go(-1)"; echo "</script>"; exit;//&

ios网络学习------8 xml格式数据的请求处理 用代码块封装

#pragma mark 加载xml - (void)loadXML { //获取网络数据. NSLog(@"load xml"); //从web服务器加载数据 NSString *str = @"http://www.baidu.com?format=xml"; //这里是乱写的 //1简历NSURL NSURL *url = [NSURL URLWithString:str]; //2建立NSURLRequest NSURLRequest *request =

如何在java代码中调用一个web项目jsp或者servlet

有时候需要调用一个web项目的jsp或者servlet,但是执行内部的代码,并不是打开jsp,例如需要在一段java代码中清除一个web项目中的缓存,那么可以把清除缓存的代码放在该web项目的一个servlet中,只需要执行如下代码: URL url = new URL("http://192.168.2.123:8080/sace/ClearCache"); url.openStream(); openStream() 执行一次相当于一次URL请求,其中url.openStream(