在Python中接收WM_COPYDATA
我正在尝试从 Python 中读取某些应用程序(我正在尝试使用 Spotify)发送到 WindowsLiveMessenger 的 WM_COPYDATA
消息,以更新“我正在听的内容...”短语。
据我所知,WM_COPYDATA
消息位于 COPYDATASTRUCT
中,其结构如下:
dwData
在我们的例子中为 0x547,以便它访问现在收听的功能cbData
包含收到的字符串长度lpData
以及指向字符串本身的指针,可能包含 Unicode 字符
字符串应具有以下格式: \0Music\0status\0format\0song\0artist\0album\0
如ListeningNowTracker
我们在 WM_COPYDATA
事件中收到的是包含 COPYDATASTRUCT
的 lParam
指针。
我开始修补 pywin32 函数,我记得根据过去的经验,它们不接受 Unicode 字符,然后我切换到 ctypes。尽管这对我来说在 Python 中几乎是一个新世界,但我尝试使用 POINTER() ,但我得到的只是未知的对象或访问冲突。
我认为代码应该创建一个COPYDATASTRUCT
:
class CopyDataStruct(Structure):
_fields_ = [('dwData', c_int),
('cbData', c_int),
('lpData', c_void_p)]
然后使lParam
成为指向该结构的指针,从lpData
获取字符串指针,最后使用ctypes.string_at(lpData,cbData)
获取字符串。
有什么建议吗?
更新1
WM_COPYDATA
事件由专门为此目的而使用win32gui
构建的隐藏窗口接收。 copydata 事件连接到一个名为 OnCopyData
的函数,这是它的标头:def OnCopyData(self, hwnd, msg, wparam, lparam):
与 Spy++ 消息日志中的值相比,该函数提供的值是正确的。
更新2
这应该接近我想要的,但给出了 NULL 指针错误。
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)
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.
From what I have been able to find, WM_COPYDATA
messages come in a COPYDATASTRUCT
with the following structure:
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
The string should have the following format: \0Music\0status\0format\0song\0artist\0album\0
as stated by ListeningNowTracker
What we receive in a WM_COPYDATA
event is a pointer for lParam
that contains the COPYDATASTRUCT
.
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.
I think that the code should create a COPYDATASTRUCT
:
class CopyDataStruct(Structure):
_fields_ = [('dwData', c_int),
('cbData', c_int),
('lpData', c_void_p)]
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)
.
Any tips?
UPDATE 1
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.
UPDATE 2
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我编写了以下简单的 win32gui 应用程序:
然后,我从另一个应用程序(用 Delphi 编写)向窗口发送了一条
WM_COPYDATA
消息:输出是:
所以看起来它的工作原理很简单,与您编写的代码非常相似。
我唯一能想到的是 Spotify 的 COPYDATASTRUCT 中的文本不是以 null 结尾的。您应该能够通过读出数据来轻松检查这一点。利用
cbData
成员。I wrote the following trivial win32gui app:
I then sent the window a
WM_COPYDATA
message from another app (written in Delphi):The output was:
So it seems that it works trivially, pretty much as you coded it.
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 thecbData
member.