Tee Posted August 12, 2021 Share Posted August 12, 2021 (edited) Could not find any example how I actually get the return value of the _SendMessage call... I've got (testing) simple message handler which would just put integer to the Message result value depending on the situation. procedure TWindow.WmStatus(var Msg: TMessage); var LResult: NativeInt; begin LResult := 1; if Assigned(FObjectReference) then if FObjectReference.Status = mpFinished then LResult := 2; Msg.Result := LResult; end; How I get that Result value at the AutoIT side? -Tee- Edited August 13, 2021 by Tee Link to comment Share on other sites More sharing options...
636C65616E Posted August 12, 2021 Share Posted August 12, 2021 (edited) You should post code like that. What's this language (sry I can't reconize that, I still have lot to learn). Edit: should be Delphi/Lazarus ? Where your procedure is called ? Anyway, according to msdn : LRESULT CALLBACK WindowProc( _In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ); // synchronous: call the WindowProc and 'halt' until return LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); LRESULT LRESULT DefWindowProcA( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); If you're not returning the LRESULT inside your window proc there's no (simple) way you can get the result, also always return at end the default WndProc (DefWindowProcA) that handle basic messages needed to interact with the window (as destroy, change data, etc), or maybe your langage automatically handle that, idk. From autoit pov _SendMessage will return the LRESULT when $iReturn is set to 0 (default value) Edited August 13, 2021 by 636C65616E Link to comment Share on other sites More sharing options...
Earthshine Posted August 12, 2021 Share Posted August 12, 2021 looks like Pascal 636C65616E and Tee 2 My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
636C65616E Posted August 12, 2021 Share Posted August 12, 2021 (edited) I've done some tests with Lazarus, but i'm not familiar enought with Pascal, anyway i guess you need to override something like that (Delphi): procedure TWindow.WndProc(var Msg: TMessage); begin // do your stuff Inherited WndProc(Msg); end; Short example in pure AutoIt: One programm to create a window with a custom WindowProc handling a custom 0x401 msg : expandcollapse popup#cs FROM MSDN: Application-Defined Messages An application can create messages to be used by its own windows or to communicate with windows in other processes. If an application creates its own messages, the window procedure that receives them must interpret the messages and provide appropriate processing. Message-identifier values are used as follows: - The system reserves message-identifier values in the range 0x0000 through 0x03FF (the value of WM_USER – 1) for system-defined messages. Applications cannot use these values for private messages. - Values in the range 0x0400 (the value of WM_USER) through 0x7FFF are available for message identifiers for private window classes. - If your application is marked version 4.0, you can use message-identifier values in the range 0x8000 (WM_APP) through 0xBFFF for private messages. - The system returns a message identifier in the range 0xC000 through 0xFFFF when an application calls the RegisterWindowMessage function to register a message. The message identifier returned by this function is guaranteed to be unique throughout the system. Use of this function prevents conflicts that can arise if other applications use the same message identifier for different purposes. #ce #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <WinAPI.au3> $form = GUICreate('TestWnd', 174, 102, -1, -1, BitOR($WS_CAPTION, $WS_SYSMENU)) $label = GUICtrlCreateLabel('received: ', 32, 24, 108, 49, BitOR($SS_CENTER,$SS_CENTERIMAGE)) GUISetState(@SW_SHOW) ; to handle native AutoIt stuff $oldproc = _WinAPI_GetWindowLong($form, $GWL_WNDPROC) func WndProc($hwnd, $uMsg, $wParam, $lParam) static $count = 0 switch $uMsg case 0x401 $count += 1 GUICtrlSetData($label, 'received: ' & $count) return 0x452 endswitch ; ConsoleWrite('msg = ' & ptr($uMsg) & @CRLF) ; return _WinAPI_DefWindowProc($hwnd, $uMsg, $wParam, $lParam) local $res = DllCallAddress('LRESULT', $oldproc, 'HWND', $hwnd, 'UINT', $uMsg, 'WPARAM', $wParam, 'LPARAM', $lParam) if @ERROR <> 0 then ConsoleWrite('ERROR: ' & @ERROR & @CRLF) return 0 endif return $res[0] endfunc $WndProc = DllCallbackRegister(WndProc, 'LRESULT', 'HWND;UINT;WPARAM;LPARAM;') _WinAPI_SetWindowLong($form, $GWL_WNDPROC, DllCallbackGetPtr($WndProc)) while 1 switch GUIGetMsg() case $GUI_EVENT_CLOSE ExitLoop endswitch wend GUIDelete($form) DllCallbackFree($WndProc) One program to interact with it (notice that sending 0x10 will close the 1st one as it is the WM_CLOSE), here the custom msg is 0x401: #include <SendMessage.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> $hwnd = WinWait('TestWnd', '', 1) if ($hwnd = 0) then MsgBox(0x10, 'Error', 'Cant find the TestWnd') Exit endif $form = GUICreate('SENDER', 196, 128, -1, -1, BitOR($WS_CAPTION, $WS_SYSMENU)) $send = GUICtrlCreateButton('SEND', 16, 46, 161, 33) $input = GUICtrlCreateInput('0x401', 50, 17, 126, 21) $disp = GUICtrlCreateLabel('-', 18, 94, 157, 17, $SS_CENTERIMAGE) GUICtrlCreateLabel("Msg:", 17, 16, 35, 22, $SS_CENTERIMAGE) GUISetBkColor(0xB9D1EA) GUISetState(@SW_SHOW) while 1 switch GUIGetMsg() case $GUI_EVENT_CLOSE Exit case $send local $msg = Number(GUICtrlRead($input),1) local $res = _SendMessage($hwnd, $msg) GUICtrlSetData($disp, '[0x' & hex($msg,4) & '] ' & ptr($res)) endswitch wend For some obscure reason selecting the window also post a WM_USER message, that's why I use 0x401 instead of simply 0x400 Edited August 13, 2021 by 636C65616E KaFu 1 Link to comment Share on other sites More sharing options...
Tee Posted August 13, 2021 Author Share Posted August 13, 2021 (edited) I think I was not very clear what I am looking for. I have message handler like in first message if shown. It should work. (I could use L/WPAram also, if can pass the value in those also. I am planning to do in AutoIT because one of our application window is hard to detect when it is finished. So I would sen message in the loop like So something Like this would be needed in AutoIT side, just can't find example on getting the result... Local Const $WM_USER_CUSTOM_STATUS = $WM_USER + 666 while $LResult <> 2 _SendMessage($hWnd, $WM_USER_CUSTOM_STATUS...) If $LResult <> 2 Then Sleep(100) EndIf EEnd When the Delphi coded message handler returns 2 we would know that that window is done it's work, and we know that we can start to interact with it. Now we kind of hack in place I don'ät like (We disable Toolbar until it's finished working, and enable it then), and AutoIT script will poll the status of the component. That works well, but it'll cause visual flickering of the toolbar, and that is bit ugly. AutoIT help on _SendMEssage is bit hard for me to decode: _SendMessage ( $hWnd, $iMsg [, $wParam = 0 [, $lParam = 0 [, $iReturn = 0 [, $wParamType = "wparam" [, $lParamType = "lparam" [, $sReturnType = "lresult"]]]]]] ) I think I need (As someone mentioned) $iReturn as 0, and should get return value from the $sReturnType parameter. Just confused about what $sReturnType = "lresult" means?? And reference to the "[optional] See DllCall in Related" If last param can be just a "Integer" variable then I think I can get this to work... (I just don't personally have test setup and that's why I did not just try, because coworker has to do the testing and need to have some idea that it could work first. Don't want to bother him in vain.) -Tee- Edited August 13, 2021 by Tee Link to comment Share on other sites More sharing options...
636C65616E Posted August 13, 2021 Share Posted August 13, 2021 (edited) Well you never assign the return value, so ... yeah you will have some struggle. The data is not transferred via a magic object working around in background ^^ $lResult = _SendMessage($hWnd, $WM_USER_CUSTOM_STATUS) no more complicated than that Futhermore don't forget to include the appropriate library and to define the WM_USER #include <SendMessage.au3> ; $WM_USER = 0x400 ; <<< this is defined inside WindowsConstants.au3 #include <WindowsConstants.au3> EDIT: 11 hours ago, Tee said: If last param can be just a "Integer" variable then I think I can get this to work... (I just don't personally have test setup and that's why I did not just try, because coworker has to do the testing and need to have some idea that it could work first. Don't want to bother him in vain.) Installing AutoIt and running a script is a matter of few minutes ... Also the AutoIt _SendMessage prototype is exactly the same as the one from Microsoft with default value 0 for wParam and lParam: $lResult = _SendMessage($hWnd, $uMsg, $wParam = 0, $lParam = 0) Don't get distracted by the other parameters, they are made to mimic the real SendMessage format by default (but they give you the option to change it). Edited August 13, 2021 by 636C65616E Link to comment Share on other sites More sharing options...
Tee Posted August 18, 2021 Author Share Posted August 18, 2021 On 8/13/2021 at 10:33 AM, 636C65616E said: Well you never assign the return value, so ... yeah you will have some struggle. The data is not transferred via a magic object working around in background ^^ $lResult = _SendMessage($hWnd, $WM_USER_CUSTOM_STATUS) Result and Return are different things, right? in my pseudocode ; _SendMessage ( $hWnd, $iMsg [, $wParam = 0 [, $lParam = 0 [, $iReturn = 0 [, $wParamType = "wparam" [, $lParamType = "lparam" [, $sReturnType = "lresult"]]]]]] ) _SendMessage($hWnd, $WM_USER_CUSTOM_STATUS, 0, 0, $lResult, 0, 0, 0) So that should work, maybe? I have really hard time to understand the documentation, What are the last parameters, and what to put in them,, very last Return type, shoudl it affect to the Return or Result value? Of cource I shoudl do something like $LReturn = _SendMessage($hWnd, $WM_USER_CUSTOM_STATUS, 0, 0, $lResult) And handle $LReturn and $lResult values. But I just can't find any confirmation that if I assign the Result value of the Windows message in Delphi side, I can receive it in AutoIT at the Result parameter or, Now that I read that more I have feelinf that it shopudl be: ; _SendMessage ( $hWnd, $iMsg [, $wParam = 0 [, $lParam = 0 [, $iReturn = 0 [, $wParamType = "wparam" [, $lParamType = "lparam" [, $sReturnType = "lresult"]]]]]] ) $LReturnTypoe = 0 ; 0 - Return value from DLL call $lResult = _SendMessage($hWnd, $WM_USER_CUSTOM_STATUS, 0, 0, $LReturnTypoe) And Change the Delphi sire that I could get the Return value I want, not the Result bit of the Windows message, have to ask around at Delphi side also. Link to comment Share on other sites More sharing options...
636C65616E Posted August 18, 2021 Share Posted August 18, 2021 (edited) well i linked you the official msdn documentation ... there's no lReturn, i also send you the exact prototype of the function : On 8/13/2021 at 9:33 AM, 636C65616E said: $lResult = _SendMessage($hWnd, $uMsg, $wParam = 0, $lParam = 0) just use that, the function return the lResult. the 'iReturn' in the _sendmessage (i you read the doc it could be clear) is a flag indicating thr function which data it should return, with default parameter 0 it returns the lResult, so once again use the prototype i posted just before and read the msdn doc Edited August 18, 2021 by 636C65616E Tee 1 Link to comment Share on other sites More sharing options...
Tee Posted August 19, 2021 Author Share Posted August 19, 2021 Thanks. Documentation has little weird syntax (to me). Well Check That Link to comment Share on other sites More sharing options...
636C65616E Posted August 19, 2021 Share Posted August 19, 2021 8 hours ago, Tee said: Documentation has little weird syntax (to me). It's C/C++ syntax, so yeah if you only code in Delphi/Pascal it may be a bit weird, anyway that's pretty standard (at least all window API is in cpp so, get used to it if you want to use it ) Link to comment Share on other sites More sharing options...
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