Тема: AHK:WM_COPYDATA
Привет друзья. Помогите поймать сообщениее WM_COPYDATA со строкой из внешней программы. Я пишу под wince.
Если запустить sender, он пошлет сообщение для всех окон WM_COPYDATA со строкой hello. Если запустить listener, он получает сообщение и выводит строку.
Но на AHK сделать слушателя не получается, который мог бы принять эти сообщения.
Я пытался написать такой код:
Gui, +AlwaysOnTop
Gui, Add, Text, vtextv w400 h60
Gui, Show
StrGet(Address, Length=-1, Encoding=0)
{
if A_IsUnicode
{
MsgBox %A_ThisFunc% does not support Unicode. Use the AutoHotkey_L (revision 46+) built-in version instead. The script will now exit.
ExitApp
}
; Flexible parameter handling:
if Length is not integer
Encoding := Length, Length := -1
; Check for obvious errors.
if (Address+0 < 1024)
return
; Ensure 'Encoding' contains a numeric identifier.
if Encoding = UTF-16
Encoding = 1200
else if Encoding = UTF-8
Encoding = 65001
else if SubStr(Encoding,1,2)="CP"
Encoding := SubStr(Encoding,3)
if !Encoding ; "" or 0
{
; No conversion necessary, but we might not want the whole string.
if (Length == -1)
Length := DllCall("lstrlen", "uint", Address)
VarSetCapacity(String, Length)
DllCall("lstrcpyn", "str", String, "uint", Address, "int", Length + 1)
}
else if Encoding = 1200 ; UTF-16
{
char_count := DllCall("WideCharToMultiByte", "uint", 0, "uint", 0x400, "uint", Address, "int", Length, "uint", 0, "uint", 0, "uint", 0, "uint", 0)
VarSetCapacity(String, char_count)
DllCall("WideCharToMultiByte", "uint", 0, "uint", 0x400, "uint", Address, "int", Length, "str", String, "int", char_count, "uint", 0, "uint", 0)
}
else if Encoding is integer
{
; Convert from target encoding to UTF-16 then to the active code page.
char_count := DllCall("MultiByteToWideChar", "uint", Encoding, "uint", 0, "uint", Address, "int", Length, "uint", 0, "int", 0)
VarSetCapacity(String, char_count * 2)
char_count := DllCall("MultiByteToWideChar", "uint", Encoding, "uint", 0, "uint", Address, "int", Length, "uint", &String, "int", char_count * 2)
String := StrGet(&String, char_count, 1200)
}
return String
}
#SingleInstance
OnMessage(0x4a, "Receive_WM_COPYDATA")
return
Receive_WM_COPYDATA(wParam, lParam)
{
StringAddress := NumGet(lParam + 2 *A_PtrSize)
CopyOfData := StrGet(StringAddress)
guicontrol, ,textv ,Received the following string: %CopyOfData%
return true
}
guiclose:
exitapp
Скачать sender и listener можно здесь. Sender шлет раз в секунду сообщение WM_COPYDATA со строкой hello всем окнам.
Код sender:
procedure senderstr;
var
MyCopyDataStruct: TCopyDataStruct;
begin
with MyCopyDataStruct do
begin
cbData:= StrLen(PChar('hello')) + 1;
lpData:= PChar('hello')
end;
SendCopyData(HWND_BROADCAST,MyCopyDataStruct);
end;
procedure SendCopyData(hTargetWnd: HWND; ACopyDataStruct:TCopyDataStruct);
begin
if hTargetWnd<>0 then
SendMessage(hTargetWnd, WM_COPYDATA, Longint(Form1.Handle), Longint(@ACopyDataStruct))
else
ShowMessage('No Recipient found!');
end;
код слушателя
function WndCallback(Ahwnd: HWND; uMsg: UINT; wParam: WParam; lParam: LParam):LRESULT; stdcall;
Var
pMyData : CopyDataStruct;
begin
if uMsg=WM_COPYDATA then
begin
pMyData:= PCopyDataStruct(lParam)^;
form1.memo1.lines.add(PChar(pMyData.lpData));
end;
result:= CallWindowProc(PrevWndProc,Ahwnd,uMsg,WParam,LParam);
end;
В Windows тоже не работает отлов сообщений, скачать exe

