在Python中接收WM_COPYDATA

我试图从Python读取WM_COPYDATA消息一些应用程序(我试图与Spotify)发送到WindowsLiveMessenger更新“我在听什么…”的短语。

从我所能find的, WM_COPYDATA消息进来COPYDATASTRUCT具有以下结构:

  • 在我们的情况下,dwData 0x547,以便它访问现在正在侦听function
  • cbData与接收的string的长度
  • 带有指向string本身的指针的lpData可能包含Unicode字符

该string应具有以下格式: \0Music\0status\0format\0song\0artist\0album\0由ListeningNowTracker

我们在WM_COPYDATA事件中收到的是一个包含COPYDATASTRUCT lParam指针。

我开始修改pywin32函数,我记得他们不接受过去经验的Unicode字符,然后我切换到ctypes。 尽pipe这对Python来说已经是一个新的世界了,但我用POINTER()试了一下,所有的东西都是未知对象,或者是访问违规。

我认为代码应该创build一个COPYDATASTRUCT

 class CopyDataStruct(Structure): _fields_ = [('dwData', c_int), ('cbData', c_int), ('lpData', c_void_p)] 

然后使lParam成为指向该结构的指针,从ctypes.string_at(lpData,cbData)获取string指针,最后用ctypes.string_at(lpData,cbData)获取string。

有小费吗?

更新1

为了这个目的, WM_COPYDATA事件被一个用win32gui构build的隐藏窗口接收。 copydata事件连接到一个名为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) 

Solutions Collecting From Web of "在Python中接收WM_COPYDATA"

我写了以下微不足道的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 listner: def __init__(self): message_map = { win32con.WM_COPYDATA: self.OnCopyData } wc = win32gui.WNDCLASS() wc.lpfnWndProc = message_map wc.lpszClassName = 'MyWindowClass' hinst = wc.hInstance = win32api.GetmoduleeHandle(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 = listner() 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成员。