Автоматизация Python Win32Gui - Отправка WM_COPYDATA для получения данных от BSPlayer

Я отчаянно пытаюсь автоматизировать BSPlayer из моего скрипта. Мне удалось отправить простые идентификаторы команд в окно BSPlayer (увеличение / уменьшение громкости, воспроизведение / пауза и т. Д.), Однако я не могу вернуть имя файла.

Вот API BSPlayer. Я был в состоянии эмулировать в Python первые части, но WM_COPYDATA не работает.

Вот мой код Python:

copyDataCmd = COPYDATASTRUCT()
copyDataCmd.dwData = self.BSP_GetFileName
copyDataCmd.lpData = ""
copyDataCmd.cbData = 4                
win32gui.SendMessage(self.playerWindowHandler, win32con.WM_COPYDATA, 
                     ownHandler, copyDataCmd);

Очевидно,.lpData возвращает "" ...

Что я пытаюсь подражать:

cds:TCOPYDATASTRUCT; 
buf:array[0..MAX_PATH-1] of char; 
adr:pointer; // 
adr:=@buf; 
cds.dwData:=BSP_GetFileName; 
cds.lpData:=@adr; 
cds.cbData:=4; 
SendMessage(bsp_hand,WM_COPYDATA,appHWND,lParam(@cds)); 
// available in BSPlayer version 0.84.484+ // 
// appHWND is calling application window handle 
// File name will be copied to buf // 
// Get open file name 
BSP_GetFileName = $1010B;

Чтобы быть более многословным, я пытаюсь получить имя файла из окна BSPlayer. Для этого я пытаюсь эмулировать код выше. Я ожидаю, что какой-то буфер будет заполнен моей желаемой строкой, но он окажется пустым. Итак, еще раз, я хочу Python-эквивалент кода чуть выше.

Например, этот код был успешно эмулирован:

status := SendMessage(bsp_hand,WM_BSP_CMD,BSP_GetStatus,0); 
// available in BSPlayer version 0.84.484+ // 
// Return player status // 0 - STOP // 1 - PAUSE 
// 2 - PLAY // 4 - No movie   open        
BSP_GetStatus = $10102; 

Заранее спасибо!

1 ответ

Решение

Вы не можете повторить это WM_COPYDATA в вашем коде Python. Он может быть использован только in-proc, например, для плагинов.

Пример кода Delphi написан в предположении, что вызов WM_COPYDATA сделан из того же процесса, что и окно, которое получает сообщение. Это потому что WM_COPYDATA используется для копирования указателя, и указатели действительны только внутри процесса, который выделил память. Вы не можете отправить указатель через границу процесса.

На мой взгляд, дизайнеры интерфейса злоупотребляют WM_COPYDATA, Он предназначен для точного решения проблемы передачи данных между процессами. Это самая простая и легковесная связь между процессами. Чтобы затем использовать его для переноса указателя, достаточно, чтобы победить процесс.

Другие вопросы по тегам