在Python中接收WM_COPYDATA [英] Receiving WM_COPYDATA in Python
问题描述
我正在尝试从Python中读取某些应用程序(我正在尝试使用Spotify)发送给WindowsLiveMessenger的 WM_COPYDATA
消息,以更新我正在听的内容。 ..短语。
I am trying to read from Python the WM_COPYDATA
message some applications (I'm trying with Spotify) send to WindowsLiveMessenger to update the "What I'm listening to..." phrase.
根据我的发现, WM_COPYDATA
消息出现在 COPYDATASTRUCT
具有以下结构:
From what I have been able to find, WM_COPYDATA
messages come in a COPYDATASTRUCT
with the following structure:
-
dwData
在我们的示例中为0x547,以便它使用接收到的字符串的长度 -
cbData
来访问立即监听功能 -
lpData
带有指向字符串本身的指针,可能包含Unicode字符
dwData
in our case 0x547 so that it access the listening now featurecbData
with the length of the string receivedlpData
with a pointer to the string itself, may include Unicode characters
字符串应具有以下格式: \0Music\0status\0format\0song\0artist\0album\0
如前所述通过 ListeningNowTracker
The string should have the following format: \0Music\0status\0format\0song\0artist\0album\0
as stated by ListeningNowTracker
我们在 WM_COPYDATA $ c中收到的内容$ c>事件是
lParam
的指针,其中包含 COPYDATASTRUCT
。
What we receive in a WM_COPYDATA
event is a pointer for lParam
that contains the COPYDATASTRUCT
.
我开始修改pywin32函数,并记得他们不接受以往经验的Unicode字符,然后我改用了ctypes。尽管对于我来说,这对Python来说几乎是一个新世界,但我还是尝试了 POINTER()
,对我来说,我得到的只是未知对象或访问冲突。
I started tinkering with pywin32 functions and I remembered that they do not accept Unicode characters from past experience, then I switched to ctypes. Despite this being an almost new world in Python for me, I tried with POINTER()
and all I got was unknown objects for me or access violations.
我认为代码应创建 COPYDATASTRUCT
:
class CopyDataStruct(Structure):
_fields_ = [('dwData', c_int),
('cbData', c_int),
('lpData', c_void_p)]
然后将 lParam
用作指针到该结构,从 lpData
获取字符串指针,最后使用 ctypes.string_at(lpData,cbData)
获取字符串。
Then make the lParam
be a pointer to that structure, get the string pointer from lpData
and finally get the string with ctypes.string_at(lpData,cbData)
.
有什么提示吗?
更新1
WM_COPYDATA
事件由使用 win32gui
生成的隐藏窗口接收。 copydata事件连接到名为 OnCopyData
的函数,它是其标头:
def OnCopyData(self,hwnd,msg ,wparam,lparam):
与Spy ++消息日志中的值相比,该函数提供的值是正确的。
The WM_COPYDATA
event is received by a hidden window built with win32gui
just for this purpose. The copydata event is connected to a function called OnCopyData
and this is its header:
def OnCopyData(self, hwnd, msg, wparam, lparam):
The values the function delivers are correct as compared with the ones from the Spy++ messages log.
更新2
这应该与我想要的接近,但是给出了NULL指针错误。
This should be close to what I want, but gives a NULL pointer error.
class CopyDataStruct(ctypes.Structure):
_fields_ = [('dwData', c_int),
('cbData', c_int),
('lpData', c_wchar_p)]
PCOPYDATASTRUCT = ctypes.POINTER(CopyDataStruct)
pCDS = ctypes.cast(lparam, PCOPYDATASTRUCT)
print ctypes.wstring_at(pCDS.contents.lpData)
推荐答案
以下琐碎的win32gui应用程序:
I wrote the following trivial win32gui app:
import win32con, win32api, win32gui, ctypes, ctypes.wintypes
class COPYDATASTRUCT(ctypes.Structure):
_fields_ = [
('dwData', ctypes.wintypes.LPARAM),
('cbData', ctypes.wintypes.DWORD),
('lpData', ctypes.c_void_p)
]
PCOPYDATASTRUCT = ctypes.POINTER(COPYDATASTRUCT)
class Listener:
def __init__(self):
message_map = {
win32con.WM_COPYDATA: self.OnCopyData
}
wc = win32gui.WNDCLASS()
wc.lpfnWndProc = message_map
wc.lpszClassName = 'MyWindowClass'
hinst = wc.hInstance = win32api.GetModuleHandle(None)
classAtom = win32gui.RegisterClass(wc)
self.hwnd = win32gui.CreateWindow (
classAtom,
"win32gui test",
0,
0,
0,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
0,
0,
hinst,
None
)
print self.hwnd
def OnCopyData(self, hwnd, msg, wparam, lparam):
print hwnd
print msg
print wparam
print lparam
pCDS = ctypes.cast(lparam, PCOPYDATASTRUCT)
print pCDS.contents.dwData
print pCDS.contents.cbData
print ctypes.wstring_at(pCDS.contents.lpData)
return 1
l = Listener()
win32gui.PumpMessages()
然后我从另一个应用程序(用Delphi编写)向窗口发送了 WM_COPYDATA
消息:
I then sent the window a WM_COPYDATA
message from another app (written in Delphi):
Text := 'greetings!';
CopyData.cbData := (Length(Text)+1)*StringElementSize(Text);
CopyData.lpData := PWideChar(Text);
SendMessage(hwnd, WM_COPYDATA, Handle, NativeInt(@CopyData));
输出为:
461584
461584
74
658190
2620592
42
22
greetings!
因此,它似乎微不足道,就像您编写的代码一样。
So it seems that it works trivially, pretty much as you coded it.
我唯一想到的是Spotify的 COPYDATASTRUCT
中的文本不是以空字符结尾的。您应该能够通过读取数据很容易地进行检查。利用 cbData
成员。
The only thing that I can think of is that the text in Spotify's COPYDATASTRUCT
is not null-terminated. You should be able to check that quite easily by reading out the data. Make use of the cbData
member.
这篇关于在Python中接收WM_COPYDATA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!