LxP Posted October 7, 2005 Posted October 7, 2005 (edited) Hi all,I wanted to be able to quickly and cleanly send commands to a running copy of PowerPro, so here's how it can be done without constructing a god-awful Run() line. Using this code also adds the benefit of having your AutoIt script execution pause while PowerPro processes the passed command/s.I have no 'expertise' in the area of DLLs and structures so please feel free to offer criticism and improvements to the code. Thanks to Larry for helping me get this far.Note: Tested with AutoIt v3.1.1.82 and PowerPro v4.3.08.Edit: The code no longer modifies the WinTitleMatchMode outside its own scope (thanks Valik).Edit: Simpler command structure preparation (thanks again Larry).Edit: Added better error checking (won't crash PowerPro if very long commands are sent).Edit: Function now returns a Boolean value to indicate success.expandcollapse popupLocal $Cmd = 'Message PowerPro can now receive commands from AutoIt!' MsgBox(0x40, "PowerProCmdSend()", 'Returned ' & PowerProCmdSend($Cmd) _ & @CRLF & '@Error was ' & @Error) Func PowerProCmdSend($Cmd) ; @Error = 0 -> Success ; @Error = 1 -> Command too long ; @Error = 2 -> PowerPro not running ; @Error = 3 -> Structures could not be made ; Assert a safe PowerPro command length If StringLen($Cmd) > 530 Then SetError(1) Return False EndIf ; Assert existence of PowerPro in memory Local $PrevOpt = Opt('WinTitleMatchMode', 4) Local $PProHandle = WinGetHandle('ClassName=PowerProMain') Local $Error = @Error Opt('WinTitleMatchMode', $PrevOpt) If $Error Then SetError(2) Return False EndIf ; Prepare command structure Local $CmdStruct = DLLStructCreate('Char[' & StringLen($Cmd) + 1 & ']') If @Error Then SetError(3) Return False EndIf DLLStructSetData($CmdStruct, 1, $Cmd) ; Prepare COPYDATASTRUCT Local $CDStruct = DLLStructCreate('Ptr;DWord;Ptr') If @Error Then DLLStructDelete($CmdStruct) SetError(3) Return False EndIf DLLStructSetData($CDStruct, 1, 1) DLLStructSetData($CDStruct, 2, StringLen($Cmd) + 1) DLLStructSetData($CDStruct, 3, DLLStructGetPtr($CmdStruct)) ; Do the call (WM_COPYDATA => 74) DLLCall('User32.dll', 'None', 'SendMessage', 'HWnd', $PProHandle, _ 'Int', 74, 'HWnd', WinGetHandle(AutoItWinGetTitle()), _ 'Ptr', DLLStructGetPtr($CDStruct)) ; Tidy up DLLStructDelete($CmdStruct) DLLStructDelete($CDStruct) ; Indicate success Return True EndFunc Edited October 15, 2005 by LxP
Valik Posted October 7, 2005 Posted October 7, 2005 Warning: The code sets the WinTitleMatchMode to 4 as it needs to determine the handle of PowerPro's main window by class name. I'd love not to have to do this if anyone can offer a better way (but using window titles is out of the question).Just set it back to whatever it was when your function ends.Local $nWinTitleMatchMode = Opt("WinTitleMatchMode", 4) ; Code Opt("WinTitleMatchMode", $nWinTitleMatchMode)
LxP Posted October 7, 2005 Author Posted October 7, 2005 Thanks Larry, Your code runs without problems; does it guarantee that the final character will be null though, or would it be wiser to explicitly declare it? -- DLLStructSetData($CmdStruct, 1, $Cmd) DLLStructSetData($CmdStruct, 1, 0x00, StringLen($Cmd) + 1)
LxP Posted October 7, 2005 Author Posted October 7, 2005 Thanks Valik -- updated. I suppose I should read the help file more effectively. Thanks Larry -- I'll hold you to your word!
LxP Posted October 15, 2005 Author Posted October 15, 2005 (edited) Thanks layer! Modified the above code to perform better error checking and to return a Boolean value indicating success. It seems that PowerPro will crash if it receives commands longer than 530 characters (while I could sometimes send longer commands during testing, the shortest command length with which I could get PowerPro to crash was 531). The function will now prevent this from occurring and return False and an appropriate @Error code. Edited October 23, 2005 by LxP
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now