Sign in to follow this  
Followers 0
E1M1

Need help with converting some autoit to C++

16 posts in this topic

I am trying to make my C++ app to communicate with autoit's app. But I am having some trouble I am having on C++ side. I tried to do that with 2 structs like autoit does it: DllStructSetData($ilParam, 3, DllStructGetPtr($tData)) which in C++ should be: mystruct.lpData= &mydata; but it doesnt work thatway.

Autoit:

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

    Local $hHandle, $sData = "D4672AD6-EA21-4FFD-88F5-4641A2B33E9F"

    $hHandle = WinGetHandle($sData)
        $hHandle = ControlGetText($hHandle, '', ControlGetHandle($hHandle, '', 'Edit1'))

_WM_COPYDATA_Send('test')


Func _WM_COPYDATA_Send($sString) ; Send data to the 1st instance.


    If $hHandle Then
        $tData = DllStructCreate("wchar[" & StringLen($sString) + 1 & "]")
        DllStructSetData($tData, 1, $sString)

        $ilParam = DllStructCreate("ulong_ptr;dword;ptr")
        DllStructSetData($ilParam, 1, 0)
        DllStructSetData($ilParam, 2, DllStructGetSize($tData))
        DllStructSetData($ilParam, 3, DllStructGetPtr($tData))
        _SendMessage($hHandle, $WM_COPYDATA, 0, DllStructGetPtr($ilParam))
        Return Number(Not @error)
    EndIf
EndFunc   ;==>_WM_COPYDATA_Send

C++

#include "windows.h"
#include <stdio.h>
    typedef struct tagCOPYDATASTRUCT {
      ULONG_PTR dwData;
      DWORD  cbData;
      unsigned int   lpData;
    } COPYDATASTRUCT, *PCOPYDATASTRUCT;

    typedef  struct tagDATATOCOPY{
        char data[10];
    }DATATOCOPY, *DATATOCOPY;


void CopyDataSend(){

    COPYDATASTRUCT mystruct;
    DATATOCOPY mydata;

    mydata.data = 'test';

    mystruct.dwData = 0;
    mystruct.cbData = 3;
    mystruct.lpData= &mydata;

    HWND hWnd =  FindWindowW(NULL,L"D4672AD6-EA21-4FFD-88F5-4641A2B33E9F");
    //HWND hWnd =  FindWindowW(NULL,L"Untitled - Notepad");
    HWND hEdit = FindWindowEx(hWnd,NULL,"Edit",NULL);
    printf("%X %X",hWnd,hEdit);
    char  sData[100];
    SendMessageA( hEdit, WM_GETTEXT, 100, (LPARAM)sData );
    HWND hTarget;
    int iHandle;
    sscanf(sData, "%x", &iHandle);
    hTarget = (HWND)iHandle;
    printf(" %X",hTarget);

    SendMessage(hTarget, WM_COPYDATA, NULL, (LPARAM)&mystruct);

    MessageBoxA(0,sData,"",0);
}

void main(){CopyDataSend();}

Error:

2 IntelliSense: expression must have class type d:\my documents\visual studio 2010\projects\emptytest\copydata.cpp 19
3 IntelliSense: a value of type "DATATOCOPY *" cannot be assigned to an entity of type "unsigned int" d:\my documents\visual studio 2010\projects\emptytest\copydata.cpp 23

edited

Share this post


Link to post
Share on other sites



Should that first struct be this?

typedef struct tagCOPYDATASTRUCT {
      ULONG_PTR dwData;
      DWORD  cbData;
      DATATOCOPY lpData;
    } COPYDATASTRUCT, *PCOPYDATASTRUCT;

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

For somereason it still dont like this: mydata.data = 'test';

Full code:

typedef struct tagDATATOCOPY{
char data[10];
}DATATOCOPY, *DATATOCOPY;

typedef struct tagCOPYDATASTRUCT {
ULONG_PTR dwData;
DWORD    cbData;
DATATOCOPY   lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;


void CopyDataSend(){

COPYDATASTRUCT mystruct;
DATATOCOPY mydata;

mydata.data = 'test';

mystruct.dwData = 0;
mystruct.cbData = 3;
mystruct.lpData= mydata;

HWND hWnd = FindWindowW(NULL,L"D4672AD6-EA21-4FFD-88F5-4641A2B33E9F");
//HWND hWnd = FindWindowW(NULL,L"Untitled - Notepad");
HWND hEdit = FindWindowEx(hWnd,NULL,"Edit",NULL);
printf("%X %X",hWnd,hEdit);
char sData[100];
SendMessageA( hEdit, WM_GETTEXT, 100, (LPARAM)sData );
HWND hTarget;
int iHandle;
sscanf(sData, "%x", &iHandle);
hTarget = (HWND)iHandle;
printf(" %X",hTarget);

SendMessage(hTarget, WM_COPYDATA, NULL, (LPARAM)&mystruct);

MessageBoxA(0,sData,"",0);
}
Edited by E1M1

edited

Share this post


Link to post
Share on other sites

Why do I have the feeling I've told you before that you are nowhere near using the things you are trying to use? You're missing the basics of types. Cross-process communication is about seven hundred miles from where you need to be right now.

Share this post


Link to post
Share on other sites

For somereason it still dont like this: mydata.data = 'test';

Firstly, there's no such thing as string literals enclosed in single ' (they are used for single chars). You need to enclose the literal in ". Secondly, you cannot assign a string literal to a char array. You either have to initialize the data element with the string, or do a memcpy afterwards, like so:

memcpy(mydata.data, "test", 5);

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Thanks for tip. Now I don't get error anymore but autoit receiver shows empty message box. Could anyone tell what's causing this?

#include "windows.h"
#include <stdio.h>
#include <string>


typedef struct tagDATATOCOPY{
     char data[5];
}DATATOCOPY;


void CopyDataSend(){

COPYDATASTRUCT mystruct;
DATATOCOPY mydata;
//mydata.data = "str";
memcpy(mydata.data, "test", 5);
mystruct.dwData = 0;
mystruct.cbData = 5;
mystruct.lpData= &mydata;

HWND hWnd = FindWindowW(NULL,L"D4672AD6-EA21-4FFD-88F5-4641A2B33E9F");
//HWND hWnd = FindWindowW(NULL,L"Untitled - Notepad");
HWND hEdit = FindWindowEx(hWnd,NULL,"Edit",NULL);
printf("%X %X",hWnd,hEdit);
char sData[100];
SendMessageA( hEdit, WM_GETTEXT, 100, (LPARAM)sData );
HWND hTarget;
int iHandle;
sscanf(sData, "%x", &iHandle);
hTarget = (HWND)iHandle;
printf(" %X",hTarget);

SendMessage(hTarget, WM_COPYDATA, NULL, (LPARAM) (LPVOID)&mystruct);

MessageBoxA(0,sData,"",0);
}

void main(){CopyDataSend();}
Edited by E1M1

edited

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Thanks for tip. Now I don't get error anymore but autoit receiver shows empty message box. Could anyone tell what's causing this?

#include "windows.h"
#include <stdio.h>
#include <string>


typedef struct tagDATATOCOPY{
     char data[5];
}DATATOCOPY;


void CopyDataSend(){

COPYDATASTRUCT mystruct;
DATATOCOPY mydata;
//mydata.data = "str";
memcpy(mydata.data, "test", 5);
mystruct.dwData = 0;
mystruct.cbData = 5;
mystruct.lpData= &mydata;

HWND hWnd = FindWindowW(NULL,L"D4672AD6-EA21-4FFD-88F5-4641A2B33E9F");
//HWND hWnd = FindWindowW(NULL,L"Untitled - Notepad");
HWND hEdit = FindWindowEx(hWnd,NULL,"Edit",NULL);
printf("%X %X",hWnd,hEdit);
char sData[100];
SendMessageA( hEdit, WM_GETTEXT, 100, (LPARAM)sData );
HWND hTarget;
int iHandle;
sscanf(sData, "%x", &iHandle);
hTarget = (HWND)iHandle;
printf(" %X",hTarget);

SendMessage(hTarget, WM_COPYDATA, NULL, (LPARAM) (LPVOID)&mystruct);

MessageBoxA(0,sData,"",0);
}

void main(){CopyDataSend();}
Are you sure your autoit script works? You send the message to a hwnd which is kept as a hexform in another window's edit control? This seems clunky and error prone, are you sure this is correct? Also, why do you define your own structures? They're all defined in <windows.h>. Also, try this:

mystruct.dwData = (void*)mydata.data; //dwData should be a unsigned long *, not dword. this can break
mystruct.cbData = 5;
mystruct.lpData= (void*)mydata.data; //lpData should be void*, not unsigned int. this can break

Also, WM_COPYDATA's wparam should be a handle to a window, i'm not sure it works if your application doesn't have a window.

Lastly, be aware of ascii/unicode compability

Edited by Shaggi

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

that (void*)mydata.data didnt help.

And yes that autoit thing works: here is full source I got from this site (can't find that topic anymore)

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#AutoIt3Wrapper_UseX64=Y

#cs
    Thanks to the following for helping in the past ...
    KaFu for the idea from _EnforceSingleInstance().
    Yashied for x64 support.
#ce

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

Global $__InterCommunication[3] = ["-GUIHandle", "-ControlID", "-Data"] ; Internal array for the WM_COPYDATA functions.

_Main()

Func _Main()
    Local $iControlID

    $iControlID = _WM_COPYDATA_Start() ; Start the communication process.
    If @error Then
        If Not _WM_COPYDATA_Send($CmdLineRaw) Then ; Send $CmdLineRaw if there is process already running.
            MsgBox(64, "2nd Instance: " & @AutoItPID, "Seems there was an @error, but more than likely $CmdLineRaw was blank.")
        EndIf
        Exit
    EndIf

    While 1
        Switch GUIGetMsg()
            Case $iControlID ; If the WM_COPYDATA message is interecepted then show your optimise function.
                _Optimise()
        EndSwitch
    WEnd
EndFunc   ;==>_Main

Func _Optimise()
    Return MsgBox(64, "1st Instance: " & @AutoItPID, _WM_COPYDATA_GetFile()) ; Get the WM_COPYDATA file.
EndFunc   ;==>_Optimise

Func _WM_COPYDATA($hWnd, $iMsg, $iwParam, $ilParam) ; WM_COPYDATA function.
    #forceref $hWnd, $iMsg, $iwParam
    Local $tData, $tParam, $tString
    $tParam = DllStructCreate("ulong_ptr;dword;ptr", $ilParam)
    $tData = DllStructCreate("wchar[" & DllStructGetData($tParam, 2) / 2 & "]", DllStructGetData($tParam, 3))
    $tString = DllStructGetData($tData, 1)
    $__InterCommunication[2] = BinaryToString($tString)
    GUICtrlSendToDummy($__InterCommunication[1])
EndFunc   ;==>_WM_COPYDATA

Func _WM_COPYDATA_GetFile() ; Retrieve the file passed via the 2nd instance.
    Return $__InterCommunication[2]
EndFunc   ;==>_WM_COPYDATA_GetFile

Func _WM_COPYDATA_Send($sString) ; Send data to the 1st instance.
    Local $hHandle = $__InterCommunication[0], $ilParam, $tData

    If $hHandle = -1 Then
        Return SetError(1, 0, 0)
    EndIf

    If StringStripWS($sString, 8) = "" Then
        Return SetError(2, 0, 0) ; String is blank.
    EndIf

    If $hHandle Then
        $tData = DllStructCreate("wchar[" & StringLen($sString) + 1 & "]")
        DllStructSetData($tData, 1, $sString)

        $ilParam = DllStructCreate("ulong_ptr;dword;ptr")
        DllStructSetData($ilParam, 1, 0)
        DllStructSetData($ilParam, 2, DllStructGetSize($tData))
        DllStructSetData($ilParam, 3, DllStructGetPtr($tData))
        _SendMessage($hHandle, $WM_COPYDATA, 0, DllStructGetPtr($ilParam))
        Return Number(Not @error)
    EndIf
EndFunc   ;==>_WM_COPYDATA_Send

Func _WM_COPYDATA_Start() ; Start the WM_COPYDATA process. Thanks to KaFu for introducing me to AutoItWinGetTitle()/AutoItWinSetTitle().
    Local $hGUI, $hHandle, $sData = "D4672AD6-EA21-4FFD-88F5-4641A2B33E9F"

    $hHandle = WinGetHandle($sData)
    If @error Then
        AutoItWinSetTitle($sData)
        $hHandle = WinGetHandle($sData)

        $hGUI = GUICreate("", 0, 0, -99, -99, "", $WS_EX_TOOLWINDOW)
        GUISetState(@SW_SHOW, $hGUI)
        ControlSetText($hHandle, "", ControlGetHandle($hHandle, "", 'Edit1'), $hGUI)
        GUIRegisterMsg($WM_COPYDATA, "_WM_COPYDATA")
        $__InterCommunication[0] = -1
        $__InterCommunication[1] = GUICtrlCreateDummy()
        Return SetError(0, 0, $__InterCommunication[1])
    Else
        $hHandle = HWnd(ControlGetText($hHandle, '', ControlGetHandle($hHandle, '', 'Edit1')))
        $__InterCommunication[0] = $hHandle
        Return SetError(1, 0, $hHandle)
    EndIf
EndFunc   ;==>_WM_COPYDATA_Start

And autoit code above is minimal code that just sends static string which I made just to see what's minimal needed to get it work..


edited

Share this post


Link to post
Share on other sites

Even though you should see some garbage text, you are still sending ascii code to your autoit, which expects unicode. Try changing your cpp to wchars.


Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

That helped. I Also figured out that cbData must be 2 bytes longer, not 1. dont know why.


edited

Share this post


Link to post
Share on other sites

It baffles me why people attempt to help somebody do something advanced like inter-process communication when clearly they don't even understand basic syntax. Then again you did just use a C-style cast so maybe that explains why.

Share this post


Link to post
Share on other sites

That helped. I Also figured out that cbData must be 2 bytes longer, not 1. dont know why.

wchars are 2 bytes wide.

It baffles me why people attempt to help somebody do something advanced like inter-process communication when clearly they don't even understand basic syntax. Then again you did just use a C-style cast so maybe that explains why.

Im sure it's the c-style casts.

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

Im sure it's the c-style casts.

Actually, it is. It shows a complete lack of critical thinking on your part. As I mentioned, the user doesn't even understand basic syntax so you provide said user with code that uses a magic C-style cast. That's a great example to teach somebody who already doesn't know what the fuck they're doing. Here's a little hint for you: People who use C-style casts do so because 1) They're writing C code (I forgive them); 2) Don't know what they are doing (I want them all to die horribly). I've had to fix stupid-ass bullshit garbage code related to idiotic use of C-style casts in C++. I've seen const cast away via C-style casting when that isn't the intent.

Back to the critical thinking part, though. The fact that you are willing to provide somebody an example using C-style casts due to a lack of critical thinking on your part also reflects on your lack of thinking about the user's question. As I also mentioned, they aren't anywhere near needing to worry about IPC. They do not understand basic syntax or basic types. Yet you are happy to provide an example of how to achieve IPC? Why? Do you want yet another shitty programmer who doesn't know what the fuck they are doing releasing garbage code into the wild? You're not just teaching somebody to blow their own foot off. You're giving them an RPG and pointing them towards an apartment building and patting them on the back saying "have fun" as you run off cackling into the night.

Stupid stupid stupid. I hope a C-style cast falls on you and breaks your face.

1 person likes this

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

The idea is to invest and learn. I like to think of it as just keep running, you will fall, get back up again. I did allot of type casting random to learn how to make a SDL_Surface linked list class. No it's not the best way, but it is the way I learned. Now I have things and systems not fully tested doing stuff I do not fully understand (not with the linked list, I scraped the idea in exchange for the speed of arrays). I still believe I have something to offer as a programmer, so I continue to code. Why wait for profection? It could hold us back. If we all keep running someone will get there.

My junk is more useful then a percentage of stuff in the wild. So where do I go now?

That helped. I Also figured out that cbData must be 2 bytes longer, not 1. dont know why.

Looks like some learning going on. I can write effective code, but I also need to learn. We don't all have 20year exp, or school when it counts. I hardly made the best of either of them. Still a straight 'A' programmer. My school was a 20k joke.

I do agree with Valik.

@E1M1 God tells me he can get me out of this mess, but he's pretty sure you're fucked

forget how to snapback, should I not even try?

Edited by Xandy

Share this post


Link to post
Share on other sites

Well if I don't get examples how I am supposed to learn? If I take C/C++ book it will teach you to write program that asks your name and age and then prints these on console but not much more.

As I also mentioned, they aren't anywhere near needing to worry about IPC

Truth to be told I wouldn't ask for something I don't need.

Do you want yet another shitty programmer who doesn't know what the fuck they are doing releasing garbage code into the wild?

Not that I want to say anything bad but did you got all your code right at first time?

edited

Share this post


Link to post
Share on other sites

Well if I don't get examples how I am supposed to learn? If I take C/C++ book it will teach you to write program that asks your name and age and then prints these on console but not much more.

And you would learn the basics that you are completely missing. Like what types are.

Truth to be told I wouldn't ask for something I don't need.

What a stupid comment. You do not need IPC. You want IPC and you want to do it now now now instead of spending time learning to do things right.

Not that I want to say anything bad but did you got all your code right at first time?

Every time I tried to do something I couldn't do I'd stop and learn all the intermediate steps. Not a single time did I stop to ask stupid questions about how to do something well beyond my experience level. I sat down with code and I experimented with it and learned how it worked. If I received compiler errors I looked those up until I understood what they actually meant and how to fix them (and avoid creating them in the first place).

I do not like your attitude. It's not about learning, otherwise you would listen to somebody who's a self-taught programmer. Instead you just attempt to argue and justify why you want to do concepts that are miles above your head. This will not be your personal C++ support forum. If you post any thread asking for C++ help it will be locked and you may optionally may be disciplined by the moderator for ignoring what you have been explicitly told. If you are unwilling to learn C++ in a sensible fashion then go annoy some other forum with your inane questions.

1 person likes this

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  
Followers 0