Click to See Complete Forum and Search --> : SetWindowsHookEx - Controlling other process?


teleplayr
June 1st, 2004, 08:21 AM
Hey, all. I'm trying to hook another GUI process so I can alter the data in some edit boxes.

I have the window handle of the app, and i have the PID of the app, retrieved with

GetWindowThreadProcessId();


The problm I have is, SetWindowsHookEx() wants a Thread ID, not a process ID. In other words, this code fails with error 87, BAD_PARAM:


GetWindowThreadProcessId(hDlg, &pid);
sg_hHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)pHookProc, hRes, pid);

if (sg_hHook == NULL)
{
// Process error
}


But this code passes:


sg_hHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)pHookProc, hRes, GetCurrentThreadId());

if (sg_hHook == NULL)
{
// Process error
}


But then my app just hooks itself :)

So, is there a way to convert that PID iinto a Thread ID? Or, is there a better way to meddle with another applications edit controls?

Thanks,

-Joe

Bond
June 1st, 2004, 09:04 AM
If you just want to set/retrieve text from another processes edit controls, you can use just post WM_SETTEXT and WM_GETTEXT messages to it.

Use FindWindow and/or FindWindowEx to get a handle to the edit control window and send it a message.

Do not use SetWindowText or GetWindowText. You must use SendMessage.

Bond
June 1st, 2004, 09:28 AM
For example, here is how you can get the text from Internet Explorer's address bar edit control:

// This is the "family tree" from IE's main window to the edit control...
static const TCHAR szClassNames[][64] = {
TEXT("WorkerW"),
TEXT("ReBarWindow32"),
TEXT("ComboBoxEx32"),
TEXT("ComboBox"),
TEXT("Edit")
};

// This is the number of generations (windows) in the family...
static const int iWindows = sizeof(szClassNames) / sizeof(szClassNames[0]);

// Get the handle to the IE window (currently on Google.com)...
HWND hIe = FindWindow(NULL, "Google - Microsoft Internet Explorer");

if (hIe == NULL)
{
// Couldn't find the main IE window...
return -1; // Error
}

// Start with the top level window...
HWND hChild = hIe;

// And continue getting children until we reach the edit control...
for (int i = 0; i < iWindows; i++)
if (!(hChild = FindWindowEx(hChild, NULL, szClassNames[i], NULL)))
return -1; // Error

// We now have a handle to IE's address bar edit control. Get the text...
TCHAR szUrl[MAX_PATH] = {0};
SendMessage(hChild, WM_GETTEXT, (WPARAM) sizeof(szUrl), (LPARAM) szUrl);

// szUrl should now contain "http://www.google.com"

teleplayr
June 1st, 2004, 09:40 AM
Bond,

Thanks. I was able to get text, but not set text. I was using GetWindowText and SetWindowText. I changed it to use SendMessage, and it works just fine. Thanks.

Back to my original question, though, there must be a way to get the Thread ID. I'd still like to be able to hook the window procedure.

-Joe

sephiroth2m
June 1st, 2004, 10:29 AM
Hi teleplayr, pliz read more about GetWindowThreadProcessId and GetCurrentThreadId's documentation :D. GetWindowThreadProcessId returns both Process ID and Thread ID of a specific window, while GetCurrentThreadId returns Thread ID of the current window.
Regards

Bond
June 1st, 2004, 10:40 AM
Why not just subclass it?

teleplayr
June 1st, 2004, 02:05 PM
sephiroth2m,

I'm not sure how I missed that in the documentation. Thanks :)

Bond,

Yes, I could, thanks.

-Joe