I am desperately trying to automate BSPlayer from my script.
I was successful in sending simple command ids to the BSPlayer window(volume up/down, play/pause, etc.), however I am not able to get the file name back.
Here is the BSPlayer API.
I was able to emulate in python the first parts, however the WM_COPYDATA doesn't work.
Here is my Python code:
copyDataCmd = COPYDATASTRUCT()
copyDataCmd.dwData = self.BSP_GetFileName
copyDataCmd.lpData = ""
copyDataCmd.cbData = 4
win32gui.SendMessage(self.playerWindowHandler, win32con.WM_COPYDATA,
ownHandler, copyDataCmd);
Obviously .lpData returns "" ...
What I am trying to emulate:
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;
To be more verbose, I am trying to get the filename from a BSPlayer window. For this I am trying to emulate the code above. I expect a buffer of some sort to be filled with my desired string, but it comes up empty.
So, again, I want the Python equivalent of the code just above.
For example this code was emulated succesfully:
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;
Thanks in advance!
解决方案
You cannot replicate that WM_COPYDATA in your Python code. It can only be used in-proc, for example for plugins.
The example Delphi code is written under the assumption that the call to WM_COPYDATA is made from the same process as the window which receives the message. That's because the WM_COPYDATA is used to copy a pointer, and pointers are only valid inside the process which allocated the memory. You cannot send a pointer across a process boundary.
In my opinion, the designers of the interface are abusing WM_COPYDATA. It is meant to be used to solve the exact problem of transferring data between processes. It is the simplest most lightweight inter-process communication available. To then use it to transfer a pointer rather defeats the process.