//显然,在汇编源文件中涉及的以 inc 为扩展名的文件一般为包含文件,由此可知,inc 是 include(包含)的缩写了。
windows.inc 中是这样描述的:
IFNDEF _wininc_ ;如果没有定义_wininc_ _wininc_ equ <1> ;那么 _wininc_ 定义为 1
wsprintfA PROTO C :DWORD,:VARARG wsprintf equ 由上面2个包含文件中的原型声明可知,wsprintf 与 wsprintfA 是等同的。 实际中基本所有函数都有2个版本,即 ANSI 版和 UNICODE(宽字符)版,命名规则上在函数名后冠以A和W来区分,wsprintf也不例外,同样有2 个版本,分别是 wsprintfA 和 wsprintfW WINUSER.H 中是这样描述的: // #ifdef UNICODE ;如果定义为 UNICODE #define wsprintf wsprintfW ;那么 wsprintf 就是 wsprintfW #else ;否则 #define wsprintf wsprintfA ;定义wsprintf 就是 wsprintfA #endif // !UNICODE // 由上面的头定义中可以看出,通过上面对ANSI 和 UNICODE 2个版本的定义,我们在实际编程时源文件中为什么只用了 wsprintf 函数名而从没 使用 wsprintfW 和wsprintfA 的原因,你把自己编写的程序静态反汇编或动态调试时为什么只见到 wsprintfW 和 wsprintfA(如果你编写的程 序中调用了这个函数的话,没有调用这个函数你至少也得调用一个吧), 二、定义 1、int wsprintf(LPTSTR lpOut, // 输出缓冲区,最大为1024字节 LPCTSTR lpFmt, // 格式字符串 ... //需输出参数列表,由此可知,只有这个函数的参数个数无法确定,也是所有函数中的一个特例(无法确定参数 //个数的唯一函数),其他函数的参数个数是确定的,只此例外。 ); 使用此函数可将数字转为字符串; 例:(C 语言源程序片断) int x=6 LPTSTR szBuffer=new TCHAR[1024]; wsprintf(szBuffer,\"%d\将变量x的值格式化为数字(%d)输出到缓冲区szBuffer指向的内存单元。 MessageBox(NULL,szBuffer,\" \ 以下红色部分阐述的申明: 以下部分阐述是完全错误的,读者不予理会,保留的目的是楼下对这个部分给了纠正建议,特意保留以示对 pengmo 的尊重和对自己所犯严重错误不得原谅的“回报”。 int x=6; LPTSTR szBuffer=new TCHAR[1024]; wsprintf(szBuffer,\"%d\//将指向缓冲区szBuffer的数据格式化为数字(%d)并按6位(int x=6)输出,如果缓冲区数据的实际位数<6,位数不够部分的左侧填充空格(还是0)???来补足,如果缓冲区数据的实际位数>=6,按实际位数输出还是截去多余的位数输出??? MessageBox(NULL,szBuffer,\" \ 由于我的不解而导致模棱两可引发误导读者,请熟悉并能准确说明的高级读者多我上述的???部分进行正确说明,在此谢过了,呵呵! ======================================== 2、wsprintf的用法 假设我们在.data中这样定义: szCaptionMain db '接收消息',0 szReceive db '接收 WM_SETTEXT 消息',0dh,0ah db '参数:%08x',0dh,0ah db '文本: \"%s\"',0dh,0ah,0 Win32 API中一个很常用的函数wsprintf,这是一个字符串格式化函数,可以将数值按指定格式转换成字符串, 类似于C语言中的printf函数,它的原型是这样的: int wsprintf( LPTSTR lpOut, // 输出缓冲区地址 LPCTSTR lpFmt, // 格式化串地址 ... // 变量列表(由此可以看出,参数个数无法确定,这正是参数入栈为什么不用stdcall 规范的原因,所有函数中的 一个特例) ); 3、作用或功能 wsprintf 与 C 语言中的功能一样都是对字符串进行格式化输出。 不过应该注意的是:wsprintf 不是将格式化结果写到标准输出,而是将其写入缓冲区中,该函数返回该字符串的长度。 三、格式化输出格式 实际使用中格式化输出以 % 打头,后跟以一个控制输出格式的字母。 1. 格式化规定符 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 符号 作用 ──────────────────────────────────────── %d 格式化为十进制有符号整数输出到缓冲区 %u 格式化为十进制无符号整数输出到缓冲区 %f 格式化为浮点数输出到缓冲区 %s 格式化为字符串输出到缓冲区 %c 格式化为单个字符输出到缓冲区 %e 格式化为指数形式的浮点数输出到缓冲区 %x 格式化为无符号以十六进制表示的整数(a-f小写输出)输出到缓冲区 %X 格式化为无符号以十六进制表示的整数(a-f大写输出)输出到缓冲区 %0 格式化为无符号以八进制表示的整数输出到缓冲区 %g 格式化为自动选择合适的表示法输出到缓冲区 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 说明: (1). 可以在\"%\"和字母之间插进数字表示最大场宽。 例如: %3d 表示输出3位整型数, 不够3位右对齐。 %9.2f 表示输出场宽为9的浮点数, 其中小数位为2, 整数位为6,小数点占一位, 不够9位右对齐。 %8s 表示输出8个字符的字符串, 不够8个字符右对齐。 如果字符串的长度、或整型数位数超过说明的场宽, 将按其实际长度输出。但对浮点数, 若整数部分位数超过了说明的整数位宽度, 将按 实际整数位输出;若小数部分位数超过了说明的小数位宽度, 则按说明的宽度以四舍五入输出。 另外, 若想在输出值前加一些0, 就应在场宽项前加个0。 例如: %04d 表示在输出一个小于4位的数值时, 将在前面补0使其总宽度为4位。 如果用浮点数表示字符或整型量的输出格式, 小数点后的数字代表最大宽度,小数点前的数字代表最小宽度。 例如: %6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9, 则第9个字符以后的内容将被删除。 (2). 可以在\"%\"和字母之间加小写字母l, 表示输出的是长型数。 例如: %ld 表示输出long整数 %lf 表示输出double浮点数 (3). 可以控制输出左对齐或右对齐, 即在\"%\"和字母之间加入一个\"-\" 号可说明输出为左对齐, 否则为右对齐。 例如: %-7d 表示输出7位整数左对齐 %-10s 表示输出10个字符左对齐 上面的格式化输出参照 C 语言中的 printf 函数,对于汇编语言中的 wsprintf 函数的格式化是否还有其他形式或上述格式列表中的某些项目不适用 wsprintf,我也不是很清楚。 希望大家都来参与讨论! 记得以前在学 C 的时候我们可以用 printf 验证程序的输出结果。 在 windows 里面,输出结果我们可以用 MessageBox(),只是,它只处理字符串! 具体的数值怎么办? 其实,你算出来的结果可以用 wsprintf() 来作处理,它是 printf 的近亲! wsprintf 函数最大的特点是它不会输出到屏幕,它只生成 MessageBox 要用的字符串。 加上 lstrcat (追加字符串) 就更方便了,下面是它们在源码里面的用法: (假定你已经非常熟悉 printf 用法) // File Name: WinMain.cpp //指定下面一句说明该程序与 MFC 无关,可以加快编译速度 #define WIN32_LEAN_AND_MEAN // Say No to MFC !! #include char Temp[77] = \"\"; // 定义一个空字符串 char Result[250] = \"\"; // // Name: WinMain() // ------ ---------- ----------- --------- int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { long x = - 40, y = 25, z = 0 ; z = x * y; // z 是我们要输出验证的结果 wsprintf( Result , \"结果是:%ld \\n\" , z ); // 最基本的 wsprintf 用法,第一个参数是目标字符串 // 第一次显示结果 MessageBox( NULL, Result, \"Sample_Code __CopyRight - `海风 \MB_OK | MB_TOPMOST ); wsprintf( Temp, \" 全式为: %ld × %ld = %ld\ x, y, z ); lstrcat( Result , Temp ); // 这是用的是追加字符串的方法 // 第二次显示结果 MessageBox( NULL, Result, \"Sample_Code __CopyRight - `海风 \MB_OK | MB_TOPMOST ); ExitProcess(0); return NULL; } // 关于 wsprintf 详细用法请参看 msdn 一个提示,这个方法我以前经常用在调试的时候察看某个变量的值变化。 不过现在看来实在不推荐。因为 MessageBox 函数其实是一个宏,它会创建一个窗口来显示信息,同时也创建一个消息循环来提取消息,如果你需要仔细研究和处理每一条消息队列里的消息,那样一定会出错! 关于消息队列我以后会详细说明。 有人不理解 为什么要 #define WIN32_LEAN_AND_MEAN 。 答案很简单,因为我要包含尽量精简的内容,包含了这一句编译的时候明显快多了。 不过,你的机器高于 800 兆主频是看不出来的! 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- efsc.cn 版权所有 赣ICP备2024042792号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务