| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 617 人关注过本帖, 1 人收藏
标题:用sendmessage发送自定义消息给特定窗口
只看楼主 加入收藏
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:805
专家分:1231
注 册:2021-10-13
结帖率:96.83%
收藏(1)
已结贴  问题点数:20 回复次数:10 
用sendmessage发送自定义消息给特定窗口
我们要怎样用sendmessage(或postmessage)来发送自定义消息给特定的窗口,来实现类似socket的功能?

查阅了好多资料,终于摸索出来用sendmessage来模拟winsocket的聊天功能。。。
在此感谢@sych!

代码分享如下:
程序代码:
server_demo=NEWOBJECT([form1])
server_demo.show


 
*!*    RETURN

**************************************************
*-- Form:         form1 (d:\documents\visual foxpro 项目\server_demo.scx)
*-- 父类:  form
*-- 基类:    form
*-- 时间戳:   08/13/24 08:34:02 PM
*
DEFINE CLASS form1 AS form


    DoCreate = .T.
    Caption = "Server_demo"
    target = 0
    Name = "form1"


    ADD OBJECT text1 AS textbox WITH ;
        Height = 20, ;
        Left = 0, ;
        Top = 2, ;
        Width = 100, ;
        Name = "Text1"


    ADD OBJECT command1 AS commandbutton WITH ;
        Top = 0, ;
        Left = 108, ;
        Height = 25, ;
        Width = 60, ;
        Caption = "\<Send", ;
        Name = "Command1"


    ADD OBJECT edit1 AS editbox WITH ;
        Height = 224, ;
        Left = 0, ;
        Top = 24, ;
        Width = 372, ;
        Name = "Edit1"


    PROCEDURE callback
        PARAMETERS nhwnd,nmsg,nparam,lparam
        IF nmsg=0x401 &&Windows为我们预留的自定义消息代码
            MESSAGEBOX(this.Caption +[ data arrival!])
            *************************************************************
            **********不知道具体收到多少个字节,只好一个个检测***********
            *********所幸windows规定发送的字符串以字符chr(0)结尾*********
            *********不知道有没有其他办法来获得指定地址的文字数?*********
            i=0
            DO WHILE .t.
                c=SYS(2600,lparam+i,1)
                IF c=CHR(0)
                    n=i
                    exit
                ELSE
                    i=i+1
                    loop
                ENDIF
            enddo
            this.eDIT1.Value=this.edit1.value+TRANSFORM(TIME())+[ Recieved: ]+SYS(2600,lparam,n)+CHR(13)
        ENDIF

    ENDPROC


    PROCEDURE queryunload
        CLEAR EVENTS 
    ENDPROC
    

    PROCEDURE Activate
        *!*    IF VARTYPE(m.client_demo)="O" AND !ISNULL(m.client_demo)
        *!*    IF VARTYPE(m.client_demo)="X"
        IF VARTYPE(client_demo)="U"
            client_demo=NEWOBJECT([form2])
            client_demo.show
            this.target=m.client_demo.hwnd
            BINDEVENT(this.target,0x401,m.client_demo,"callback")
        ENDIF
        READ EVENTS
    ENDPROC


    PROCEDURE Init
        DECLARE inte SendMessage IN WIN32API integer,integer,integer,string
    ENDPROC


    PROCEDURE command1.Click
        IF !EMPTY(thisform.text1.value)
            n=sendmessage(thisform.target,0x401,0,thisform.text1.Value)
            MESSAGEBOX(TRANSFORM(n))
            thisform.edit1.Value=thisform.edit1.Value+TRANSFORM(TIME())+[ Send: ]+thisform.text1.Value+CHR(13)
            thisform.text1.Value=''
        ENDIF

    ENDPROC


ENDDEFINE
*
*-- EndDefine: form1
**************************************************
    **************************************************
*-- Form:         form2 (d:\documents\visual foxpro 项目\client_demo.scx)
*-- 父类:  form
*-- 基类:    form
*-- 时间戳:   08/13/24 08:39:07 PM
*
DEFINE CLASS form2 AS form


    DoCreate = .T.
    Caption = "Client_demo"
    target = 0
    Name = "form2"
    autocenter=.t.


    ADD OBJECT text1 AS textbox WITH ;
        Height = 20, ;
        Left = 0, ;
        Top = 2, ;
        Width = 100, ;
        Name = "Text1"


    ADD OBJECT command1 AS commandbutton WITH ;
        Top = 0, ;
        Left = 108, ;
        Height = 25, ;
        Width = 60, ;
        Caption = "\<Send", ;
        Name = "Command1"


    ADD OBJECT edit1 AS editbox WITH ;
        Height = 224, ;
        Left = 0, ;
        Top = 24, ;
        Width = 372, ;
        Name = "Edit1"


    PROCEDURE callback
        PARAMETERS nhwnd,nmsg,nparam,lparam
        IF nmsg=0x401
            MESSAGEBOX(this.caption+[ data arrival!])
            *************************************************************
            **********不知道具体收到多少个字节,只好一个个检测***********
            *********所幸windows规定发送的字符串以字符chr(0)结尾*********
            i=0
            DO WHILE .t.
                c=SYS(2600,lparam+i,1)
                IF c=CHR(0)
                    n=i
                    exit
                ELSE
                    i=i+1
                    loop
                ENDIF
            enddo
            this.eDIT1.Value=this.edit1.value+TRANSFORM(TIME())+[ Received: ]+SYS(2600,lparam,n)+CHR(13)
        ENDIF

    ENDPROC


    PROCEDURE Unload
        CLEAR EVENTS 
        IF vart(m.server_demo)="O"
            m.server_demo.release
        ENDIF

    ENDPROC


    PROCEDURE Init
        DECLARE inte SendMessage IN WIN32API integer,integer,integer,string
        IF VARTYPE(m.server_demo)!="O" OR ISNULL(m.server_demo)
            MESSAGEBOX([Pls run server_demo at first!])
            RETURN .f.
        ELSE
            this.target=m.server_demo.HWnd
        ENDIF

        BINDEVENT(this.target,0x401,m.server_demo,"callback")
    ENDPROC


    PROCEDURE command1.Click
        IF !EMPTY(thisform.text1.value)
            sendmessage(thisform.target,0x401,0,thisform.text1.Value)
            thisform.edit1.Value=thisform.edit1.Value+TRANSFORM(TIME())+[ Send: ]+thisform.text1.Value+CHR(13)
            thisform.text1.Value=''
        ENDIF

    ENDPROC


ENDDEFINE
*
*-- EndDefine: form2
**************************************************



[此贴子已经被作者于2024-8-18 19:53编辑过]

搜索更多相关主题的帖子: Value IF text1 this thisform 
2024-08-12 16:54
sych
Rank: 6Rank: 6
等 级:侠之大者
威 望:7
帖 子:322
专家分:450
注 册:2019-10-11
收藏
得分:20 
DECLARE Integer SendMessageTimeout IN user32 ;
    Integer hwnd , ;
    Integer msg , ;
    Integer wParam , ;
    string @lParam , ;
    Integer fuFlags , ;
    Integer uTimeout , ;
    long @
    DECLARE INTEGER GlobalAlloc IN win32api INTEGER uFlags, INTEGER dwBytes
    DECLARE INTEGER GlobalLock IN win32api  INTEGER hMem
    DECLARE INTEGER GlobalSize IN win32api   INTEGER hMem
    DECLARE INTEGER GlobalUnlock IN win32api  INTEGER hMem
    DECLARE INTEGER GlobalFree IN win32api    INTEGER hMem
    mzfc="发送字符串"
    MemHandle = GlobalAlloc(0,LEN(mzfc))
    = GlobalLock(MemHandle)
    =SYS(2600,MemHandle,LEN(mzfc),mZFC)
    mzfc=REPLICATE(CHR(0),4)+BINTOC(LEN(mzfc),"4rs")+BINTOC(m.MemHandle,"4rs")
    LRES=0
    =SendMessageTimeout(VAL(FILETOSTR("c:\hwnd.txt")), 0x4a, 0, @mzfc,2,1000, @lRes)
    GlobalUnlock(MemHandle)
    GlobalFree(MemHandle)


[此贴子已经被作者于2024-8-13 07:11编辑过]

2024-08-13 06:52
sych
Rank: 6Rank: 6
等 级:侠之大者
威 望:7
帖 子:322
专家分:450
注 册:2019-10-11
收藏
得分:0 
SET SAFETY off
oform1=NEWOBJECT("form1")
susp
RETURN
DEFINE CLASS form1 AS form
    PROCEDURE Init
        =BINDEVENT(thisform.HWnd,0x4a,thisform,"mycopy")
        =STRTOFILE(transform(thisform.HWnd),"c:\hwnd.txt")
    ENDPROC
    PROCEDURE mycopy
        lPARAMETERS bb,cc,dd,ee
        lcBuffer=SYS(2600,EE,12)
        lcBuffer=SYS(2600,CTOBIN(SUBSTR(lcbuffer,9,4),"4rs"),CTOBIN(SUBSTR(lcbuffer,5,4),"4rs"))
        MESSAGEBOX(lcBuffer)
    ENDPROC
ENDDEFINE


[此贴子已经被作者于2024-8-13 07:10编辑过]

2024-08-13 06:52
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:805
专家分:1231
注 册:2021-10-13
收藏
得分:0 
虽然可以运行 mycopy没看懂啊
以下是引用sych在2024-8-13 06:52:40的发言:
SET SAFETY off
oform1=NEWOBJECT("form1")
susp
RETURN
DEFINE CLASS form1 AS form
    PROCEDURE Init
        =BINDEVENT(thisform.HWnd,0x4a,thisform,"mycopy")
        =STRTOFILE(transform(thisform.HWnd),"c:\hwnd.txt")
    ENDPROC
    PROCEDURE mycopy
        lPARAMETERS bb,cc,dd,ee &&这里4个参数只用到一个?
        lcBuffer=SYS(2600,EE,12) &&这里EE是什么? 传过来的mzfc字符串的地址吗?
        lcBuffer=SYS(2600,CTOBIN(SUBSTR(lcbuffer,9,4),"4rs"),CTOBIN(SUBSTR(lcbuffer,5,4),"4rs"))
        MESSAGEBOX(lcBuffer)
    ENDPROC
ENDDEFINE

2024-08-13 14:18
sych
Rank: 6Rank: 6
等 级:侠之大者
威 望:7
帖 子:322
专家分:450
注 册:2019-10-11
收藏
得分:0 
=SendMessageTimeout(VAL(FILETOSTR("c:\hwnd.txt")), 0x4a, 0, @mzfc,2,1000, @lRes)
bb,cc,dd,ee对应上面的4个参数

2024-08-13 17:48
easyppt
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:309
专家分:711
注 册:2021-11-24
收藏
得分:0 
涉及  4rs  的 函数 我也一直看不懂,我想这就是不懂C++,所以导致不懂底层的原理的缘故吧,也正因此,所以我们对 诸如内存共享及 4rs 相关的函数总是不会用

希望 版主们  指导一下,给些说明可以吗,不然确实无法理解,比如这句,能帮忙详细解释一下吗,谢谢:

mzfc=Replicate(Chr(0),4)+BinToC(Len(mzfc),"4rs")+BinToC(m.MemHandle,"4rs")

我能理解的是: mzfc 刚开始 是声明的 VFP普通字符串变量,内容是:mzfc="发送字符串"
未什么要执行 上面的一行处理呢? 上面一行里的 BinToC() 及 4rs,虽然看了VFP帮助文档,但还是不太不理解,恳请再详细解释一下!
而且发现 好多 与  WinAPI 交互的函数,似乎 都用到了 4rs  相关的函数。

BinToC()  帮助中说:将一个数字值转换成一个二进制字符表示。啥意思?
数字值 是否可以理解为10进制的值? 转换为 二进制字符,这个 二进制字符 是啥?
是把 十进制 转换为 二进制 的 字符串形式吗  这个 二进制字符  和进制转换 有关系吗? 比如 10进制 转换 为 2进制  



[此贴子已经被作者于2024-8-18 11:06编辑过]

2024-08-18 08:31
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:805
专家分:1231
注 册:2021-10-13
收藏
得分:0 
回复 6楼 easyppt
有个简便的理解,RS表示字符,4RS,就是4个字符;用字符来表示数字,可以有更大的压缩量,因为它是16进制的。
计算机中规定一个字节有8个位,每个位就是0和1组成,也就是说一个字节最小是0000 0000 &&chr(0x00),最大是1111 1111 &&chr(0xFF),就是说一个字节可以代表0-255之间的任何一个数字!
4个字节就是可以代表 0xffffffff, 10进制就是4294967295,用10进制需要10个字符,而16进制只需要4个字符。

比如:数字1,你可以用?transform(1,[@0])在命令窗口查看,就是0x00000031;字符A,就是0x00000041;
你可以在命令窗输入?LEN(BINTOC(65,[4rs]))&&4个字符,3个chr(0), 和一个A 和?LEN(BINTOC(65,[2rs])) &&一个chr(0)和一个字符A 来查看是几个字符。

mzfc=Replicate(Chr(0),4)+BinToC(Len(mzfc),"4rs")+BinToC(m.MemHandle,"4rs")

Replicate(Chr(0),4) &&4个chr(0)
BinToC(Len(mzfc),"4rs") &&字符串mzfc的长度,转换位4个字符的表达式
BinToC(m.MemHandle,"4rs") &&mzfc内存地址的4个字符表达式
合计12个字符

我就是这样理解的,好像管用
2024-08-18 20:48
easyppt
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:309
专家分:711
注 册:2021-11-24
收藏
得分:0 
太感谢:sam_jiang 了!
解释的非常详细,也易于理解,我好好消化消化!!

2024-08-18 23:06
sych
Rank: 6Rank: 6
等 级:侠之大者
威 望:7
帖 子:322
专家分:450
注 册:2019-10-11
收藏
得分:0 
sendmessage(thisform.target,0x401,0,thisform.text1.Value)
改为
sendmessage(thisform.target,0x401,len(thisform.text1.Value),thisform.text1.Value)
那么callback的第三个参数nparam就是接收字符串的长度
PROCEDURE callback
        PARAMETERS nhwnd,nmsg,nparam,lparam
        IF nmsg=0x401
            MESSAGEBOX(this.caption+[ data arrival!])
            this.eDIT1.Value=this.edit1.value+TRANSFORM(TIME())+[ Received: ]+SYS(2600,lparam,nparam)+CHR(13)
        ENDIF

    ENDPROC
2024-08-22 17:03
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:805
专家分:1231
注 册:2021-10-13
收藏
得分:0 
回复 9楼 sych


受教了,谢谢!
2024-08-22 19:49
快速回复:用sendmessage发送自定义消息给特定窗口
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.031670 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved