生活的天平本不平衡,只有通过努力改变其偏向。

窗口间的数据通信之消息通信

2008-06-14

Windows窗口之间的通信有多种方式,据我所知的就有:通过Socket、互发消息、剪贴板等,我用Win32 ASM演示了通过互发消息进行通信的两种方式,一种方式通过发送WM_SETTEXT,进行简单的字符串的通信;一种方式通过WM_COPYDATA的方 式进行复杂数据通信。

演示程序和代码下载:

  WinComunication.zip (6.3 KiB, 453 hits)

程序界面:

接收端的CallBack:

ASM代码
  1. ;窗口回调函数
    _WndProc proc hwnd:HWND,msg:UINT, wParam:WPARAM, lParam:LPARAM
    ;local    RecCDS:COPYDATASTRUCT
    mov eax,msg
    .if eax == WM_CREATE
    invoke CreateWindowEx,0,offset szEditClass, 0,WS_CHILD or WS_VISIBLE or WS_VSCROLL or ES_LEFT or ES_MULTILINE or ES_AUTOVSCROLL, 0, 0, 0, 0, hwnd, IDEDIT, hInstance, 0
    mov hEditWnd,eax
    invoke _SetFont,eax
    .elseif eax == WM_SETTEXT
    invoke SendMessage, hEditWnd, EM_SETSEL, -1, -1
    invoke SendMessage, hEditWnd, EM_REPLACESEL, 0, lParam
    .elseif eax == WM_COPYDATA
    mov ebx,lParam
    invoke SendMessage, hEditWnd, EM_SETSEL, -1, -1

    ;invoke    SendMessage, hEditWnd, EM_REPLACESEL, 0, [ ebx + COPYDATASTRUCT.lpData ] ; 可有用这种方式定位结构体

    ;也可以用这种方式定位结构体
    assume ebx:ptr COPYDATASTRUCT
    invoke SendMessage, hEditWnd, EM_REPLACESEL, 0, [ ebx ].lpData
    assume ebx:nothing

    .elseif eax == WM_CLOSE
    invoke DestroyWindow,hwnd
    invoke PostQuitMessage,0
    .elseif eax == WM_SIZE
    mov eax,lParam
    mov bx,ax
    shr eax,16
    invoke MoveWindow, hEditWnd, 1, 1, ebxeaxTRUE
    .else
    invoke DefWindowProc,hwnd,msg,wParam,lParam
    ret
    .endif
    xor eax,eax
    ret
    _WndProc endp

发送端的CallBack:

ASM代码
  1. ;窗口回调函数
    _CallWnd     proc hwnd:HWND, msg:UINT, wParam:WPARAM, lParam:LPARAM
    local SendCDS:COPYDATASTRUCT
    mov eax,msg

    .if eax == WM_CREATE
    invoke CreateWindowEx,0,CTEXT(“BUTTON”),CTEXT(“WM_SETTEXT发送”),\
    WS_CHILD or WS_VISIBLE, 125,80,150,30,hwnd, IDM_BTN_SETTEXT,hInstance,0

    invoke _SetFont,eax

    invoke CreateWindowEx,0,CTEXT(“BUTTON”),CTEXT(“WM_COPYDATA发送”),\
    WS_CHILD or WS_VISIBLE, 125,150,150,30,hwnd, IDM_BTN_COPYDATA,hInstance,0

    invoke _SetFont,eax

    call _CheckTarget
    .elseif eax == WM_COMMAND

    ;SetText按钮按下
    .if wParam == IDM_BTN_SETTEXT
    call _CheckTarget
    .if hTargetWin != 0
    invoke SendMessage, hTargetWin, WM_SETTEXT,0,offset szSetText_Data
    ;invoke MessageBox, 0, CTEXT(“我发送了WM_SETTEXT到接收端”),CTEXT(“信息”),0
    .endif
    .endif

    ;CopyData按钮按下
    .if wParam == IDM_BTN_COPYDATA
    call _CheckTarget
    .if hTargetWin != 0
    invoke RtlZeroMemory,addr SendCDS,sizeof COPYDATASTRUCT

    invoke _GetStringLen,offset szCopyData_Data

    mov SendCDS.cbData ,eax
    mov SendCDS.lpData ,offset szCopyData_Data
    invoke SendMessage, hTargetWin, WM_COPYDATA,hwnd,addr SendCDS
    ;invoke MessageBox, 0, CTEXT(“我发送了WM_CopyData到接收端”),CTEXT(“信息”),0
    .endif
    .endif
    .elseif eax == WM_CLOSE
    invoke DestroyWindow,hwnd
    invoke PostQuitMessage,0
    .else
    invoke DefWindowProc,hwnd,msg,wParam,lParam
    ret
    .endif
    xor eax,eax
    ret
    _CallWnd    endp

通过这个小程序学不到以下几点,感觉不错呵呵:

1.提高手写Asm代码的熟练程序,除了查看一下WNDCLASS的几个结构成员的名子外,在不查考其他什么资料的情况下,已经能将Win32 SDK框架窗口代码写出来了。为了提高手写熟练的锻练我暂时停用Aogo MASMPlus了,改用SlickEdit进行手写。等熟练后再使用MasmPlus,这是个很不错的工具。

2.让我明白原来窗口程序和对话框程序有很大的不同,比如CreateWindowsEx建立窗口程序,就不执行WM_InitDIALOG这个消息。这一点让大牛老K同志狠狠BS了一顿,失败。做Windows程序这么多年了,居然这一点还不知道。

3.在ASM中写子程序总是忘记在最后ret,总是让程序给跑飞了。这个问题上一次就吃过苦了。还是老忘记,都者写惯了C/C++的结果,希望下次不要再出现。

4.明白了结构在ASM中两表示方式。参见接收端的CallBack。

5.PostMessage是不能进行WM_COPYDATA进行数据共享的。

作者:lonkil | 分类目录:编程开发 | 标签:

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>