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

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

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




_ProcWinMain         proc    uses ebx edi esi;hWnd;uMsg;wParam;lParam

 

                     invoke  _ShowMessage;uMsg;wParam;lParam

                     mov     eax;uMsg

                     。if     eax   WM_XXX

                     …

_ShowMessage子程序用来将消息查表翻译成字符串,源程序如下:

_ShowMessage         proc       _uMsg;_wParam;_lParam

                     local   @szBuffer'128':byte

 

                     pushad

;********************************************************************

; 查找消息的说明字符串

;********************************************************************

                     mov        eax;_uMsg

                     mov        edi;offset dwMsgTable

                     mov        ecx;MSG_TABLE_LEN

                     cld

                     repnz   scasd

                     。if        ZERO?

                            sub     edi;offset dwMsgTable + sizeof dword

                            shr     edi;2

                            mov     eax;edi

                            mov     ecx;MSG_STRING_LEN

                            mul     ecx

                            add     eax;offset szStringTable

;********************************************************************

; 翻译格式并发送到 Notepad 窗口

;********************************************************************

                            invoke  wsprintf;addr @szBuffer;addr szFormat;

                                    _uMsg;eax;_wParam;_lParam

                            invoke _SendtoNotepad;addr @szBuffer

                     。endif

                     popad

                     ret

 

_ShowMessage         endp

在这里要用到repnz scasd指令,scasd指令是把eax中的值从'edi'开始的内存中按双字比较,同时将edi加4,如果相等,则ZR标志置位,否则为NZ,repnz表示如果标志为NZ,则以ecx为重复次数重复搜索,直到相等或ecx为零为止。

将ecx赋值为消息表的项数MSG_TABLE_LEN,将edi赋值为消息表的开始地址offset dwMsgTable,然后开始查找,停止后可以查看标志Zero位,如果是非ZERO,表示查完全部都没有找到,如果是ZERO,则表示找到表项。

当标志为ZERO时,edi指向找到项目的后一项,将edi减去一项的长度(sizeof dword)以及表的基址,再除以表项的长度(sizeof dword等于4,除以4等于右移两位,所以程序中用shr edi;2),就是消息在表中的索引了,接下来算出消息字符串的位置,位置等于:索引×字符串长+字符串表基址,代码如下:

    mov     ecx;MSG_STRING_LEN

    mul     ecx

    add     eax;offset szStringTable

这样,eax中就是字符串的地址了。最后将消息编号、名称和参数用wsprintf函数格式化成可以发送的字符串存放到@szBuffer中,并用_SendtoNotepad子程序将@szBuffer中的内容发送到记事本去。

程序增加的第二部分就是下面这个_SendtoNotepad子程序:

szDestClass      db        'Notepad';0

_SendtoNotepad   proc      _lpsz

                 local     @hWinNotepad

 

                 pushad

                 invoke    FindWindow;addr szDestClass;NULL

                 。if       eax

                           mov      ecx;eax

                           invoke   ChildWindowFromPoint;ecx;20;20

                 。endif

                 。if       eax

                           mov      @hWinNotepad;eax

                           mov      esi;_lpsz

                           @@:

                           lodsb

                           or       al;al

                           jz       @F

                           movzx    eax;al

                           invoke   PostMessage;@hWinNotepad;WM_CHAR;eax;1

                           jmp      @B

                           @@:

                 。endif

                 popad

                 ret

 

_SendtoNotepad   endp



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


第4章 第一个窗口程序


4。4 实 验(2)

    
该子程序中首先用FindWindow函数来查找记事本程序是否已经运行,记事本程序的窗口类名称为“Notepad”,FindWindow可以用窗口类当做第一个参数来查找,如果找到,返回的是记事本程序的主窗口句柄,否则返回0。

要发送的是模拟键盘按键的消息WM_CHAR,这样就好像在记事本中人工键入字符,但直接向记事本主窗口发送WM_CHAR消息是不行的,要向记事本窗口客户区中的编辑子窗口发送消息才行,所以程序中又用从位置获取子窗口句柄的函数ChildWindowFromPoint来获得编辑子窗口的句柄。

锁定了最后的目标即记事本中的编辑子窗口后,程序用PostMessage向它发送消息,根据字符串的长度,用一个循环每次发送一个WM_CHAR消息,WM_CHAR消息的wParam和lParam的含义是:

wParam = chCharCode    // wParam是键值

lParam = lKeyData      // lParam是键数据(重复次数)

程序中用mov eax;al将键值扩展到参数所需的32位,当做wParam参数发送,lParam为1,表示键的重复次数为1次,这样一来,记事本中就源源不断地显示出MsgWindow程序的运行轨迹了。

MsgWindow程序增加的第三部分是在每个函数的前后增加了显示状态的语句,它们只是简单地把一个字符串发送到记事本中去:

;定义一些字符串

szCreateWindow1    db       'Creating Window。。。';0dh;0

szCreateWindow2    db       'CreateWindow end';0dh;0

szShowWindow1      db       'Showing Window。。。';0dh;0

szShowWindow2      db       'ShowWindow end';0dh;0

szUpdateWindow1    db       'Updating Window。。。';0dh;0

szUpdateWindow2    db       'UpdateWindow end';0dh;0

szGetMsg1          db       'Getting Message。。。';0dh;0

szGetMsg2          db       ''%04x'Message gotten';0dh;0

szDispatchMsg1     db       'Dispatching Message。。。';0dh;0

szDispatchMsg2     db       'DispatchMessage end';0dh;0

                                …

                       invoke   _SendtoNotepad;addr szCreateWindow1

                       invoke   CreateWindowEx;…

                       invoke   _SendtoNotepad;addr szCreateWindow2

                       invoke   _SendtoNotepad;addr szShowWindow1

                       invoke   ShowWindow;hWinMain;SW_SHOWNORMAL

                       invoke   _SendtoNotepad;addr szShowWindow2

                       invoke   _SendtoNotepad;addr szUpdateWindow1

                       invoke   UpdateWindow;hWinMain

                       invoke   _SendtoNotepad;addr szUpdateWindow2

                       …

上面代码中的粗体部分就是相对于FirstWindow程序增加的内容,好了,现在DOS控制台上键入nmake将MsgWindow程序编译出来,然后打开记事本,再运行MsgWindow。exe,如果记事本上出现一大堆的东西,就说明实验可以开始了!

4。4。2  开始实验

实验1。 验证收到消息的顺序

打开记事本,然后运行MsgWindow程序,记事本上出现的内容为:

Creating Window。。。

WndProc: '0024'WM_GETMINMAXINFO       00000000 0012fda4

WndProc: '0081'WM_NCCREATE            00000000 0012fd8c

WndProc: '0083'WM_NCCALCSIZE          00000000 0012fdc4

WndProc: '0001'WM_CREATE              00000000 0012fd68

CreateWindow end

Showing Window。。。

WndProc: '0018'WM_SHOWWINDOW          00000001 00000000

WndProc: '0046'WM_WINDOWPOSCHANGING   00000000 0012fec0

WndProc: '0046'WM_WINDOWPOSCHANGING   00000000 0012fec0

WndProc: '001c'WM_ACTIVATEAPP         00000001 00000450

WndProc: '0086'WM_NCACTIVATE          00000001 00000000

WndProc: '000d'WM_GETTEXT             000001fe 0012f52c

WndProc: '0006'WM_ACTIVATE            00000001 00000000

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