Aktonius Posted January 31, 2012 Posted January 31, 2012 (edited) I need help with sending wm_copydata from dll to autit. Wm_copydata sends c++ struct which has all information needed for autoit app.Struct with data sent(hwnd, wchar[1024]) is naturally stored in lpdata(ref: http://msdn.microsoft.com/query/dev10.qu...2B%22%29;k%28TargetOS-WINDOWS%)c++ code and struct sent...///////////////////////////////// //make_struct c(L"text"); // just a struct with ctor, hwnd and text(passed) are stored in struct //c.text //c.hwnd ///////////////////// COPYDATASTRUCT cds; ::ZeroMemory(&cds, sizeof(COPYDATASTRUCT)); cds.dwData = 1; cds.lpData = c; ::SendMessage(g_main, WM_COPYDATA, (WPARAM)::GetDesktopWindow(), (LPARAM)&cds);Now the receiving part from autoit. I cant figure how to slice the struct in autoit code and get info piece by piece(hwnd then text(wchar))...The only thing i managed to do is simply send wchar[1024] in lpdata, with the following code... I would prefer to send a struct as lpdata instead so i can receive hwnd as well without sending more wm_copydata messages.Func WM_COPYDATA($hWnd, $MsgID, $wParam, $lParam) Switch $hWnd Case $myform Local $tCOPYDATA = DllStructCreate("ULONG_PTR;DWORD;PTR", $lParam) Local $tMsg = DllStructCreate("WCHAR[1024]", DllStructGetData($tCOPYDATA, 3)) $sWM_COPYDATA_Received_String = DllStructGetData($tMsg, 1) ConsoleWrite("received str > "&$sWM_COPYDATA_Received_String&@LF) EndSwitch EndFunc ;==>WM_COPYDATA Edited January 31, 2012 by Aktonius
jaberwacky Posted January 31, 2012 Posted January 31, 2012 Seems like we might need more info? I do anyways. Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum?
wraithdu Posted January 31, 2012 Posted January 31, 2012 (edited) First, your C code is wrong. Reread the doc for the COPYDATASTRUCT. dwData is just some data, doesn't have to been anything. The important info is cbData, the size of the data pointed to by lpData, and the data itself. lpData is a pointer, not the struct itself, and can point to any kind of structure you want to create. If you need to pass different kinds of data, use an enumeration in dwData to tell AutoIt which structure it is receiving. Variable lengths of things like strings can be handled by checking cbData for the size. On the AutoIt side, read up on Dll structs, and create whatever struct you need for you data (you should know what the structure is going to be) and create it at the pointer received by AutoIt in the lpData member of the received COPYDATASTRUCT. Edited January 31, 2012 by wraithdu
Aktonius Posted January 31, 2012 Author Posted January 31, 2012 (edited) On the AutoIt side, read up on Dll structs, and create whatever struct you need for you data (you should know what the structure is going to be) and create it at the pointer received by AutoIt in the lpData member of the received COPYDATASTRUCT. wraithdu, yeah i know c code was wrong but that was just something wrapped in comment to show what i am doing. But hey, thanks so much for the help, i cant believe how stupidly close i was to solution. Func WM_COPYDATA($hWnd, $MsgID, $wParam, $lParam) ; http://www.autoitscript.com/forum/index....?showtopic=105861&view=findpos ; Melba23, based on code from Yashied ConsoleWrite("wm_copydata "&@LF) Switch $hWnd Case $Form2 Local $tCOPYDATA = DllStructCreate("ULONG_PTR;DWORD;PTR", $lParam) Local $tMsg = DllStructCreate("HWND;WCHAR[1024]", DllStructGetData($tCOPYDATA, 3)) $sWM_COPYDATA_Received_String = DllStructGetData($tMsg, 2) $HWND = DllStructGetData($tMsg, 1) ConsoleWrite("received str > "&$sWM_COPYDATA_Received_String&@LF) ConsoleWrite("$HWND > "&$HWND&@LF) EndSwitch EndFunc ;==>WM_COPYDATA THe only issue now that i have is that i cant get control hwnd in the dll by using struct.hwnd = ::WindowFromDC(hdc); This will only return hwnd from a window so when i receive hwnd it will only work if hdc belongs to top level window(not controls). Any idea how i could get control hwnd(listview in this case) from hdc in the c++? Thanks again edit: Oh and another thing, since i am sending wm_copydata from a dll injected in another process, hooked process has giant hogs while sending data and i am pretty sure the issue is because it waits for sendmessage to return(finish processing in my autoit gui). When i tested the same method where c app would receive this messages, there were no hogs at all. Is this because autoit is bit to slow for tasks like this? wm_copy data messages are unloaded all the time and with autoit the hooked process which sends messages will simply slow down alot while messages are processed. I was thinking to use postmessage but then wm_copydata wont work with it Edited January 31, 2012 by Aktonius
wraithdu Posted January 31, 2012 Posted January 31, 2012 Not sure about hanging the sending app, but make sure you return success (1 I think) from the AutoIt side. You should also not do any lengthy processing in the WM_COPYDATA function in AutoIt.
Aktonius Posted February 1, 2012 Author Posted February 1, 2012 any idea how to get this data then, i could store it in text file and read from there with autoit but this is kind of solution i somehow dont like
Beege Posted February 1, 2012 Posted February 1, 2012 Can't you just send the hwnd in a message? I think it would work the same way your sending all the other data. As for the delay, I have noticed it in one project of mine, but that was only because I was sending a hundreds of msgs per second. Assembly Code: fasmg . fasm . BmpSearch . Au3 Syntax Highlighter . Bounce Multithreading Example . IDispatchASMUDFs: Explorer Frame . ITaskBarList . Scrolling Line Graph . Tray Icon Bar Graph . Explorer Listview . Wiimote . WinSnap . Flicker Free Labels . iTunesPrograms: Ftp Explorer . Snipster . Network Meter . Resistance Calculator
wraithdu Posted February 1, 2012 Posted February 1, 2012 You'll need to follow guidelines on managing GUIRegisterMsg without blocking. There are examples somewhere, I just can't find them at the moment.
wraithdu Posted February 1, 2012 Posted February 1, 2012 Ah, here we go, wiki time:http://www.autoitscript.com/wiki/Interrupting_a_running_function
Yashied Posted February 1, 2012 Posted February 1, 2012 Any idea how i could get control hwnd(listview in this case) from hdc in the c++?HDC should belong to the current process. My UDFs: iKey | FTP Uploader | Battery Checker | Boot Manager | Font Viewer | UDF Keyword Manager | Run Dialog Replacement | USBProtect | 3D Axis | Calculator | Sleep | iSwitcher | TM | NetHelper | File Types Manager | Control Viewer | SynFolders | DLL Helper Animated Tray Icons UDF Library | Hotkeys UDF Library | Hotkeys Input Control UDF Library | Caret Shape UDF Library | Context Help UDF Library | Most Recently Used List UDF Library | Icons UDF Library | FTP UDF Library | Script Communications UDF Library | Color Chooser UDF Library | Color Picker Control UDF Library | IPHelper (Vista/7) UDF Library | WinAPI Extended UDF Library | WinAPIVhd UDF Library | Icon Chooser UDF Library | Copy UDF Library | Restart UDF Library | Event Log UDF Library | NotifyBox UDF Library | Pop-up Windows UDF Library | TVExplorer UDF Library | GuiHotKey UDF Library | GuiSysLink UDF Library | Package UDF Library | Skin UDF Library | AITray UDF Library | RDC UDF Library Appropriate path | Button text color | Gaussian random numbers | Header's styles (Vista/7) | ICON resource enumeration | Menu & INI | Tabbed string size | Tab's skin | Pop-up circular menu | Progress Bar without animation (Vista/7) | Registry export | Registry path jumping | Unique hardware ID | Windows alignment More...
Aktonius Posted February 1, 2012 Author Posted February 1, 2012 Ok pardon me for more question guys, notice that i am not MVP as most of you in this post @Beege I am also sendin ALOT of them because all messages contain bunch of data that is updated in real time. I cant send hwnd since hdc from listview wont return hwnd with windowfromdc(hdc). The same code and i will repeat same code again detects hwnd fine from the top level window but when it comes to hdc from the listview = nothing. Perhaps this hdc is somehow blocked from the app to not return hwnd, i dont know. @wraithdu The issue with wm_copydata is that it cant be used with anything but sendmessage() which must wait for return and therefore makes hogs. How would you avoid that blocking from that example? @Yashied I hooked to the function of the process that passes its own hdc, so i am pretty sure it belongs to the targeted process
Richard Robertson Posted February 2, 2012 Posted February 2, 2012 HDC should belong to the current process.I hooked to the function of the process that passes its own hdc, so i am pretty sure it belongs to the targeted processAnything you do with the handle to device context needs to happen in the context of the process that owns it. It has nothing to do with whether or not you have the right handle.
Aktonius Posted February 2, 2012 Author Posted February 2, 2012 Anything you do with the handle to device context needs to happen in the context of the process that owns it. It has nothing to do with whether or not you have the right handle.I am using windowfromdc() in the dll which belongs to the targeted process, so it must happen in the context of process that owns hdc no?
Richard Robertson Posted February 2, 2012 Posted February 2, 2012 I am using windowfromdc() in the dll which belongs to the targeted process, so it must happen in the context of process that owns hdc no?No, because you are calling the dll from your program. You have to actually inject a function into the target process and get that process to execute your function. This is doable at a low level, but certainly not in AutoIt without a lot of trouble.
Aktonius Posted February 2, 2012 Author Posted February 2, 2012 (edited) No, because you are calling the dll from your program. You have to actually inject a function into the target process and get that process to execute your function. This is doable at a low level, but certainly not in AutoIt without a lot of trouble.Thats exactly what i am doing. Not doing it with autoit though but through dll and detours.Anyway, after some testing, everything works fine since i figured a way to properly filter stuff that i actually need to send to my autoit app, not hogging anymore.Thanks for help everyone Edited February 2, 2012 by Aktonius
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