Jump to content

C++, Get hWnd by Class Name and PID, Almost solved but tips are welcomed.


FaridAgl
 Share

Recommended Posts

Look, in AutoIt, i can find the main window of a process this way:

Func _ProcessGetWindow($iProcessID, $sTitle, $sText = '')
Local $aWinList = WinList($sTitle, $sText)
For $i = 1 To $aWinList[0][0]
  If WinGetProcess($aWinList[$i][1]) = $iProcessID Then
   Return $aWinList[$i][1]
  EndIf
Next
EndFunc

However i believe a process can have more than one main window ( i mean windows that are not the child window of any other windows ) even with same classname, but hopefully in this case ( what i want to get to work ), it doesn't have more than one window with same classname.

What makes it a little harder to me is that i'm coding a Dll to be injected in a process, i know i can use GetCurrentProcessId() API to retrieve the PID of the process that i had injected my Dll into it.

DWORD PID = GetCurrentProcessId();

Now i want to get the handle of the window with classname "SkinWindow" and this PID.

I have no idea how to do it, however i tried a lot and i found that a combination of EnumWindows(), GetWindowThreadProcessId() is somehow a way to do it, but as i'm new to C++ and EnumWindows() needs structure, callback :-?? etc i always stuck at this.

Any help is welcomed and would be great.

Edited by D4RKON3
Link to comment
Share on other sites

You can write something yourself easily. I suspect it would look something like this:

#include <Array.au3>

Func _ProcessGetWindow($iProcessID, $sTitle, $sText = '')
    Local $aRet[1]
    Local $aWinList = WinList($sTitle, $sText)
    For $i = 1 To $aWinList[0][0]
        If WinGetProcess($aWinList[$i][1]) = $iProcessID Then
            _ArrayAdd($aRet, $aWinList[$i][1])
        EndIf
    Next
    $aRet[0] = UBound($aRet)
    Return $aRet
EndFunc
Link to comment
Share on other sites

There is also a function in WinAPIEx called _WinAPI_EnumProcessWindows.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Thanks for your attention Mat,

I'm injecting my Dll to a process, i want to change the text of some controls within one of the window of that process from the Dll, sometimes i run multiple instance of that process so FindWindow() can't be a good idea.

The process have a window, with classname SkinWindow, i want to get the Handle of this window, in other hand as i usually have multiple instance of that program running at the same time, my current code fails some times ( Cause i simply used FindWindow() and it sometimes returns the window handle of other instance of the program ), i was thinking about using GetWindowThreadProcessId() to compare the returned PID by with GetCurrentProcessId() to make sure the returned window handle belongs to the current process, but i have no idea about how to do this, actually i have the idea but i can't code it in C++.

I think a combination of,

GetCurrentProcessId()

FindWindow() or maybe FindWindowEx()

GetWindowThreadProcessId()

can do the trick, but i stuck at the step that i need to check the next window when the first window handle returned by FindWindow() doesn't match the current PID.

Please to not ask me to show my current code, cause each time i posted some C++ code i got blamed :-??

Link to comment
Share on other sites

Finally i have done it this way, working fine for me:

HWND GetGarenaWindow()
{
HWND hWnd = FindWindow("SkinWindow", NULL);
while (!ComparePIDs(hWnd))
  hWnd = FindWindowEx(NULL, hWnd, "SkinWindow", NULL);
return hWnd;
}
bool ComparePIDs(HWND hWnd)
{
DWORD CurrentPID = GetCurrentProcessId();

DWORD TargetPID = NULL;
GetWindowThreadProcessId(hWnd, &TargetPID);

if (CurrentPID == TargetPID)
  return true;
else
  return false;
}

Any suggestion for improving it?

Link to comment
Share on other sites

Stop using a 4 line if...else block to return a boolean result based on the results of a boolean test. All you need is return CurrentPID == TargetPID; which does 4 lines of work in a single line. It's much clearer, cleaner and shorter (without sacrificing readability).

Link to comment
Share on other sites

There's nothing wrong with ternaries if used correctly. I use them quite a bit (much to Jon's chagrin at one time) to initialize variables. They can lead to concise code. However, the code you show above - or the ternary equivalent - do a boolean test to return the result of that boolean test. So skip the extra lines of code. You don't need to test if something is true to return true. Just return the result of the test and you're done.

Link to comment
Share on other sites

Off-topic,

I used this to get the size of a Module:

DWORD GetModuleSize(char *ModuleName)
{
HMODULE hModule = GetModuleHandle(ModuleName);
MODULEINFO ModuleInfo = {0};
GetModuleInformation(GetCurrentProcess(), hModule, &ModuleInfo, sizeof(MODULEINFO));
return ModuleInfo.SizeOfImage;
}

Usage:

DWORD Size = GetModuleSize(NULL);

*** Using NULL returns the size of main executable, because of the behavior of GetModuleHandle(),

And i include <Psapi.h> as said here:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms683201(v=vs.85).aspx

But when i'm going to compile my source, it gives me this error:

error LNK2001: unresolved external symbol _GetModuleInformation@16
fatal error LNK1120: 1 unresolved externals

I have no idea why :|

Link to comment
Share on other sites

You have to link against psapi.lib if you want to use the executable on 2000 and XP. Read the Remarks and Requirements sections :oops:

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

OK, i'm almost agree with you but, do you know why?

I didn't started C++ from its basics but i was familiar with Computer-Programming when i started playing with C++. I had no time for learning the very basics so i had started coding what was my need exactly, it's why i'm going to be annoying by asking such questions.

I didn't forgot here is AutoIt's forum, but here is the only place i think i can find someone :|

Now, if somebodyjust answer my current question, it's a great help for me.

Link to comment
Share on other sites

For fuck's sake use Google. The very first Google result for LNK1120 takes you to MSDN which directs you to LNK2001. You were given both of those errors. USE THEM, THAT'S WHY THEY ARE THERE. Look them up. Learn what they mean and how to fix them. You don't need to ask us. THIS IS DOCUMENTED.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...