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?
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.
Looks like C to me. But anyway. You are also using if(Result = false) which looks like you missed an equals sign
Yep, 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++.
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).
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 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.
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++.
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++.
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.
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 *.
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?
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++.