FindWindow Function

Posts 1–9 of 9 · Page 1 of 1
FindWindow Function
The problem isn't actually the code it works I can find any window like minesweeper for example but I cannot find the game I want to use it for. When you play it searches for patches then loads the client and its window is labelled as "game", while its loading I can find the window, but once the game fully loads the game window changes to "Talisman Online | ver.2030" and no matter what I seem to do I can't find the window at this point using the FindWindow function. Can it read "|"? or well what is wrong.. If anybody could enlighten me i would be awful grateful
Hmm... I don't see the 'vertical bar/pipe' on the standard ascii table: http://www.asciitable.com/index/asciifull.gif

Most functions that take string arguments are overloaded: one expecting a 1-byte-per-character ascii string and the other a 'wide string'

FindWindowA() = ascii version
FindWindowW() = wide-string version

You'll see a lot of functions that end in 'A' and 'W'.

If you look at the functions' argument lists, you can see they expect either LPCSTR or LPCWSTR


which are typedefs for


CHAR typedef'd for "char", and WCHAR for "wchar_t"

edit: pipe character must be in the 128-255 range (?): visualstudio will let you define a regular string with the pipe char in it..
LPCSTR myStr = "Talisman Online | ..."; // works fine

test something like this:
Thank you, but this still didn't work. I mean the code works, and I can find any window name except once again Talisman's... Could I find the Window name using the exe. or PID, Or should I even try to find the Active Window? Cheat Engine shows the process as "00000508-client.exe" Task Manager's program list shows the same as the windows title "Talisman Online | ver.2030" but in the process list it is "client.exe" and UOPilot (UOPilot is a general automated macro program) lists the workwindow handle "12387396" and "1288" next to the name of the window which is again "Talisman Online | ver.2030"
Try to use the Window Class name, not the window title.

Usually, the window class gives less problems than the title. You can find the class of any windows using the Spy++ tool under Tools → Spy++ on Visual Studio.

Once open, it will display something like this:


When you find the window you want, right click it, go to Properties, then go to the Class tab and you'll see the Class Name.


And then you can use it like this:
Code:
HWND windowHandle = FindWindow("USurface_266139671", NULL);
Quote Originally Posted by abuckau907 View Post
Hmm... I don't see the 'vertical bar/pipe' on the standard ascii table: http://www.asciitable.com/index/asciifull.gif
I think it is 0x7C.
Quote Originally Posted by MarkHC View Post

I think it is 0x7C.
..I looked a couple times and didn't see it. Thanks.


@OP post code please. You asked 'should I even bother finding the window' ..well...if you don't need a handle to the window, then don't, but you *should* be able to. If your goal is read/writeprocessmemory, then no you probably don't need it. You still need a way to find your specific target process tho ==> "in the process list it is 'client.exe'"
@WhiteBoiNic I had nothing better to do so I downloaded the game to see what could be going on. It turns out the window title it's not always the same (it changes when you enter a server, when you change servers, when you're on the main menu and so on. It also changes the Class Name every time you open the game.

So, that means you cannot use FindWindow to get the handle because both the title and class aren't static. What you have to do is iterate through all open windows and find the one you want.

Here's the code for that. I commented the code so hopefully you can understand what it does.

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

using namespace std;

//Callback function. This function will be called for every open window
BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam ) {
	int* found = reinterpret_cast<int*>(lParam); //Pointer to hold the result
	char szClassName[80], szTitle[80];

	GetClassNameA( hwnd, szClassName, sizeof(szClassName) ); //Gets the current window's class name
	GetWindowTextA( hwnd, szTitle, sizeof(szTitle) ); //Gets the current window's title

	if( strstr( szTitle, "Talisman Online" ) ) { //If the title contains the string
		cout << "Window title: " << szTitle << endl;
		cout << "Class name: " << szClassName << endl << endl;
		*found = 1; //We found what we wanted
	}
	return TRUE;
}

BOOL FindGameWindow() {
	int iFound = 0;
	//Enumerates all open windows.
	//It will call EnumWindowsProc for every window it finds.
	EnumWindows( EnumWindowsProc, reinterpret_cast<LPARAM>( &iFound ) );
	return iFound == 1;
}
// Main routine.
int main( int argc, char **argv ) {
	
	while( !FindGameWindow() ) {
		Sleep( 500 );
	}
	std::cout << "FOUND" << endl;

	system( "pause" );
	return 0;
}
Enumerate through running processes and check for the executable name:

Code:
#include <windows.h>
#include <Psapi.h>

#pragma comment(lib, "Psapi.lib")
#pragma comment(lib, "User32.lib")      // Just for the messagebox

#define APPLICATION_NAME "client.exe"

bool CheckProcess(DWORD processID)
{
    char szProcessName[MAX_PATH];
    memset(szProcessName, 0x0, sizeof(szProcessName));

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,              // Less access would be fine depending on what you want to do
                                  FALSE, processID);
    if(hProcess != NULL)
    {
        GetModuleBaseName(hProcess, NULL, szProcessName, sizeof(szProcessName));

        if(strcmp(szProcessName, APPLICATION_NAME) == 0)
        {
            MessageBoxA(NULL, "Found the process!", "Found", MB_OK);
            return true;
        }
    }

    CloseHandle( hProcess );
    return false;
}

bool CheckAllProcesses()
{
    DWORD aProcesses[1024], cbNeeded, cProcesses;

    if (!EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded))
    {
        return false;
    }

    cProcesses = cbNeeded / sizeof(DWORD);
    for (int i = 0; i < cProcesses; i++)
    {
        if(aProcesses[i] != 0)
        {
            CheckProcess(aProcesses[i]);
        }
    }
    return true;
}

int main()
{
    CheckAllProcesses();
    return 0;
}
Quote Originally Posted by MarkHC View Post
@WhiteBoiNic I had nothing better to do so I downloaded the game to see what could be going on. It turns out the window title it's not always the same (it changes when you enter a server, when you change servers, when you're on the main menu and so on. It also changes the Class Name every time you open the game.

So, that means you cannot use FindWindow to get the handle because both the title and class aren't static. What you have to do is iterate through all open windows and find the one you want.

Here's the code for that. I commented the code so hopefully you can understand what it does.

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

using namespace std;

//Callback function. This function will be called for every open window
BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam ) {
	int* found = reinterpret_cast<int*>(lParam); //Pointer to hold the result
	char szClassName[80], szTitle[80];

	GetClassNameA( hwnd, szClassName, sizeof(szClassName) ); //Gets the current window's class name
	GetWindowTextA( hwnd, szTitle, sizeof(szTitle) ); //Gets the current window's title

	if( strstr( szTitle, "Talisman Online" ) ) { //If the title contains the string
		cout << "Window title: " << szTitle << endl;
		cout << "Class name: " << szClassName << endl << endl;
		*found = 1; //We found what we wanted
	}
	return TRUE;
}

BOOL FindGameWindow() {
	int iFound = 0;
	//Enumerates all open windows.
	//It will call EnumWindowsProc for every window it finds.
	EnumWindows( EnumWindowsProc, reinterpret_cast<LPARAM>( &iFound ) );
	return iFound == 1;
}
// Main routine.
int main( int argc, char **argv ) {
	
	while( !FindGameWindow() ) {
		Sleep( 500 );
	}
	std::cout << "FOUND" << endl;

	system( "pause" );
	return 0;
}
That works perfectly although there are a few things I don't quite understand the comments help me grasp the basic idea of what is being done. Now I've hit a roadblock trying to read the memory I have tried a few different approaches not with much success. Trial and error is the best way to learn... right? Thanks for the help
If you really need the window. You can use EnumWindows() with a callback and pass the process ID as lparam. The code i posted isnt the best. But it finds the Window by Process ID. And if the process has windows it attempts to close them gracefully. It isn't exactly what you are looking for. But I have it from an old project.
Code:
#include <iostream>
#include <windows.h>
#include <TlHelp32.h>

using namespace std;
DWORD GetOutlookPID();
BOOL CALLBACK CloseOutlook(HWND hWnd,LPARAM lParam);
int main()
{
    cout << "Exiting Outlook"<<endl;
    cout<<endl;
    DWORD PID = 0;
    PID = GetOutlookPID();
    EnumWindows((WNDENUMPROC)*CloseOutlook,(LPARAM)PID);
    return 0;
}

BOOL CALLBACK CloseOutlook(HWND hWnd,LPARAM lParam)
{
    DWORD PID =  (DWORD)lParam;
    DWORD test = 0;
    DWORD ProcessID = 0;
    DWORD dWait;
    bool retValue = true;
    HANDLE hHandle;
    do
    {
        GetWindowThreadProcessId(hWnd,&ProcessID);
        test = GetLastError();
        if(ProcessID == PID)
        {
            DWORD dWait;
            if(PostMessage(hWnd,WM_CLOSE,0,0) != 0)
            {
                hHandle = OpenProcess(PROCESS_TERMINATE|SYNCHRONIZE,false,PID);
                dWait = WaitForSingleObject(hHandle,300);
                if(dWait != WAIT_OBJECT_0)
                {
                /*if(dWait == WAIT_FAILED || dWait == WAIT_TIMEOUT)
                {
                    TerminateProcess(hHandle,0);
                }*/
            }
        }
        retValue = false;
    }
    else
    {
        retValue = true;
    }
    }while(test == 0);
    return retValue;
}

DWORD GetOutlookPID()
{
    TCHAR * tName = "OUTLOOK.EXE\0";
    HANDLE hProcess;
    DWORD ProcessID;
    PROCESSENTRY32 PE;
    PE.dwSize = sizeof(PE);
    bool bSuccess, bSuccess2 = true;
    hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
    if(hProcess != INVALID_HANDLE_VALUE)
    {
        bSuccess = Process32First(hProcess,&PE);
        if(bSuccess == true)
        {
            if(strcmp(PE.szExeFile,tName)==0)
            {
                ProcessID = PE.th32ProcessID;
            }
            else
            {
                do
                {
                    bSuccess2 = Process32Next(hProcess,&PE);
                    if(bSuccess2 == true)
                    {
                        if(strcmp(PE.szExeFile,tName) == 0)
                        {
                            ProcessID = PE.th32ProcessID;
                        }
                    }
                }while(bSuccess2 == true);
            }
        }
        CloseHandle(hProcess);
    }
    return ProcessID;
}
Posts 1–9 of 9 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?