Page 1 of 1

howto get hwnd from started process?

Posted: Tue Oct 06, 2009 5:19 am
by depp69
hello,

im trying to write a small app, that starts runesofmagic and gets its hwnd.
the hwnd will then get passed to bot.lua.
passing over the hwnd to bot.lua is not the problem, but i cant get the hwnd.
this is what i tried:

Code: Select all

#include <iostream>
#include <windows.h>

using namespace std;

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM param)
{

	DWORD id = GetWindowThreadProcessId(hwnd, NULL);
	if (id == (DWORD)param)
	{
		//do whatever we want to do
		cout << hwnd << endl;
		return false;
	}
		return true;
}

int main ()
{
	char path[] = "myapp.exe";
	PROCESS_INFORMATION pi;
	
	CreateProcess(
		path,
		NULL,				// Command line.
		NULL,				// Process handle not inheritable.
		NULL,				// Thread handle not inheritable.
		FALSE,				// Set handle inheritance to FALSE.
		0,					// No creation flags.
		NULL,				// Use parent's environment block.
		NULL,				// Use parent's starting directory.	
		NULL,				// Pointer to STARTUPINFO structure.
		&pi					// Pointer to PROCESS_INFORMATION structure.
	);

	Sleep(100);
	
	::EnumWindows(&EnumWindowsProc, pi.dwThreadId);
	
	system("pause");

	return 0;
}
it doesnt even reach system("pause"), but why?
any hints or suggestions?

thanks in advance.

greetings depp

Re: howto get hwnd from started process?

Posted: Tue Oct 06, 2009 5:58 am
by Administrator
First and foremost, you should add a few printf/cout statements so you know exactly when it fails. You should also check all function return values to see if they succeeded or failed, and print a message accordingly. The first thing I noticed is that you are not providing the command line and that you are not zeroing your PROCESS_INFORMATION instance. Check MSDN for an example on how to use that function properly.

Re: howto get hwnd from started process?

Posted: Tue Oct 06, 2009 11:26 am
by depp69
thx for your help :)

the missing STARTUPINFO was the problem, but still strange that no error was given.

Re: howto get hwnd from started process?

Posted: Wed Oct 07, 2009 9:57 am
by depp69
ive got another problem, i would like to bypass the update screen
when i use a shortcut with "client.exe NoCheckVersion" it runs fine, but when i try this
from within my app, like this

Code: Select all

CreateProcess(
			"Client.exe",
			"NoCheckVersion",
			NULL,					// Process handle not inheritable.
			NULL,					// Thread handle not inheritable.
			FALSE,					// Set handle inheritance to FALSE.
			0,						// No creation flags.
			NULL,					// Use parent's environment block.
			NULL,					// Use parent's starting directory.	
			&si,					// Pointer to STARTUPINFO structure.
			&pi						// Pointer to PROCESS_INFORMATION structure.
		)
it doenst work, also it doesnt work at command prompt, any ideas?

thx in advance.

Re: howto get hwnd from started process?

Posted: Wed Oct 07, 2009 5:21 pm
by Administrator
Your command line is wrong. You must use the fully qualified path to the executable and then the arguments. This means, use something like "C:\\Program Files\\Runes of Magic\\Client.exe NoCheckVersion". It must be exactly like what is normally passed to Client.exe from the launcher. If you aren't sure how it should look, create your own Client.exe (after backing up the real one) to dump the values:

Code: Select all

int main(int argc; char **argv)
{
  for(unsigned int i = 0; i < argc; i++)
  {
    printf("arg[%d]: %s\n", i, argv[i]);
  }

  system("pause");
  return 0;
}

Re: howto get hwnd from started process?

Posted: Wed Oct 21, 2009 5:02 am
by depp69
hmm after many tries i still cant get it working ...
now im using shellexecute to start with NoCheckVersion and it works
but i have to enumerate through all windows and search by title.
so i need some kind of rom window list to check wether its the right one
or not, like checking for rom windows before i start my own, and checking after
start for new rom windows ...

Re: howto get hwnd from started process?

Posted: Wed Oct 21, 2009 7:12 am
by Administrator

Code: Select all

BOOL CALLBACK findWindowProc(HWND hwnd, LPARAM lparam)
{
    EnumWindowPair *winpair = (EnumWindowPair *)lparam;
    char namestring[2048];
    GetWindowText(hwnd, (char *)&namestring, 2047);

    int match = wildfind(sztolower(winpair->windowname),
        sztolower((char*)&namestring));

    if( match )
    {
        // Looking for just the window, not a specific classname
        if( winpair->classname.compare("") == 0 )
        {
			// Ensure that this isn't a window preview/overlay
			char tmpBuf[256];
			GetClassName(hwnd, (char*)&tmpBuf, 256);

			if( tmpBuf && !strcmp((char*)&tmpBuf, windowThumbnailClassName))
			return true;

            winpair->hwnd = hwnd;
            return false;
        }
        else
        {
			// Check if this window is valid itself
			char tmpBuf[256];
			GetClassName(hwnd, (char*)&tmpBuf, 256);
			if( strcmp(tmpBuf, winpair->classname.c_str()) == 0 )
			{
				// We have a match
				winpair->hwnd = hwnd;
				return false;
			}

			// If not, scan it's children
            HWND controlHwnd = FindWindowEx(hwnd, NULL,
                winpair->classname.c_str(), NULL);

            if( controlHwnd == NULL )
                return true;

            // We have a match
            winpair->hwnd = controlHwnd;
            return false;
        }
    }
    else
        return true;
}

HWND ProcessDevice::findWindow(std::string name, std::string classname,
    int &err)
{
    err = 0;
    EnumWindowPair searchpair;
    searchpair.windowname = name;
    searchpair.classname = classname;
    searchpair.hwnd = 0;

    EnumWindows(findWindowProc, (LPARAM)&searchpair);

    if( searchpair.hwnd == 0 )
        err = GetLastError();

    return searchpair.hwnd;
}