找回密码
 加入
搜索
查看: 16530|回复: 25

[AU3基础] 请教大家,进程消息传递的数据,如何超过1000[已解决]

 火... [复制链接]
发表于 2011-2-6 00:07:26 | 显示全部楼层 |阅读模式
本帖最后由 itljl 于 2011-2-18 11:57 编辑

请教大家,进程消息传递的数据,如何超过1000

在下面的代码中,第3,9,19分别有一个数值1000,用来决定传递消息字节的大小,如何改为10000呢?
我直接改这三个值为10000后(我的实际需要是10000-20000),出现内存错误,请高手指正.

另外,如果有空懂的兄弟,请简单讲一下这个代码示例中的数据结构是怎么一会事?
看起来想是一个变量的矩阵?和数组有一定的相似?

代码为程序之间数据共享传递用的.另,AU3中,似乎还没有人写过以内存共享的方式来实现多个程序间数据共享.
Func _Process_Msg_Send($Message)
        $hwnd = WinGetHandle('Process_Msg')
        $struct = DllStructCreate('wchar 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)
EndFunc   ;==>_Process_Msg_Send

Func _Process_Msg_Rec($hwnd, $iMsg, $iwParam, $ilParam)
        $a = DllStructCreate('dword var1;dword var2;ptr var3', $ilParam)
        $b = DllStructGetData($a, 3)
        $c = DllStructCreate('wchar var1[1000]', $b)
        $d = DllStructGetData($c, 1)        
        _Process_Msg_process($d)
EndFunc   ;==>_Process_Msg_Rec
发表于 2011-2-6 00:42:40 | 显示全部楼层
请公开原来的指针结构.另外0x4A是什么?vk_j?
发表于 2011-2-6 06:35:47 | 显示全部楼层
回复 2# ceoguang


WM_copydata
发表于 2011-2-6 06:38:47 | 显示全部楼层
WM_copydata不是用来传递大量数据的,建议楼主换个。其他方法参考进程间通讯。
发表于 2011-2-6 14:54:51 | 显示全部楼层
分多次传
并加个是否结束的记号
发表于 2011-2-7 09:30:53 | 显示全部楼层
本帖最后由 ceoguang 于 2011-2-7 10:16 编辑
回复  ceoguang


WM_copydata
republican 发表于 2011-2-6 06:35

谢谢.
我明白楼主的意思了,下面这个是动态调整的.同样是WM_COPYDATA

代码:
#NoTrayIcon

Opt("GUIOnEventMode", 1)
Opt("GUIResizeMode", 1)

Global Const $WM_COPYDATA = 0x004A
Global Const $WM_NULL = 0x0000
Global Const $WM_GETTEXTLENGTH = 0x000E
Global Const $EM_REPLACESEL = 0xC2
Global Const $EM_SETSEL = 0xB1

Global Const $tagCOPYDATASTRUCT = "dword dwData;dword cbData;ptr lpData;"

;http://msdn.microsoft.com/en-us/library/ms649010
#cs
        typedef struct tagCOPYDATASTRUCT {
        ULONG_PTR dwData;
        DWORD     cbData;
        PVOID     lpData;
        } COPYDATASTRUCT, *PCOPYDATASTRUCT;
#ce

Global $Mark = Random(1024, 65535, 1) ;广播的标识

$Form1 = GUICreate("进程通讯示例", 484, 351, -1, -1, -2133917696);$GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX
GUISetOnEvent(-3, "_GuiEvent")
$Edit1 = GUICtrlCreateEdit("", 8, 8, 465, 209)
GUICtrlSetLimit(-1, 1e8)
GUICtrlSetResizing(-1, 102)
$Edit2 = GUICtrlCreateEdit("", 8, 225, 465, 81)
GUICtrlSetResizing(-1, 582)
$Button1 = GUICtrlCreateButton("发送", 200, 318, 75, 25)
GUICtrlSetOnEvent(-1, "_GuiEvent")
GUICtrlSetResizing(-1, 840)
GUISetState()
GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA")
GUIRegisterMsg($WM_NULL, "WM_NULL")
#EndRegion ### END Koda GUI section ###
Global $Target
Local $Count = 0
Broadcast_Msg()
While 1
        Sleep(100)
        $Count += 1
        If $Count = 100 Then ;10秒钟.
                $Count = 0
                If Not IsWindow($Target) Then Broadcast_Msg() ;向系统广播
        EndIf
WEnd

Func _GuiEvent()
        Switch @GUI_CtrlId
                Case -3
                        Exit
                Case $Button1
                        If GUICtrlRead($Edit2) <> "" Then
                                If IsWindow($Target) Then
                                        _SendProcessMsg($Target, GUICtrlRead($Edit2))
                                        If @extended Then
                                                $iLength = _SendMessageTimeout(GUICtrlGetHandle($Edit1), $WM_GETTEXTLENGTH) ;发送消息获取$Edit1的字节
                                                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_SETSEL, $iLength, $iLength) ;将焦点定位到最后
                                                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_REPLACESEL, True, "<<发送到进程: (" & WinGetProcess($Target) & ") 的消息 " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF & GUICtrlRead($Edit2) & @CRLF & @CRLF, 0, "wparam", "wstr") ;向$Edit1焦点处写入收到的消息
                                                GUICtrlSetData($Edit2, "")
                                        Else
                                                MsgBox(48, "", "消息发送失败", -1, $Form1)
                                        EndIf

                                Else
                                        MsgBox(48, "", "找不到接收进程!", -1, $Form1)
                                EndIf
                        Else
                                MsgBox(48, "", "请输入要发送的内容!", -1, $Form1)
                        EndIf
        EndSwitch
EndFunc   ;==>_GuiEvent

Func WM_COPYDATA($hWnd, $iMsg, $iwParam, $ilParam)
        Local $iBuffer = DllStructCreate($tagCOPYDATASTRUCT, $ilParam)
        Local $tBuffer, $iLength, $RecMsg
        If DllStructGetData($iBuffer, "dwData") = 0x01234567 Then
                $tBuffer = DllStructCreate("wchar[" & DllStructGetData($iBuffer, 'cbData') & "]", DllStructGetData($iBuffer, 'lpData')) ;cbData保存着数据的大小,lpData接收到的数据,其值可以为空
                $RecMsg = DllStructGetData($tBuffer, 1)
                $Target = $iwParam ;保存当前对话者的句柄
                $iLength = _SendMessageTimeout(GUICtrlGetHandle($Edit1), $WM_GETTEXTLENGTH) ;发送消息获取$Edit1的字节
                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_SETSEL, $iLength, $iLength) ;将焦点定位到最后
                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_REPLACESEL, True, ">>收到消息类型 (" & $iMsg & ") 来自进程: (" & WinGetProcess($Target) & ") " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF & $RecMsg & @CRLF & @CRLF, 0, "wparam", "wstr") ;向$Edit1焦点处写入收到的消息
        EndIf
        Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_COPYDATA

Func WM_NULL($hWnd, $iMsg, $iwParam, $ilParam)
        Local $iLength
        If $ilParam <> $Mark Then
                MsgBox(64, "收到消息", "目标句柄: " & $iwParam, -1, $Form1);挂起线程,终止消息传递
                _SendProcessMsg($iwParam, "欢迎")
                $iLength = _SendMessageTimeout(GUICtrlGetHandle($Edit1), $WM_GETTEXTLENGTH)
                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_SETSEL, $iLength, $iLength)
                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_REPLACESEL, True, ">>HWND (" & $iwParam & ") Process: (" & WinGetProcess($iwParam) & ") Msg: (" & $iMsg & ") " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF, 0, "wparam", "wstr")
        EndIf
        Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_NULL

Func Broadcast_Msg()
        _SendMessageTimeout(0xFFFF, $WM_NULL, $Form1, $Mark)
        $iLength = _SendMessageTimeout(GUICtrlGetHandle($Edit1), $WM_GETTEXTLENGTH)
        _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_SETSEL, $iLength, $iLength)
        _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_REPLACESEL, True, "<<广播WM_NULL信息 " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF, 0, "wparam", "wstr")
EndFunc   ;==>Broadcast_Msg

Func _SendProcessMsg($hWnd, $sMsg)
        ;$hWnd: 目标进程的主窗口句柄
        ;$sMsg: 要发送的消息内容
        Local $sBuffer = DllStructCreate("wchar[" & StringLen($sMsg) + 1 & "]")
        Local $tBuffer = DllStructCreate($tagCOPYDATASTRUCT)
        Local $pBuffer = DllStructGetPtr($tBuffer)
        DllStructSetData($sBuffer, 1, $sMsg)
        DllStructSetData($tBuffer, "dwData", 0x01234567) ;标识。这个数值可以随意定。
        DllStructSetData($tBuffer, "cbData", DllStructGetSize($sBuffer)) ;数据大小
        DllStructSetData($tBuffer, "lpData", DllStructGetPtr($sBuffer)) ;发送的数据
        _SendMessageTimeout($hWnd, $WM_COPYDATA, $Form1, $pBuffer)
        ;对应消息函数的($hWnd, $iMsg, $iwParam, $ilParam)
        ;这里使用SendMessageTimeout是为了防止因目标线程繁忙或挂起导致返回时间过长(或无返回)从而导致当前调用的线程挂起(不再向下执行),当然你可以使用PostMessage,但PostMessage是没有结果返回的.
        Return SetExtended(@extended)
EndFunc   ;==>_SendProcessMsg

Func _SendMessageTimeout($hWnd, $iMsg, $wparam = 0, $lparam = 0, $iReturn = 0, $wParamType = "wparam", $lParamType = "lparam", $sReturnType = "lresult", $iTimeout = 1000, $iFlags = 3)
        ;这个参数结构是根据封装好的_SendMessage修改而来.可以完全替换_SendMessage.默认超时设置$iTimeout = 1000(单位毫秒),$iFlags是(SMTO_BLOCK , SMTO_ABORTIFHUNG)的组合
        ;http://msdn.microsoft.com/en-us/library/ms644952(VS.85).aspx
        Local $Ret = DllCall("user32.dll", $sReturnType, "SendMessageTimeoutW", "hwnd", $hWnd, "uint", $iMsg, $wParamType, $wparam, $lParamType, $lparam, "uint", $iFlags, "uint", $iTimeout, "dword_ptr*", $iReturn)
        If (@error) Or (Not $Ret[0]) Then
                Return SetError(1, 0, "")
        EndIf
        Return SetError(0, 1, $Ret[7])
EndFunc   ;==>_SendMessageTimeout

Func IsWindow($hWnd)
        Local $aResult = DllCall("user32.dll", "bool", "IsWindow", "hwnd", $hWnd)
        If @error Then Return SetError(@error, @extended, 0)
        Return $aResult[0]
EndFunc   ;==>IsWindow

本帖子中包含更多资源

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

×
 楼主| 发表于 2011-2-7 14:56:02 | 显示全部楼层
回复 7# ceoguang


    谢谢版主,果然很强大, 我测试后再反馈
发表于 2011-2-7 16:09:56 | 显示全部楼层
进程间通信要满足两个条件的,一是数据共享,二是线程同步。如果不加入同步机制,就必须要在一个循环中实时判断是否有数据传了过来,或者是否需要将数据发送出去,浪费资源,也浪费效率。

这个内存映射的帖子就是通过共享内存区实现进程通信的。1#的代码没有同步,10#的代码加入了同步,同是用SendMessage函数调用窗口过程的。

说到进程通信,最著名的方法大概就是调用SendMessage调用目标进程的窗口过程了,这种方法既能共享数据,也有线程同步(因为 窗口过程 本身就是一个回调函数)。

总结了一下,进程通信大概包含(但不限于)以下这些方法:

1、SendMessage
2、临时文件(磁盘文件、注册表、环境变量)
3、Socket
4、事件、互斥体、信号量
5、共享内存区
6、本地过程调用(LPC)
7、快速本地过程调用(Quick LPC)


最著名,最常用的是第1种方法SendMessage。
2、5只能传递数据,没有同步。
4、7只有同步,不能传递数据。
1、3、6是正宗的通信方法,其中第6种方法是最快的。

若只看线程同步,最高效的是第7种。若只看共享数据,最高效的是第5种。
 楼主| 发表于 2011-2-7 16:19:31 | 显示全部楼层
回复 7# ceoguang

发送以下消息就失败了

111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|====111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|====111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|====111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|====111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|====111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|====111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|====111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|====111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|====111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|111.111.111.111|====
 楼主| 发表于 2011-2-7 16:27:01 | 显示全部楼层
回复 9# pusofalse


    请问P版,内存共享可以是一个数组吗?
如A.exe中的
$arr1
与B.exe中的
$arr1
同一个数组,任意一个程序中变化,另一个程序就变化了,并且,有个消息通知程序,这个变化了。
 楼主| 发表于 2011-2-7 16:29:27 | 显示全部楼层
回复 9# pusofalse


   P版能不能写个你的源码的示例:

ShareMemory.au3 (3.13 KB)

http://www.autoitx.com/forum.php ... 4%E6%2B%C8%A1%CA%FD
10楼
发表于 2011-2-8 00:22:29 | 显示全部楼层
本帖最后由 ceoguang 于 2011-2-8 06:48 编辑
回复  ceoguang

发送以下消息就失败了

111.111.111.111|111.111.111.111|111.111.111.111|111.111.1 ...
itljl 发表于 2011-2-7 16:19

SendMessage跨进程时LPARAM不能超过32位本身.最后测试了一下,原来是宽字符的问题,修改了一下,转换成单字符.总算能达到了32位的最大限制.


#NoTrayIcon

Opt("GUIOnEventMode", 1)
Opt("GUIResizeMode", 1)

Global Const $WM_COPYDATA = 0x004A
Global Const $WM_NULL = 0x0000
Global Const $WM_GETTEXTLENGTH = 0x000E
Global Const $EM_REPLACESEL = 0xC2
Global Const $EM_SETSEL = 0xB1

Global Const $tagCOPYDATASTRUCT = "dword dwData;dword cbData;ptr lpData;"

;http://msdn.microsoft.com/en-us/library/ms649010
#cs
        typedef struct tagCOPYDATASTRUCT {
        ULONG_PTR dwData;
        DWORD     cbData;
        PVOID     lpData;
        } COPYDATASTRUCT, *PCOPYDATASTRUCT;
#ce

Global $Mark = Random(1024, 65535, 1) ;广播的标识

$Form1 = GUICreate("进程通讯示例", 484, 351, -1, -1, -2133917696);$GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX
GUISetOnEvent(-3, "_GuiEvent")
$Edit1 = GUICtrlCreateEdit("", 8, 8, 465, 209)
GUICtrlSetLimit(-1, 1e8)
GUICtrlSetResizing(-1, 102)
$Edit2 = GUICtrlCreateEdit("", 8, 225, 465, 81)
GUICtrlSetResizing(-1, 582)
GUICtrlSetLimit(-1, 1e8)
$Button1 = GUICtrlCreateButton("发送", 200, 318, 75, 25)
GUICtrlSetOnEvent(-1, "_GuiEvent")
GUICtrlSetResizing(-1, 840)
GUISetState()
GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA")
GUIRegisterMsg($WM_NULL, "WM_NULL")
#EndRegion ### END Koda GUI section ###
Global $Target
Local $Count = 0
Broadcast_Msg()
While 1
        Sleep(100)
        $Count += 1
        If $Count = 100 Then ;10秒钟.
                $Count = 0
                If Not IsWindow($Target) Then Broadcast_Msg() ;向系统广播
        EndIf
WEnd

Func _GuiEvent()
        Switch @GUI_CtrlId
                Case -3
                        Exit
                Case $Button1
                        If GUICtrlRead($Edit2) <> "" Then
                                If IsWindow($Target) Then
                                        _SendProcessMsg($Target, GUICtrlRead($Edit2))
                                        If @extended Then
                                                $iLength = _SendMessageTimeout(GUICtrlGetHandle($Edit1), $WM_GETTEXTLENGTH) ;发送消息获取$Edit1的字节
                                                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_SETSEL, $iLength, $iLength) ;将焦点定位到最后
                                                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_REPLACESEL, True, "<<发送到进程: (" & WinGetProcess($Target) & ") 的消息 " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF & GUICtrlRead($Edit2) & @CRLF & @CRLF, 0, "wparam", "wstr") ;向$Edit1焦点处写入收到的消息
                                                GUICtrlSetData($Edit2, "")
                                        Else
                                                MsgBox(48, "", "消息发送失败", -1, $Form1)
                                        EndIf

                                Else
                                        MsgBox(48, "", "找不到接收进程!", -1, $Form1)
                                EndIf
                        Else
                                MsgBox(48, "", "请输入要发送的内容!", -1, $Form1)
                        EndIf
        EndSwitch
EndFunc   ;==>_GuiEvent

Func WM_COPYDATA($hWnd, $iMsg, $iwParam, $ilParam)
        Local $iBuffer = DllStructCreate($tagCOPYDATASTRUCT, $ilParam)
        Local $tBuffer, $iLength, $RecMsg
        If DllStructGetData($iBuffer, "dwData") = 0x01234567 Then
                $tBuffer = DllStructCreate("char[" & DllStructGetData($iBuffer, 'cbData') & "]", DllStructGetData($iBuffer, 'lpData')) ;cbData保存着数据的大小,lpData接收到的数据,其值可以为空
                $RecMsg = BinaryToString(DllStructGetData($tBuffer, 1))
                $Target = $iwParam ;保存当前对话者的句柄
                $iLength = _SendMessageTimeout(GUICtrlGetHandle($Edit1), $WM_GETTEXTLENGTH) ;发送消息获取$Edit1的字节
                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_SETSEL, $iLength, $iLength) ;将焦点定位到最后
                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_REPLACESEL, True, ">>收到消息类型 (" & $iMsg & ") 来自进程: (" & WinGetProcess($Target) & ") " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF & $RecMsg & @CRLF & @CRLF, 0, "wparam", "wstr") ;向$Edit1焦点处写入收到的消息
        EndIf
        Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_COPYDATA

Func WM_NULL($hWnd, $iMsg, $iwParam, $ilParam)
        Local $iLength
        If $ilParam <> $Mark Then
                MsgBox(64, "收到消息", "目标句柄: " & $iwParam, -1, $Form1);挂起线程,终止消息传递
                _SendProcessMsg($iwParam, "欢迎")
                $iLength = _SendMessageTimeout(GUICtrlGetHandle($Edit1), $WM_GETTEXTLENGTH)
                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_SETSEL, $iLength, $iLength)
                _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_REPLACESEL, True, ">>HWND (" & $iwParam & ") Process: (" & WinGetProcess($iwParam) & ") Msg: (" & $iMsg & ") " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF, 0, "wparam", "wstr")
        EndIf
        Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_NULL

Func Broadcast_Msg()
        _SendMessageTimeout(0xFFFF, $WM_NULL, $Form1, $Mark)
        $iLength = _SendMessageTimeout(GUICtrlGetHandle($Edit1), $WM_GETTEXTLENGTH)
        _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_SETSEL, $iLength, $iLength)
        _SendMessageTimeout(GUICtrlGetHandle($Edit1), $EM_REPLACESEL, True, "<<广播WM_NULL信息 " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF, 0, "wparam", "wstr")
EndFunc   ;==>Broadcast_Msg

Func _SendProcessMsg($hWnd, $sMsg)
        ;$hWnd: 目标进程的主窗口句柄
        ;$sMsg: 要发送的消息内容
        Local $sBuffer = DllStructCreate("char[" & StringLen(StringToBinary($sMsg)) + 1 & "]")
        Local $tBuffer = DllStructCreate($tagCOPYDATASTRUCT)
        Local $pBuffer = DllStructGetPtr($tBuffer)
        Local $StrLen
        DllStructSetData($sBuffer, 1, StringToBinary($sMsg))
        DllStructSetData($tBuffer, "dwData", 0x01234567) ;标识。这个数值可以随意定。
        $StrLen = DllStructGetSize($sBuffer)
        If $StrLen > 2 ^ 32 - 1 Then
                MsgBox(16, "", "消息内容超出lParam限制", -1, $hWnd)
                Return SetError(1, 0)
        EndIf
        DllStructSetData($tBuffer, "cbData", $StrLen) ;数据大小
        DllStructSetData($tBuffer, "lpData", DllStructGetPtr($sBuffer)) ;发送的数据
        _SendMessageTimeout($hWnd, $WM_COPYDATA, $Form1, $pBuffer)
        ;对应消息函数的($hWnd, $iMsg, $iwParam, $ilParam)
        ;这里使用SendMessageTimeout是为了防止因目标线程繁忙或挂起导致返回时间过长(或无返回)从而导致当前调用的线程挂起(不再向下执行),当然你可以使用PostMessage,但PostMessage是没有结果返回的.
        Return SetExtended(@extended)
EndFunc   ;==>_SendProcessMsg

Func _SendMessageTimeout($hWnd, $iMsg, $wparam = 0, $lparam = 0, $iReturn = 0, $wParamType = "wparam", $lParamType = "lparam", $sReturnType = "lresult", $iTimeout = 1000, $iFlags = 3)
        ;这个参数结构是根据封装好的_SendMessage修改而来.可以完全替换_SendMessage.默认超时设置$iTimeout = 1000(单位毫秒),$iFlags是(SMTO_BLOCK , SMTO_ABORTIFHUNG)的组合
        ;http://msdn.microsoft.com/en-us/library/ms644952(VS.85).aspx
        Local $Ret = DllCall("user32.dll", $sReturnType, "SendMessageTimeoutW", "hwnd", $hWnd, "uint", $iMsg, $wParamType, $wparam, $lParamType, $lparam, "uint", $iFlags, "uint", $iTimeout, "dword_ptr*", $iReturn)
        If (@error) Or (Not $Ret[0]) Then
                Return SetError(1, 0, "")
        EndIf
        Return SetError(0, 1, $Ret[7])
EndFunc   ;==>_SendMessageTimeout

Func IsWindow($hWnd)
        Local $aResult = DllCall("user32.dll", "bool", "IsWindow", "hwnd", $hWnd)
        If @error Then Return SetError(@error, @extended, 0)
        Return $aResult[0]
EndFunc   ;==>IsWindow


回复  pusofalse
    请问P版,内存共享可以是一个数组吗?
如A.exe中的
$arr1
与B.exe中的
$arr ...
itljl 发表于 2011-2-7 16:27

首先你得去了解CreateProcess的工作过程.
但是对于autoit而言这些都是白费力.因为你很难找到所谓的变量地址.真正要这样做的话必须调用汇编来实现.
回复  pusofalse


   P版能不能写个你的源码的示例:

ShareMemory.au3 (3.13 KB)


10楼
itljl 发表于 2011-2-7 16:29

这个UDF仅仅是使用读写及关闭部份.
要实现全功能,还得添加两个步骤.
1.创建内核对象.(createfile)
2.创建文件映射对象(createfilemapping)

本帖子中包含更多资源

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

×

评分

参与人数 1金钱 +10 收起 理由
itljl + 10 谢谢。

查看全部评分

发表于 2011-2-8 01:13:02 | 显示全部楼层
回复 13# ceoguang


    那个ShareMemory.au3是调用了Ntdll.NtCreateSection来创建文件映射对象的,实际Kernel32.CreateFileMapping也是调用了这个函数。要在进程间共享数据根本不必调用CreateFile函数获取文件句柄,映射中的文件句柄只有在加载映像文件时才会用到,当然,如果共享的内容来源于某个文件的话,使用此方法就不必再次调用ReadFile读取了。
发表于 2011-2-8 01:24:20 | 显示全部楼层
好好学习。。
发表于 2011-2-8 01:46:14 | 显示全部楼层
回复  ceoguang


    那个ShareMemory.au3是调用了Ntdll.NtCreateSection来创建文件映射对象的,实际K ...
pusofalse 发表于 2011-2-8 01:13

不好意思,我太菜了.
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-16 21:14 , Processed in 0.085219 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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