首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用Python接收WM_COPYDATA

用Python接收WM_COPYDATA
EN

Stack Overflow用户
提问于 2011-03-09 17:42:56
回答 1查看 4.7K关注 0票数 5

我正在尝试从WindowsLiveMessenger中读取一些应用程序(我正在使用Spotify)发送到WindowsLiveMessenger,以更新“我正在收听的内容”。短语。

根据我所发现的,WM_COPYDATA消息是以具有以下结构的COPYDATASTRUCT形式出现的:

  • 在我们的例子中,dwData是0x547,因此它现在访问侦听功能。
  • 具有接收到的字符串长度的cbData
  • 具有指向字符串本身的指针的lpData,可能包括Unicode字符。

字符串应该具有以下格式:\0Music\0status\0format\0song\0artist\0album\0,如ListeningNowTracker所述

我们在WM_COPYDATA事件中接收到的是一个指向包含COPYDATASTRUCTlParam的指针。

我开始修改pywin32函数,我记得从过去的经验来看,它们不接受Unicode字符,然后我转而使用ctype。尽管对我来说,这几乎是Python中的一个新世界,但我尝试使用POINTER(),而我得到的只是未知的对象或访问违规行为。

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

代码语言:javascript
运行
复制
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

这应该接近我想要的,但会给出一个空指针错误。

代码语言:javascript
运行
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-03-10 09:36:13

我编写了以下简单的win32gui应用程序:

代码语言:javascript
运行
复制
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消息:

代码语言:javascript
运行
复制
Text := 'greetings!';
CopyData.cbData := (Length(Text)+1)*StringElementSize(Text);
CopyData.lpData := PWideChar(Text);
SendMessage(hwnd, WM_COPYDATA, Handle, NativeInt(@CopyData));

产出如下:

代码语言:javascript
运行
复制
461584
461584
74
658190
2620592
42
22
greetings!

所以看起来它的工作原理是微不足道的,就像你编码它一样。

我唯一能想到的是,Spotify的COPYDATASTRUCT中的文本不是以空结尾的。通过读取数据,您应该能够很容易地检查这一点。利用cbData成员。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5249903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档