FaridAgl Posted February 20, 2012 Share Posted February 20, 2012 In AutoIt we have ControlSetText that works with CtrlID or Ctrl Classname, i'm going to do such thing in C++, it works fine with CtrlID but i'm looking for a way to use ClassnameNN ( What AutoIt Info gives me ) rather than CtrlID, take a look at my code please.Function:int ControlSetText(char * WindowClass, int CtrlID, char * Text) { HWND hWnd = FindWindow(WindowClass, NULL); if (hWnd == NULL) return -1; HWND hCtrl = GetDlgItem(hWnd, CtrlID); if (hCtrl == NULL) return -2; LRESULT Result = SendMessage(hCtrl, WM_SETTEXT, NULL, (LPARAM)Text); if (Result = false) return -3; return 1; }Usage:ControlSetText("Notepad", 15, "Test Text");As you can see, this function takes CtrlID (15 in here), it's Notepad's main Edit control with ClassnameNN "Edit1", is there any possibility to use "Edit1" instead of 15? http://faridaghili.ir Link to comment Share on other sites More sharing options...
Mat Posted February 20, 2012 Share Posted February 20, 2012 (edited) Looks like C to me. But anyway. You are also using if(Result = false) which looks like you missed an equals sign The number is the instance, the "Edit" bit is the classname. Enumerate through all child windows with the "Edit" class until you reach the Nth one (in this case it's the first one). In terms of making a C function that does that, you'd probably want to have a function more like: int ControlSetText( char* WindowClass, char* ControlClass, int ControlInstance, char* text ) Saves you having to go through the messy task of splitting up the string and checking to make sure it's in the right format. When I said enumerate further up, I didn't mean blindly EnumChildWindows, Something like this instead: int i; HWND ret; ret = NULL; for ( i = 0; i < ControlInstance; i++ ) { ret = FindWindowEx( hParent, ret, ControlClass, NULL ); } That will find child windows of hParent with class name ControlClass, starting with the control after ret, so each iteration finds the Nth item. I don't know of any way to do that directly. Edited February 20, 2012 by Mat AutoIt Project Listing Link to comment Share on other sites More sharing options...
FaridAgl Posted February 20, 2012 Author Share Posted February 20, 2012 Looks like C to me. But anyway. You are also using if(Result = false) which looks like you missed an equals signYep, my miss. Thanks for your great explanations, i get it to work using your method, here it is, tested in several windows and controls and working fine. bool ControlSetText(char *WindowClass, char *ControlClass, int ControlInstance, char *Text) { HWND hwndParent = FindWindow(WindowClass, NULL); if (hwndParent == NULL) return false; HWND hwndChildAfter = NULL; for (int i = 0 ; i < ControlInstance ; i++) hwndChildAfter = FindWindowEx(hwndParent, hwndChildAfter, ControlClass, NULL); LRESULT Result = SendMessage(hwndChildAfter, WM_SETTEXT, NULL, (LPARAM)Text); if (Result == NULL) return false; return true; } Now that i can find any control handle withing any window using Classname and Instance, i'm pretty sure i can easily code most of AutoIt's control related functions in C++. Thanks Mat. http://faridaghili.ir Link to comment Share on other sites More sharing options...
Mat Posted February 20, 2012 Share Posted February 20, 2012 If you want to do that, then write the WinGetHandle and ControlGetHandle functions first and get other functions to call that. Even if they are just wrappers for FindWindow(Ex). FaridAgl 1 AutoIt Project Listing Link to comment Share on other sites More sharing options...
FaridAgl Posted February 20, 2012 Author Share Posted February 20, 2012 Some simple funcs:WinGetHandleWinActiveWinExistsWinGetProcessHWND WinGetHandle(char *WindowClass) { return FindWindow((LPCTSTR)WindowClass, NULL); } bool WinActive(HWND WindowHandle) { return GetForegroundWindow() == WindowHandle ? true:false; } bool WinExists(char *WindowClass) { return FindWindow((LPCTSTR)WindowClass, NULL) != NULL ? true:false; } DWORD WinGetProcess(HWND WindowHandle) { DWORD PID = NULL; GetWindowThreadProcessId(WindowHandle, &PID); if (PID != NULL) return PID; else return NULL; } http://faridaghili.ir Link to comment Share on other sites More sharing options...
Valik Posted February 20, 2012 Share Posted February 20, 2012 Well that code's a horror show. You're missing some basics. Rule #138: If you find that you have to use a cast a lot then you're using the wrong type somewhere to begin with. You also failed to even think about some of the code. You test PID for non-NULL and then return it's value, or you return NULL. What did that code accomplish? Link to comment Share on other sites More sharing options...
Mat Posted February 20, 2012 Share Posted February 20, 2012 Also the: return test ? true : false AutoIt Project Listing Link to comment Share on other sites More sharing options...
Valik Posted February 20, 2012 Share Posted February 20, 2012 Mat, that's also superfluous. The same is accomplished by return Result != NULL. Link to comment Share on other sites More sharing options...
FaridAgl Posted February 20, 2012 Author Share Posted February 20, 2012 (edited) Well that code's a horror show. You're missing some basics. Rule #138: If you find that you have to use a cast a lot then you're using the wrong type somewhere to begin with. You also failed to even think about some of the code. You test PID for non-NULL and then return it's value, or you return NULL. What did that code accomplish? Well, actually you are right about the PID, thanks for that. I usually make some mistakes in my codes and i need to reread them later with more focus to fix them out. I'm almost a beginner in C++, but i like it and i'm trying to learn more. These codes aren't a challenge for me, just some kind practices for further uses. An important thing about me, i never forget what i learned. I made these function so far, at least working for me. WinGetHandle WinActive WinExists WinGetProcess WinSetState WinMove However i believe what AutoIt presents in similar functions are extremely better, but at the moment i'm in a situation that i MUST write some of these functions in C++. expandcollapse popupHWND WinGetHandle(char *WindowClass) { return FindWindow((LPCTSTR)WindowClass, NULL); } bool WinActive(char *WindowClass) { HWND hWnd = WinGetHandle(WindowClass); if (GetForegroundWindow() == hWnd) return true; else return false; } bool WinExists(char *WindowClass) { HWND hWnd = FindWindow((LPCTSTR)WindowClass, NULL); if (hWnd != NULL) return true; else return false; } DWORD WinGetProcess(char *WindowClass) { HWND hWnd = WinGetHandle(WindowClass); DWORD PID = NULL; GetWindowThreadProcessId(hWnd, &PID); return PID; } bool WinSetState(char *WindowClass, int State) { HWND hWnd = WinGetHandle(WindowClass); if (ShowWindow(hWnd, State) != 0) return true; else return false; } bool WinMove(char *WindowClass, int X, int Y) { HWND hWnd = WinGetHandle(WindowClass); if (SetWindowPos(hWnd, HWND_TOP, X, Y, 0, 0, SWP_NOSIZE) != 0) return true; else return false; } Edited February 20, 2012 by D4RKON3 http://faridaghili.ir Link to comment Share on other sites More sharing options...
Mat Posted February 20, 2012 Share Posted February 20, 2012 Mat, that's also superfluous. The same is accomplished by return Result != NULL.That's why I posted it.As a C programmer, the only thing you are using in your code that is C++ is the bool type. If you replaced that with the winapi BOOL type and used TRUE and FALSE instead of true and false then you'd be writing C, not C++. On the other hand, if you are writing C++, you should probably be exposing functions that take string arguments (then using c_str() before passing it to the functions), rather than char*. Not that I have any expertise whatsoever with C++. AutoIt Project Listing Link to comment Share on other sites More sharing options...
Valik Posted February 20, 2012 Share Posted February 20, 2012 These codes aren't a challenge for me, just some kind practices for further uses.So that's why almost every single thing about the code is wrong?Assuming you are writing C then you're using a C++ type (bool) so that's wrong. Assuming you are using C++ then you are using C-style casts which is wrong. See this bug? The root cause of that is a C-style cast done by somebody who doesn't understand what their code does. What's cast away is const. This allows a const string which has it's lifetime managed elsewhere to be returned from a function it shouldn't be returned from. This string is later deleted incorrectly which leads to undefined behavior when it's deleted for a second time. Production releases of AutoIt act weird, running it under the debugger generates an assertion. All because somebody thought lazy C-style casts were a good idea.No matter what language the casts are just plain wrong to begin with. LPCTSTR is defined as const wchar_t * if the UNICODE flag is set. That is not the same thing as the char *you are passing. Either do not cast at all (if you only need to use the ANSI version) or your functions need to take LPCTSTR parameters if you do care about ANSI/UNICODE compatibility.In addition your input parameters are not declared as const. Believe it or not const-correctness is important and should be learned early only. We've already discussed the other problems in the code concerning return values. Link to comment Share on other sites More sharing options...
FaridAgl Posted February 20, 2012 Author Share Posted February 20, 2012 (edited) Thanks to both of you, i never said i know everything about C & C++ or i'm an expert, as i said i'm new to C & C++ and i'm just trying to learn.Your comments are great for me Valik.Mat. thanks for c_str(), now i will use an string object instead of char *.Thanks guys. Edited February 20, 2012 by D4RKON3 http://faridaghili.ir Link to comment Share on other sites More sharing options...
FaridAgl Posted February 21, 2012 Author Share Posted February 21, 2012 After all of these, i finally found something :| AutoItX3.dll and AutoIt3.h I can include AutoIt3.h in my C++ source, but what else should i do to become able to use AutoIt functions? I need a little help to get it to work. An other question, when i compiled my source and want to use it some where else, i mean on a windows without AutoIt installed, do i need to copy the AutoItX3.dll ? If it helps, i should say i'm coding a Dll to inject it, AutoItX3.dll will work in this case as well as exe projects? http://faridaghili.ir Link to comment Share on other sites More sharing options...
FaridAgl Posted February 22, 2012 Author Share Posted February 22, 2012 OK, so far i had included AutoItX.h in my project, then i tried these codes: AU3_BlockInput(1); AU3_Sleep(5000); AU3_BlockInput(0); But it gives me these errors: error LNK2001: unresolved external symbol _AU3_Sleep@4 error LNK2001: unresolved external symbol _AU3_BlockInput@4 fatal error LNK1120: 2 unresolved externals http://faridaghili.ir Link to comment Share on other sites More sharing options...
Richard Robertson Posted February 23, 2012 Share Posted February 23, 2012 Did you actually link to the dll in your linker settings? Link to comment Share on other sites More sharing options...
FaridAgl Posted February 23, 2012 Author Share Posted February 23, 2012 Not exactly, A little help can be great. http://faridaghili.ir Link to comment Share on other sites More sharing options...
Mat Posted February 23, 2012 Share Posted February 23, 2012 Not exactly? So no. Google it. AutoIt Project Listing Link to comment Share on other sites More sharing options...
FaridAgl Posted February 23, 2012 Author Share Posted February 23, 2012 Give me some links at least, i do not know to search for what. I'm using Visual C++ Express 2010. http://faridaghili.ir Link to comment Share on other sites More sharing options...
Valik Posted February 23, 2012 Share Posted February 23, 2012 You don't know what to search for? You have an error ID there. You have an error string there. I'm pretty fucking sure you have everything you need to look up your problem online. If you can't... then you aren't ready for C++. Link to comment Share on other sites More sharing options...
FaridAgl Posted February 23, 2012 Author Share Posted February 23, 2012 I'm trying to understand how C++ works, no matter if you like to blame me. http://faridaghili.ir 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