在窗口间传递数据

来源:互联网 发布:卡盟刷钻平台软件 编辑:程序博客网 时间:2024/06/10 23:24

对于不同应用程序之间的窗口中可以互发消息 方法是通过SendMessage 或者PostMessage 函数,用法为:

invoke PostMessage,hWnd,Msg,wParam,lParam

invoke SendMessage,hWnd,Msg,wParam,lParam

对于WM_SETTEXT来说 wParam=0 lParam=(LPARAM)(LPCTSTR)lpsz

首先拷贝FirstWindow中的代码  在回调函数中加入以下代码:

.elseif    eax ==    WM_SETTEXT
            invoke    wsprintf,addr szBuffer,addr szReceive,\
                lParam,lParam

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

同时在数据段中加上下列定义:


szCaptionMain    db    'Receive Message',0

szReceive    db    'Receive WM_SETTEXT message',0dh,0ah
        db    'param: %08x',0dh,0ah
        db    'text: "%s"',0dh,0ah,0


调用如下语句:

invoke wsprintf,addr szBuffer,addr szReceive,lParam,lParam

将收到的结果存放到szBuffer中 然后将szBuffer中的内容在一个消息框中显示出来:

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


接收程序就写好了


下面来写发送程序;

发送程序利用FindWindow函数找到接收窗口的窗口句柄,FindWindow函数使用方法是:

invoke FindWindow,lpClassName,lpWindowName

.if eax

mov hWin,eax

.endif

send.exe源代码如下:

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; Sample code for < Win32ASM Programming 2nd Edition>; by 罗云彬, http://asm.yeah.net;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; Send.asm; 从一个程序向另一个窗口程序发送消息 之 发送程序;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 使用 nmake 或下列命令进行编译和链接:; ml /c /coff Send.asm; Link /subsystem:windows Send.obj;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.386.model flat,stdcalloption casemap:none;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; Include 文件定义;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>includewindows.incincludeuser32.incincludelibuser32.libincludekernel32.incincludelibkernel32.lib;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 数据段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.datahWnddd?szBufferdb256 dup (?).constszCaptiondb'SendMessage',0szStartdb'Press OK to start SendMessage, param: %08x!',0szReturndb'SendMessage returned!',0szDestClassdb'MyClass',0;目标窗口的窗口类szTextdb'Text send to other windows',0szNotFounddb'Receive Message Window not found!',0;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 代码段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.codestart:invokeFindWindow,addr szDestClass,NULL.ifeaxmovhWnd,eax;找到目标窗口则发送消息invokewsprintf,addr szBuffer,addr szStart,addr szTextinvokeMessageBox,NULL,offset szBuffer,offset szCaption,MB_OKinvokeSendMessage,hWnd,WM_SETTEXT,0,addr szTextinvokeMessageBox,NULL,offset szReturn,offset szCaption,MB_OK.elseinvokeMessageBox,NULL,offset szNotFound,offset szCaption,MB_OK.endifinvokeExitProcess,NULL;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>endstart

receive.exe

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; Sample code for < Win32ASM Programming 2nd Edition>; by 罗云彬, http://asm.yeah.net;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; Receive.asm; 从一个程序向另一个窗口程序发送消息 之 消息接收程序;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 使用 nmake 或下列命令进行编译和链接:; ml /c /coff Receive.asm; Link /subsystem:windows Receive.obj;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.386.model flat,stdcalloption casemap:none;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; Include 文件定义;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>includewindows.incincludegdi32.incincludelibgdi32.libincludeuser32.incincludelibuser32.libincludekernel32.incincludelibkernel32.lib;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 数据段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.data?hInstancedd?hWinMaindd?szBufferdb512 dup (?).constszClassNamedb'MyClass',0szCaptionMaindb'Receive Message',0szReceivedb'Receive WM_SETTEXT message',0dh,0ahdb'param: %08x',0dh,0ahdb'text: "%s"',0dh,0ah,0;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 代码段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.code;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 窗口过程;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_ProcWinMainprocuses ebx edi esi,hWnd,uMsg,wParam,lParammoveax,uMsg;********************************************************************.ifeax ==WM_CLOSEinvokeDestroyWindow,hWinMaininvokePostQuitMessage,NULL;********************************************************************; 收到 WM_SETTEXT 消息则将消息字符串和字符串地址显示出来;********************************************************************.elseifeax ==WM_SETTEXTinvokewsprintf,addr szBuffer,addr szReceive,\lParam,lParaminvokeMessageBox,hWnd,offset szBuffer,addr szCaptionMain,MB_OK;********************************************************************.elseinvokeDefWindowProc,hWnd,uMsg,wParam,lParamret.endif;********************************************************************xoreax,eaxret_ProcWinMainendp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_WinMainproclocal@stWndClass:WNDCLASSEXlocal@stMsg:MSGinvokeGetModuleHandle,NULLmovhInstance,eaxinvokeRtlZeroMemory,addr @stWndClass,sizeof @stWndClass;********************************************************************; 注册窗口类;********************************************************************invokeLoadCursor,0,IDC_ARROWmov@stWndClass.hCursor,eaxpushhInstancepop@stWndClass.hInstancemov@stWndClass.cbSize,sizeof WNDCLASSEXmov@stWndClass.style,CS_HREDRAW or CS_VREDRAWmov@stWndClass.lpfnWndProc,offset _ProcWinMainmov@stWndClass.hbrBackground,COLOR_WINDOW + 1mov@stWndClass.lpszClassName,offset szClassNameinvokeRegisterClassEx,addr @stWndClass;********************************************************************; 建立并显示窗口;********************************************************************invokeCreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\WS_OVERLAPPEDWINDOW,\50,50,200,150,\NULL,NULL,hInstance,NULLmovhWinMain,eaxinvokeShowWindow,hWinMain,SW_SHOWNORMALinvokeUpdateWindow,hWinMain;********************************************************************; 消息循环;********************************************************************.whileTRUEinvokeGetMessage,addr @stMsg,NULL,0,0.break.if eax== 0invokeTranslateMessage,addr @stMsginvokeDispatchMessage,addr @stMsg.endwret_WinMainendp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>start:call_WinMaininvokeExitProcess,NULL;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>endstart

课件字符串正确的传了过来 但是地址却不是发送地址。因为当Windows在处理SendMessage的时候检查消息类型 发现发送的的消息参数是一个指针的时候。Windows对指针指向的内容更进行一些处理,以便能够正常的传递进目标进程中。

Windows首先创建一块共享内存,并将WM_SETTEXT消息lParam指向的字符串拷贝到该内存中,然后在发消息到其他进程,并将共享内存在目标进程中的地址发送给目标窗口过程,目标窗口郭城处理完消息后 函数返回 共享内存释放。(内存映射文件技术)




为了能够在不同进程的窗口间自由地任意拷贝任意类型的数据。windows提供了一个特殊消息  WM_COPYDATA

COPYDATASTRUCT STRUCT

dwData DWORD ?;附加字段

cbData DWORD ?;数据长度

lpData DWORD ?;数据位置指针

COPYDATASTRUCT ENDS



.data

stCopyData COPYDATASTRUCT <>


.code

...

invoke SendMessage,hDestWnd,WM_COPYDATA,hWnd,addr stCopyData

hDestWnd为目标窗口句柄 wParam指定为hWnd 是当前窗口的句柄 lParam 指向已经填充完毕的COPYDATASTRUCT




SendMessage 和 PostMessage的区别
对于普通消息 两者几乎没有区别,但对于WM_SETTEXT WM_COPYDATA等在参数中用到指针的消息来说 两者就有所不同
当用PostMessage函数实现上述消息时,会发现根本接收不到消息,这是因为,当消息参数中用到指针时,用PostMessage函数来发送消息都不会成功。该函数不能用于任何参数中用到指针的消息、


0 0
原创粉丝点击