找回密码
 加入
搜索
查看: 5048|回复: 11

[AU3基础] [已解决]DllStructCreate "char"该如何转变为"wchar" (例子)

  [复制链接]
发表于 2010-9-18 09:17:50 | 显示全部楼层 |阅读模式
本帖最后由 republican 于 2010-9-18 22:33 编辑

整个例子是用WM_COPYDATA传输数据,不过只能传递char,单独修改为wchar后会有小问题。

这么做的目的是为了传递中文字符,而我对DllStruct之类的没什么研究,希望得到大家的帮忙,谢谢!


Parent.au3
#include <WindowsConstants.au3>

Global $hParent, $hChild, $received

; parent gui
$hParent = GUICreate("Parent", 300, 120, 100)
$input_send = GUICtrlCreateInput("", 10, 10, 280, 20)
$btn = GUICtrlCreateButton("SEND TO CHILD", 80, 35, 140, 20, 0x0001)
GUICtrlCreateLabel("RECEIVED FROM CHILD", 10, 75, 280, 20, 0x01)
$input_received = GUICtrlCreateInput("", 10, 90, 280, 20, 0x0800)
GUISetState(@SW_SHOW)

; launch child - trade handles
GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA_ReceiveData") ; register WM_COPYDATA
ShellExecute("child.exe", $hParent) ; start child process - send parent handle
While Not $received ; wait for child process to return it's handle
    Sleep(50)
WEnd
$hChild = HWnd($received); assign child hamdle
$received = ""

; main loop
While 1
    $msg = GUIGetMsg()
    If $msg = -3 Then ExitLoop
    If $msg = $btn Then WM_COPYDATA_SendData($hChild, GUICtrlRead($input_send)) ; send to child
    If $received Then
        GUICtrlSetData($input_received, $received) ; receive form child
        $received = ""
    EndIf
WEnd
ProcessClose("child.exe")
Exit

;===================================================================================================================================
Func WM_COPYDATA_ReceiveData($hWnd, $MsgID, $wParam, $lParam) ;
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr", $lParam)
    Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3))
    $received = DllStructGetData($tMsg, 1)
EndFunc

Func WM_COPYDATA_SendData($hWnd, $sData)
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr")
    Local $tMsg = DllStructCreate("char[" & StringLen($sData) + 1 & "]")
    DllStructSetData($tMsg, 1, $sData)
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
    $Ret = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWnd, "int", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA))
EndFunc
Child.au3
#NoTrayIcon
#include <WindowsConstants.au3>

Global $hParent, $hChild, $received

Global $hParent = HWnd($CmdLine[1]) ; get parent handle from commandline

; child gui
$hChild = GUICreate("Child", 300, 150, 440, Default, 0x00800000)
$input_send = GUICtrlCreateInput("", 10, 10, 280, 20)
$btn = GUICtrlCreateButton("SEND TO PARENT", 80, 35, 140, 20, 0x0001)
GUICtrlCreateLabel("RECEIVED FROM PARENT", 10, 75, 280, 20, 0x01)
$input_received = GUICtrlCreateInput("", 10, 90, 280, 20, 0x0800)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA_ReceiveData") ; register WM_COPYDATA
WM_COPYDATA_SendData($hParent, $hChild) ; return child handle to parent

; main loop
While 1
    $msg = GUIGetMsg()
    If $msg = $btn Then WM_COPYDATA_SendData($hParent, GUICtrlRead($input_send)) ; send to parent
    If $received Then
        GUICtrlSetData($input_received, $received) ; receive from parent
        $received = ""
    EndIf
WEnd
Exit

;===================================================================================================================================
Func WM_COPYDATA_ReceiveData($hWnd, $MsgID, $wParam, $lParam) ;
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr", $lParam)
    Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3))
    $received = DllStructGetData($tMsg, 1)
EndFunc

Func WM_COPYDATA_SendData($hWnd, $sData)
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr")
    Local $tMsg = DllStructCreate("char[" & StringLen($sData) + 1 & "]")
    DllStructSetData($tMsg, 1, $sData)
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
    $Ret = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWnd, "int", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA))
EndFunc
代码打包:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×

评分

参与人数 1金钱 +10 收起 理由
afan + 10 感谢主动将修改帖子分类为[已解决],请继续 ...

查看全部评分

 楼主| 发表于 2010-9-18 13:30:39 | 显示全部楼层
谢谢Afan!

以上例子如果不修改成wchar的话,可以通过转换为 二进制 传递中文。不过这么做代码就啰嗦了,还有二次转换的问题, 所以希望研究过的各位仁兄提供一下修改意见,谢谢!
发表于 2010-9-18 13:32:26 | 显示全部楼层
发送
#include <winapi.au3>
 
$hwnd = WinGetHandle('Msg_Catcher')
$message = StringToBinary('大家好才是真的好')
 
$struct = DllStructCreate('char var1[1000]')
DllStructSetData($Struct,1,$message)
$pStruct = DllStructGetPtr($struct)
 
$struct2 = DllStructCreate('dword;dword;ptr')
DllStructSetData($struct2,1,0)
DllStructSetData($struct2,2,1000)
DllStructSetData($struct2,3,$pStruct)
$pStruct2 = DllStructGetPtr($struct2)
 
_SendMessage($hwnd, 0x4A, 0, $pStruct2)


接收

#include <winapi.au3>
 
GUICreate('Msg_Catcher')
 
GUIRegisterMsg(0x4A, '_Func')
 
While 1
    Sleep(1000)
WEnd
 
Func _Func($hWnd, $iMsg, $iwParam, $ilParam)
 
$a = DllStructCreate('dword var1;dword var2;ptr var3', $ilParam)
    $b = DllStructGetData($a, 3)
    
    $c = DllStructCreate('char var1[1000]',$b)
    $d = DllStructGetData($c, 1)
    
    MsgBox(0, '接收', BinaryToString($d))
EndFunc

评分

参与人数 1金钱 +40 收起 理由
republican + 40 谢谢。 如果能改为wchar就更好了!

查看全部评分

发表于 2010-9-18 16:04:30 | 显示全部楼层
是字符长度计算的问题把...unicode

5个中文可以显示4个 stringlen算法有问题估计

评分

参与人数 1金钱 +40 收起 理由
republican + 40 谢谢,回去试试!

查看全部评分

发表于 2010-9-18 17:05:48 | 显示全部楼层
- -|||
直接把char改成wchar不就好了吗,接收端和发送端都要修改,相应的指明缓存区长度的第2个DWORD,也应该改成wchar所占的长度。
 楼主| 发表于 2010-9-18 21:00:01 | 显示全部楼层
回复 5# pusofalse

这个长度我换了许多值都没有正确结果,可以提示一下吗?
发表于 2010-9-18 22:15:07 | 显示全部楼层
回复 6# republican


    Send:
#include <winapi.au3>
 
$hWnd = WinGetHandle('Msg_Catcher')

$sString = "大家好才是真的好"
$iLength = StringLen($sString)

$tBuffer = DllStructCreate("dword;dword;ptr;wchar[" & $iLength + 1 & "]")
$pBuffer = DllStructGetPtr($tBuffer)

DllStructSetData($tBuffer, 2, $iLength * 2 + 2)
DllStructSetData($tBuffer, 3, $pBuffer + 12)
DllStructSetData($tBuffer, 4, $sString)

_SendMessage($hWnd, 0x4A, 0, $pBuffer)


Recv:
#include <winapi.au3>
 
GUICreate('Msg_Catcher')
 
GUIRegisterMsg(0x4A, '_Func')
 
While 1
    Sleep(1000)
WEnd
 
Func _Func($hWnd, $iMsg, $iwParam, $ilParam)
        Local $tBuffer, $pBuffer, $iLength, $tText

        $tBuffer = DllStructCreate("dword[2];ptr", $ilParam)
        $pBuffer = DllStructGetData($tBuffer, 2)
        $iLength = DllStructGetData($tBuffer, 1, 2) / 2

        $tText = DllStructCreate("wchar[" & $iLength & "]", $pBuffer)

        MsgBox(0, "", DllStructGetData($tText, 1))
EndFunc

评分

参与人数 1贡献 +5 收起 理由
afan + 5

查看全部评分

发表于 2010-9-18 22:19:02 | 显示全部楼层
本帖最后由 rolaka 于 2010-9-18 22:36 编辑
- -|||
直接把char改成wchar不就好了吗,接收端和发送端都要修改,相应的指明缓存区长度的第2个DWORD,也应 ...
pusofalse 发表于 2010-9-18 17:05


p版最近风格大变啊。。。

回复  pusofalse

这个长度我换了许多值都没有正确结果,可以提示一下吗?
republican 发表于 2010-9-18 21:00


win7下不能测试 xpmode里成功了- -

DllStructSetData($tCOPYDATA, 2, DllStructGetSize($tMsg));StringLen($sData) + 1)
 楼主| 发表于 2010-9-18 22:31:42 | 显示全部楼层
本帖最后由 republican 于 2010-9-18 22:42 编辑

回复 7# pusofalse

谢谢,解决了!!!

Func WM_COPYDATA_ReceiveData($hWnd, $MsgID, $wParam, $lParam) ;
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr", $lParam)
    Local $tMsg = DllStructCreate("wchar[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3))
    $received = DllStructGetData($tMsg, 1)
EndFunc

Func WM_COPYDATA_SendData($hWnd, $sData)
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr")
    Local $tMsg = DllStructCreate("wchar[" & StringLen($sData) + 1 & "]")
    DllStructSetData($tMsg, 1, $sData)
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) * 2 + 2)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
    $Ret = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWnd, "int", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA))
EndFunc
发表于 2010-9-18 22:38:19 | 显示全部楼层
本帖最后由 rolaka 于 2010-9-18 22:41 编辑
回复  pusofalse

谢谢,解决了!!!
republican 发表于 2010-9-18 22:31


我也贴下我的把...

Func WM_COPYDATA_ReceiveData($hWnd, $MsgID, $wParam, $lParam) ;
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr", $lParam)
    Local $tMsg = DllStructCreate("wchar[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3))
    $received = DllStructGetData($tMsg, 1)
EndFunc

Func WM_COPYDATA_SendData($hWnd, $sData)
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr")
    Local $tMsg = DllStructCreate("wchar[" & StringLen($sData) + 1 & "]")
    DllStructSetData($tMsg, 1, $sData)
    DllStructSetData($tCOPYDATA, 2, DllStructGetSize($tMsg));StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
    $Ret = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWnd, "int", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA))
EndFunc


引用的原帖地址: http://www.autoitscript.com/foru ... =1&#entry830524

评分

参与人数 2金钱 +20 贡献 +5 收起 理由
republican + 20
afan + 5

查看全部评分

 楼主| 发表于 2010-9-18 22:47:35 | 显示全部楼层
回复 10# rolaka

谢谢!!
 楼主| 发表于 2010-12-3 07:02:45 | 显示全部楼层
回复 10# rolaka
昨天才发现这个现象:
在64位系统下,需要这样创建结构:

Local $tCOPYDATA = DllStructCreate("ptr;dword;ptr")
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-19 16:21 , Processed in 0.081688 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表