Sign in to follow this  
Followers 0
usabrad86

help _sendmessage()

7 posts in this topic

hey im trying to send message from a program made from VisualStudio2008 useing sendmessage()

i was wondering how i could "return the input in autoit" that is sent from the "VS 2k8" program,

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Look at GUIRegisterMsg(), you'll need to have a GUI (not necessarily visible) to receive the message notification, then instead of returning $GUI_RUNDEFMSG you can return the value you want.

Edit: If the return value has something to do with pointers or data other than the built-in primitives (int, double, ...) you may want to search the forum for WM_COPYDATA, it's simpler. If you want to return pointers data from a user-defined message, you can pass the window handle of the VS application to the AutoIt handler and AutoIt handler can allocate memory on your VS application process space and return the pointer to the caller. Look for example in the definition of the _GUICtrlListView_GetItemText() function.

Edited by Authenticity

Share this post


Link to post
Share on other sites

here is how the other program allready sends

SendMessage(hWnd, WM_COPYDATA, (WPARAM)D2WIN_GetHwnd(), (LPARAM)&aCopy);

i just need an example to return the message into a msgbox

Share this post


Link to post
Share on other sites

WM_COPYDATA in AutoIt is something like:

GUIRegisterMsg($WM_COPYDATA, "_WM_COPYDATA")

; ...

Func _WM_COPYDATA($hWnd, $iMsg, $iwParam, $ilParam)
    Local $tCDS = DllStructCreate($tagCOPYDATASTRUCT, $ilParam)
    Local $icbData = DllStructGetData($tCDS, "cbData")
    Local $tBuffer
    Local $xDataBuf
    
    If $icbData > 0  Then
        $tBuffer = DllStructCreate("ubyte[" & $icbData & "]", DllStructGetData($tCDS, "lpData"))
        $xDataBuf = DllStructGetData($tBuffer, 1)
        ; Work with data
    EndIf
    
    Return True
EndFunc

If you want to deliver more meaningful data to the caller other the true or false you should call _SendMessage() yourself with WM_COPYDATA but only after you've returned from the handler to avoid deadlock. Another alternative is to allocate memory on the target process space and give it this memory address through _SendMessage() or something.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

ok i made this

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $tagCOPYDATASTRUCT, $rtlist
GUIRegisterMsg($WM_COPYDATA, "_WM_COPYDATA")

_gui()

Func _gui()

    $gui = GUICreate("OOG", 600, 200)
    GUISetState()       ;Show GUI

    $rtlist = GUICtrlCreateListView("ReturnedInfo      |              |              |              ",25,25,550,150)

    while 1

    WEnd
EndFunc

; ...


Func _WM_COPYDATA($hWnd, $iMsg, $iwParam, $ilParam)
    Local $tCDS = DllStructCreate($tagCOPYDATASTRUCT, $ilParam)DllStructCreate(
    Local $icbData = DllStructGetData($tCDS, "cbData")
    Local $tBuffer
    Local $xDataBuf

    If $icbData > 0  Then
        $tBuffer = DllStructCreate("ubyte[" & $icbData & "]", DllStructGetData($tCDS, "lpData"))
        $xDataBuf = DllStructGetData($tBuffer, 1)
        ; Work with data
    EndIf

    GUICtrlCreateListViewItem($hWnd & "|" & $iMsg & "|" &  $iwParam & "|" &  $ilParam,$rtlist)
    Return True
EndFunc

i am gitting info

just not the correct info

and i also found this

Private Const WM_COPYDATA As Integer = &H4A

    Private Structure CopyData
        Public dwData As IntPtr
        Public cbData As Integer
        Public lpData As IntPtr
    End Structure

this is some source i found but its in VS2008

Edited by usabrad86

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

ok YAY i got it... i can now receive message from my other program..

;;;;;;;;;;;;;;;;;;;

Global Const $StructDef_COPYDATA = "ptr;dword;ptr"
;Global Const $WM_COPYDATA = 0x4A
;Global Const $WM_CLOSE = 0x10
Global Const $STRUCTDEF_AU3MESSAGE = "char[255]"
Global $rtlist
Dim $cmd

;;;;;;;;;;;;;;;;;;
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
_gui()

Func _gui()
;;;;;;;;;;;;;;;;;;;;;;;;;



    $gui = GUICreate("OOG", 800, 600)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_exitgui')
    ; Register Windows Messages
    GUIRegisterMsg($WM_COPYDATA, "_GUIRegisterMsgProc")
    GUIRegisterMsg($WM_CLOSE, "_GUIRegisterMsgProc")

    GUISetState()       ;Show GUI

    $rtlist = GUICtrlCreateListView("Title      |Handle     |Status                                                   ",25,25,750,550,0x0010)

    while 1

    WEnd

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EndFunc

Func _exitgui()
    Exit
EndFunc
; ...
; Message Handler
Func _GUIRegisterMsgProc($hWnd, $MsgID, $WParam, $LParam)
    If $MsgID = $WM_COPYDATA Then
        ; We Recived a WM_COPYDATA Message
        ; $LParam = Poiter to a COPYDATA Struct
        $vs_cds = DllStructCreate($StructDef_COPYDATA, $LParam)
        ; Member No. 3 of COPYDATA Struct (PVOID lpData;) = Pointer to Costum Struct
        $vs_msg = DllStructCreate($STRUCTDEF_AU3MESSAGE, DllStructGetData($vs_cds, 3))

        $SciTECmdLen = DllStructGetData($vs_cds, 2)
        $cmd = StringLeft(DllStructGetData($vs_msg, 1), $SciTECmdLen)
        GUICtrlCreateListViewItem(WinGetTitle($WParam) & "|" & $WParam & "|" & $cmd,$rtlist)
        ; Display what we have recived
        ;MsgBox(0, "Test String", $cmd)

    ElseIf $MsgID = $WM_CLOSE Then
    ; We Recived a WM_CLOSE Message
        Exit
    EndIf
EndFunc ;==>_GUIRegisterMsgProc

Now can someone help me get it to send message back with an input box?

Edited by usabrad86

Share this post


Link to post
Share on other sites

You can't do it within the handler or you'll hang your VS application sending the message. You can use AdlibEnable() (AutoIt v3.3.0.0) and send the other application your own custom message or WM_COPYDATA.

#include <SendMessage.au3>

Global Const $tagCOPYDATASTRUCT = "uint;uint;ptr;"

Local $hGUI = GUICreate("Title")
; ...

Func _WM_COPTDATA($hWnd, $iMsg, $iwParam, $ilParam)
   ; ... Work with dara
   AdlibEnable("_TheFunc", 500)
   Return True
EndFunc

Func _TheFunc
   AdlibDisable()
   Local $sMessage = InputBox("Title", "Prompt", "Default")
   Local $tCDS = DllStructCreate($tagCOPYDATASTRUCT)
   Local $tBuffer = DllStructCreate("wchar[" & StringLen($sMessage)+1 & "]")
   
   DllStructsetData($tCDS, 1, 0xDEADBEEF)
   DllStructSetData($tCDS, 2, DllStructGetSize($tBuffer))
   DllStructSetData($tCDS, 3, DllStructGetPtr($tBuffer))
   
   _SendMessage($hVBApp, $WM_COPYDATA, $hGUI, DllStructGetPtr($tCDS))
EndFunc

You can avoid Adlib function by returning from the handler. The calling application posts a user message via PostMessage() to your window and you send message in return.

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0