友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
飞读中文网 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

windows环境下32位汇编语言程序设计-第20章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




szReceive         db       'Receive WM_SETTEXT message';0dh;0ah

                  db       'param: %08x';0dh;0ah

                  db       'text: 〃%s〃';0dh;0ah;0

在这里,要提及Win32 API中一个很常用的函数wsprintf,这是一个字符串格式化函数,可以将数值按指定格式翻译成字符串,类似于C语言中的printf函数,它的原型是这样的:

int wsprintf(

    LPTSTR lpOut;        // 输出缓冲区地址

    LPCTSTR lpFmt;       // 格式化串地址

    。。。                  // 变量列表

   );

变量列表的数目由格式化字符串规定,wsprintf处理格式化字符串,遇到普通的字符则直接拷贝到输出,遇到%字符则代表有一个变量,%后面不同的字母表示不同的输出格式,如%d表示输出为整数,%x表示输出为16进制,%s表示输出字符串等。

%符号和表示格式的d,x和s等字母间可以用数字来指定输出时占用的位长,这时输出的位长不够时函数会用空格填齐。另外,表示位长的数字前可以加0来表示填齐时用“0”而非空格,如%08x表示输出为8位前面用0填齐的16进制数。wsprintf是Win32 API中惟一一个参数数量不定的函数,使用wsprintf函数的时候,参数的数量取决于格式化字符串中用%号指定的数量,变量列表的数目和格式化串中的%格式一定要一一对应。这里szReceive中有两个%号定义,那么后面就要额外跟两个参数:

    invoke  wsprintf;addr szBuffer;addr szReceive;lParam;lParam

这条语句将lParam的数值以及lParam的字符串按照szReceive格式化串定义的格式转换,并将结果存放到szBuffer中,然后程序将szBuffer中的内容在一个消息框中显示出来:

    invoke  MessageBox;hWnd;offset szBuffer;addr szCaptionMain;MB_OK

接收程序写好了,现在来写一个发送程序,如下所示:

               。386

               。model flat;stdcall

               option casemap:none

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

include        windows。inc

include        user32。inc

includelib     user32。lib

include        kernel32。inc

includelib     kernel32。lib

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

               。data

hWnd           dd     ?

szBuffer       db     256 dup (?)

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

               nst

szCaption      db     'SendMessage';0

szStart        db     'Press OK to start SendMessage; param: %08x!';0

szReturn       db     'SendMessage returned!';0

szDestClass    db     'MyClass';0

szText         db     'Text send to other windows';0

szNotFound     db     'Receive Message Window not found!';0

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

               de

start:

               invoke FindWindow;addr szDestClass;NULL

               。if    eax

                      mov     hWnd;eax

                      invoke  wsprintf;addr szBuffer;addr szStart;addr szText

                      invoke  MessageBox;NULL;offset szBuffer;

                              offset szCaption;MB_OK

                      invoke  SendMessage;hWnd;WM_SETTEXT;0;addr szText

                      invoke  MessageBox;NULL;offset szReturn;

                              offset szCaption;MB_OK

               。else

                      invoke  MessageBox;NULL;offset szNotFound;

                      offset  szCaption;MB_OK

               。endif

               invoke ExitProcess;NULL

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

               end    start

在这个程序中首先用FindWindow函数找到接收窗口的窗口句柄,FindWindow函数的使用方法是:

    invoke  FindWindow;lpClassName;lpWindowName

    。if     eax

            mov hWin;eax

    。endif

两个参数都指向字符串,lpClassName指向需要寻找的窗口的窗口类,lpWindowName指向需要寻找窗口的窗口标题,如果目标窗口存在的话,函数的返回值是找到的窗口句柄,否则函数返回0。

用接收窗口的窗口类当做参数寻找窗口,如果没有找到则显示“Receive Message Window not found”,找到的话则把“Text send to other windows”字符串的地址当做WM_SETTEXT消息的参数用SendMessage发送给接收窗口。两个程序的源代码可以在所附带光盘的Chapter04SendMessage目录中找到。

好!现在发送开始,首先执行Receive。exe,窗口出来了,然后执行Send。exe,屏幕上出现一个对话框:Press OK to start SendMessage; param: 00402072,表示在Send程序中字符串的地址是00402072h,现在单击“确定”按钮执行SendMessage函数,单击后对话框消失,但接收程序显示出了一个对话框,内容为:

Receive WM_SETTEXT message

param: 0012ff1c

text: 〃Text send to other windows〃

可见字符串是正确地传了过来,但地址却不是发送程序的00402072h,这是怎么回事呢?答案是Windows做“红娘”做到底,它拷贝了WM_SETTEXT消息lParam指向的字符串,并在接收程序的地址空间中开了一块内存放上这个字符串,然后把新的地址值当做lParam传给接收程序,毕竟在WM_GETTEXT消息中,lParam的数值是多少并不重要,重要的是它指向的字符串是否正确。

最后,单击Receive 程序中的“确定”按钮,Send程序马上会弹出一个消息框并显示:SendMessage returned,这是SendMessage函数告诉我们:我回来了!

其实Windows在处理SendMessage和PostMessage的时候要检查消息的类型,并对不同的消息做不同的处理,当消息的参数是一个指针的时候,Windows要把指针指向的内容复制到缓冲区,以便在两个程序的地址空间中传递。

 在用户自定义的消息中(WM_USER等)不要在消息参数中传递指针,这只会引发非法访问内存,因为Windows不知道用户的意图,它只会把lParam和wParam当两个普通的数值传递,而不会帮用户把指针指向的内容复制到一个缓冲区中。



 
来源:电子工业出版社 作者:罗云彬 上一页         回书目         下一页          
上一页         回书目         下一页          
  


第4章 第一个窗口程序


4。4 实 验(1)

    
在这一节中,将通过不同的实验,进一步介绍窗口的运行。首先构造一个程序,在程序中将收到的消息查表翻译成文本以“WM_XXX”格式显示出来,并且将调用各个API函数的过程也显示出来,这样可以分析窗口的各种行为和消息之间的关系。

4。4。1  MsgWindow程序

为了把需要的内容显示出来,可以选择在客户区显示文本,但这样会引入新的消息,干扰实验,所以,这里选择了一种新的方法,就是先打开Windows附件中自带的Notepad记事本程序,然后在程序中将要显示的内容通过SendMessage发送到记事本中,可以通过查看记事本中的内容来了解MsgWindow的运行情况。

同样,先拷贝一份FirstWindow程序进行修改,共增加3个部分。第一部分是将消息查表转换为字符串,首先在 nst段中增加两个表:16进制的消息编号列表dwMsgTable和字符串列表szStringTable,两表中的项目一一对应,代码如下:

                 nst

dwMsgTable       dd       WM_NULL

                 dd       WM_CREATE

                 dd       WM_DESTROY

                 dd       WM_MOVE

                 …

                 dd       WM_EXITSIZEMOVE

MSG_TABLE_LEN    equ      ( … dwMsgTable)/sizeof dword

 

MSG_STRING_LEN   equ      sizeof szStringTable

szStringTable    db       'WM_NULL                ';0

                          db'WM_CREATE            ';0

                 db       'WM_DESTROY             ';0

                 db       'WM_MOVE                ';0

                 …

                 db       'WM_EXITSIZEMOVE        ';0

szFormat         db       'WndProc: '%04x'%s %08x %08x';0dh;0

MSG_TABLE_LEN定义了表的项数,MSG_STRING_LEN定义了字符串表中每一项的长度。sizeof操作符取的是szStringTable这一行中的数据长度,而非包括下面全部的字符串行。为了简化处理,全部字符串的长度保持相等。由于篇幅所限,这里没有列出全部的消息列表,完整的源代码可以在本书附带光盘的Chapter04MsgWindow01目录中找到。程序在窗口过程的入口处调用_ShowMessage子程序来翻译消息并传给记事本:

_ProcWinMain         proc    uses e
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!