-
Windows handles
Hi,
I'm trying to write a program that will automate a process for me based on the text output in a scroll window belonging to another app. The first step is that I need to be able to get the handle for the window in question but I'm not sure how to do this.
So, can someone tell me how to get a list of all the current active windows ?
Thanks,
Marc
-
EnumWindows() and EnumChildWindows() would be a good starting point.
-
-
That's great, thanks.
While I'm at it, once I have these handles, can I send messages to any child window of one of these parent windows belonging to another app ? For example, could I even register a mouse button press on a button belonging to the window just by sending it the appropriate message ?
Apologies if these are basic questions - I'm an experienced coder but just not to windows.
-
You would use the SendMessage function, its prototype is:
SendMessage(HWND hwnd, UINT message, WPARAM, LPARAM)
Below are 2 examples one basic which writes characters to the notepad window and one slightly more general which was originally provided by Lucky.
Basic:
Code:
#include <windows.h>
#include <stdio.h>
int main(void)
{
char chars[] = "abc";
HWND hwndNotepad, hwndChild;
//query for notepad
hwndNotepad = FindWindow(NULL, "Untitled - Notepad");
if(hwndNotepad == NULL)
{
printf("error! HWND notepad = NULL\n");
return(0);
}
//query for the child window(edit control)
hwndChild = GetWindow(hwndNotepad, GW_CHILD);
//send our message
if(!(hwndChild == NULL)) {
for(int a = 0; a<4; a++) {
SendMessage(hwndChild, WM_CHAR, (WPARAM)chars[a], 1);
}
}
return 0;
}
General(provided by Lucky):
Code:
#include <windows.h>
#include <tchar.h>
// use some default text if none is supplied on the command line
static LPCTSTR DEFAULT_MSG = _T("This text was automatically inserted.");
// a container to pass to arguments - the string and it's length
struct StringMsg {
int nLength;
LPCTSTR pszText;
};
// iteratively process each child window of the pass HWND
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) {
// first we determine the classname
TCHAR szClassName[32];
GetClassName(hwnd, szClassName, 32);
// if it is not an edit window, we'll just continue with
// the next child window
if (_tcsncmpi(szClassName, _T("EDIT"), 4) != 0)
return TRUE;
// otherwise we auto-type something into the edit window and
// cease the enumeration
StringMsg *pMsg = (StringMsg*)lParam;
for (int i = 0; i < pMsg->nLength; ++i)
SendMessage(hwnd, WM_CHAR, pMsg->pszText[i], 0);
return FALSE;
}
// this is called for every top-most HWND
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
TCHAR szClassName[32];
GetClassName(hwnd, szClassName, 32);
// determine if it is our target application window
if (_tcsncmpi(szClassName, _T("NOTEPAD"), 7) == 0)
// if it is, we'll enumerate it's children and let that
// enumeration handle finding the target control and doing
// our dirty work, then stop looking
if (!EnumChildWindows(hwnd, EnumChildProc, lParam))
return FALSE;
// otherwise we just keep looking
return TRUE;
}
// program entry point
// pass a string on the command line or let the default text
// be used
int _tmain(int argc, TCHAR **argv) {
StringMsg sm;
// argument? use it
if (argc > 1) {
sm.nLength = _tcslen(argv[1]);
sm.pszText = argv[1];
}
// none? use ours
else {
sm.nLength = _tcslen(DEFAULT_MSG);
sm.pszText = DEFAULT_MSG;
}
// enumerate all the top-level windows
EnumWindows(EnumWindowsProc, (LPARAM)&sm);
return 0;
}
Happy Coding!!!
-
Thanks,
I've started using SendMessage ( ) with EM_GETLINECOUNT and EM_GETLINE and that seems to be retrieving the text for me.
I plan to just keep a count of the line count when I last read and the new line count to get new content added to the window.
Much appreciated,
Marc
-
The basic example above isn't working. I am using Pelles C for Windows as a compiler.
It compiles ok but when I tell it to build I get errors:
Building window.exe.
POLINK: error: Unresolved external symbol '__imp__FindWindowA'.
POLINK: error: Unresolved external symbol '__imp__GetWindow'.
POLINK: error: Unresolved external symbol '__imp__SendMessageA'.
POLINK: fatal error: 3 unresolved external(s).
*** Error code: 1 ***
Done.
:(
-
Looks like you need to link with user32.lib.
-