我正在尝试从WindowsLiveMessenger中读取一些应用程序(我正在使用Spotify)发送到WindowsLiveMessenger,以更新“我正在收听的内容”。短语。
根据我所发现的,WM_COPYDATA
消息是以具有以下结构的COPYDATASTRUCT
形式出现的:
dwData
是0x547,因此它现在访问侦听功能。cbData
lpData
,可能包括Unicode字符。字符串应该具有以下格式:\0Music\0status\0format\0song\0artist\0album\0
,如ListeningNowTracker所述
我们在WM_COPYDATA
事件中接收到的是一个指向包含COPYDATASTRUCT
的lParam
的指针。
我开始修改pywin32函数,我记得从过去的经验来看,它们不接受Unicode字符,然后我转而使用ctype。尽管对我来说,这几乎是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
构建的隐藏窗口接收的。复制数据事件连接到一个名为OnCopyData
的函数,这是它的头:
def OnCopyData(self, hwnd, msg, wparam, lparam):
与来自Spy++消息日志的值相比,函数传递的值是正确的。
更新2
这应该接近我想要的,但会给出一个空指针错误。
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)
发布于 2011-03-10 09:36:13
我编写了以下简单的win32gui应用程序:
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
消息:
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!
所以看起来它的工作原理是微不足道的,就像你编码它一样。
我唯一能想到的是,Spotify的COPYDATASTRUCT
中的文本不是以空结尾的。通过读取数据,您应该能够很容易地检查这一点。利用cbData
成员。
https://stackoverflow.com/questions/5249903
复制相似问题