5

stickiesのコピーとやり取りする python スクリプトを作成しようとしています。Python が WM_COPYDATA 構造体と対話する方法に問題があり、残念ながらオンラインで多くの例を見つけることができませんでした。

コードの使用:

import struct
import win32con
import win32gui

import struct, array
int_buffer = array.array("L", [0])
char_buffer = array.array('b', 'do new sticky')
int_buffer_address = int_buffer.buffer_info()[0]
char_buffer_address, char_buffer_size = char_buffer.buffer_info

copy_struct = struct.pack("pLp",
int_buffer_address,
char_buffer_size, char_buffer_address)

hwnd = win32gui.FindWindow("ZhornSoftwareStickiesMain", None)

win32gui.SendMessage(w, WM_COPYDATA, hwnd, copy_struct)

次のエラーが表示されます。

C:\Users\%userprofile%\Desktop>python sender.py
Traceback (most recent call last):
  File "sender.py", line 7, in <module>
    char_buffer = array.array('b', 'do new sticky')
TypeError: an integer is required

なぜこのようなエラーが発生するのか理解できないようです。何か案は?

編集:部分的に機能するコード

import struct
import win32con
import win32gui
import struct, array


int_buffer = array.array("L", [0])
char_buffer = array.array('b', b"do manage open")
int_buffer_address = int_buffer.buffer_info()[0]

# Add () to buffer_info to call it.
char_buffer_address, char_buffer_size = char_buffer.buffer_info()

# Need P  type for the addresses.
copy_struct = struct.pack("PLP",int_buffer_address,char_buffer_size, char_buffer_address)

hwnd = win32gui.FindWindow(None, "ZhornSoftwareStickiesMain")
win32gui.SendMessage(hwnd, win32con.WM_COPYDATA, None, copy_struct)
4

3 に答える 3

4

これは、ctypes を使用する方がはるかに簡単です。このコードは、 経由で送信された文字列を受信して​​表示する単純な Delphi アプリケーションでテストされていますWM_COPYDATA

import win32con
import ctypes
import ctypes.wintypes

FindWindow = ctypes.windll.user32.FindWindowW
SendMessage = ctypes.windll.user32.SendMessageW

class COPYDATASTRUCT(ctypes.Structure):
    _fields_ = [
        ('dwData', ctypes.wintypes.LPARAM),
        ('cbData', ctypes.wintypes.DWORD),
        ('lpData', ctypes.c_wchar_p) 
        #formally lpData is c_void_p, but we do it this way for convenience
    ]

hwnd = FindWindow('TheNameOfMyWindowClass', None)
cds = COPYDATASTRUCT()
cds.dwData = 0
str = 'boo'
cds.cbData = ctypes.sizeof(ctypes.create_unicode_buffer(str))
cds.lpData = ctypes.c_wchar_p(str)

SendMessage(hwnd, win32con.WM_COPYDATA, 0, ctypes.byref(cds))

これは、受信者が UTF-16 でエンコードされたペイロードを予期していることを前提としています。受信者が ANSI エンコードのペイロードを期待している場合は、このバリアントを使用する必要があります。

import win32con
import ctypes
import ctypes.wintypes

FindWindow = ctypes.windll.user32.FindWindowW
SendMessage = ctypes.windll.user32.SendMessageW

class COPYDATASTRUCT(ctypes.Structure):
    _fields_ = [
        ('dwData', ctypes.wintypes.LPARAM),
        ('cbData', ctypes.wintypes.DWORD),
        ('lpData', ctypes.c_char_p)
        #formally lpData is c_void_p, but we do it this way for convenience
]

hwnd = FindWindow('TheNameOfMyWindowClass', None)
cds = COPYDATASTRUCT()
cds.dwData = 0
str = b'boo'
cds.cbData = ctypes.sizeof(ctypes.create_string_buffer(str))
cds.lpData = ctypes.c_char_p(str)

SendMessage(hwnd, win32con.WM_COPYDATA, 0, ctypes.byref(cds))

投稿した Stickies リンクを見ると、ANSI バリアントを使用する必要があります。通知を受け取りたい場合は、上記の 0 の代わりに SendMessage 呼び出しでウィンドウ ハンドルを渡す必要があります。

于 2013-11-17T21:48:03.240 に答える
0

次のバリアントは、ctypes lib を使用せずにUnicode 入力文字列をサポートします。

import array, struct, win32con, win32gui

def copy_data(hwnd, message, dwData = 0):
    buffer = array.array('u', message + '\x00')
    buffer_address, buffer_length = buffer.buffer_info()

    copy_struct = struct.pack('PLP', dwData, buffer_length * buffer.itemsize, buffer_address)

    return win32gui.SendMessage(hwnd, win32con.WM_COPYDATA, None, copy_struct)

hwnd = win32gui.FindWindow(None, 'ZhornSoftwareStickiesMain')
copy_data(hwnd, 'Hello ')
于 2021-12-23T08:26:10.910 に答える