Jump to content
Sign in to follow this  
FaridAgl

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

Recommended Posts

FaridAgl

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

Share this post


Link to post
Share on other sites
jvanegmond

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

Share this post


Link to post
Share on other sites
guinness

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

Share this post


Link to post
Share on other sites
FaridAgl

I'm so sorry,

Maybe i asked my question in a wrong way,

I'm trying to do it in C++ not AutoIt :|

BTW, thanks for the time you'd spent on my thread.

Share this post


Link to post
Share on other sites
FaridAgl

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 :-??

Share this post


Link to post
Share on other sites
FaridAgl

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?

Share this post


Link to post
Share on other sites
Valik

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).

Share this post


Link to post
Share on other sites
FaridAgl

Wow, i can name it the tips of the day.

I remember i used something with " ? true:false " in my other thread but you rejected using that, may i know why? Cause i saw it in some almost professorial source, how ever i stopped using that and used a 4 line if...else instead :|

Share this post


Link to post
Share on other sites
Valik

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.

  • Like 1

Share this post


Link to post
Share on other sites
FaridAgl

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 :|

Share this post


Link to post
Share on other sites
ProgAndy

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

Share this post


Link to post
Share on other sites
FaridAgl

I'm on Windows 7 Ultimate 32-bit

And if it's matter, i'm coding a Dll to be injected on a process, i'm almost done.

How to link something? I saw Linker settings on my project's setting but i have no idea where and what to link.

Share this post


Link to post
Share on other sites
Valik

You should not be injecting code if you do not have basic understanding of how your linker works.

Share this post


Link to post
Share on other sites
FaridAgl

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.

Share this post


Link to post
Share on other sites
Valik

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.

  • Like 1

Share this post


Link to post
Share on other sites
Valik

I deleted your last post. Think about some of the content of that post, please.

Share this post


Link to post
Share on other sites
FaridAgl

OK, sorry, i didn't realize the forum rules about AutoIt should be followed about C++ too.

Share this post


Link to post
Share on other sites
Valik

/facepalm

  • Like 1

Share this post


Link to post
Share on other sites
Richard Robertson

OK, sorry, i didn't realize the forum rules about AutoIt should be followed about C++ too.

  • Like 1

Share this post


Link to post
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
Sign in to follow this  

×