| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 704 人关注过本帖, 1 人收藏
标题:用sendmessage发送自定义消息给特定窗口
取消只看楼主 加入收藏
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1300
注 册:2021-10-13
结帖率:97.18%
收藏(1)
已结贴  问题点数:20 回复次数:3 
用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
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1300
注 册: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
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1300
注 册: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
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1300
注 册:2021-10-13
收藏
得分:0 
回复 9楼 sych


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



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

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