Windows Get Forground Proces Name and Process ID

Hello,

I am trying to get forground process name and id. I could get process id active window with the code below. But returned processid was not correct. Proceses id is not returning correctly.

Ty

//Example:
Declare Function GetForegroundWindow Lib “user32.dll” As Integer
var dwPID as Integer
Soft Declare Function GetWindowThreadProcessId Lib “User32.dll” ( hwnd As Integer,dwPID as Integer ) as Integer
dim sonucpid as integer
sonucpid=GetWindowThreadProcessId(GetForegroundWindow(),dwPID)
return sonucpid.ToString

Well, in our WindowsListMBS class, we have a function ForegroundWindow to also give you the handle to the front window.
Then you can use WindowsListMBS class to loop over windows to find this handle WindowHandle(index) and pick WindowImageFileName(index) to get file path for the process. That should point to the exe, wehre you can extract the name part.

I checked WindowsList. i can id get by ForegroundWindowHandle func.
What is the returned value from ForegroundWindowHandle ? I think its not PID.
Do you have any other example ?

Ty very much.

dim w as new WindowsListMBS
TextArea1.AddText(w.ForegroundWindowHandle.ToString+EndOfLine)

I was able to get it with WindowImageFileName(index).

Thank you very much.
Best Regards

1 Like

You missed the ByRef on the declare of GetWindowThreadProcessId as it returns the value you need there.

Here’s the code if anyone wants to do it without plugins:

Declare Function GetForegroundWindow Lib "User32.dll" () As Integer
Declare Function GetWindowThreadProcessId Lib "User32.dll" (hwnd As Integer, ByRef dwPID As Integer) As Integer

Declare Function QueryFullProcessImageName Lib "Kernel32.dll" Alias "QueryFullProcessImageNameW" ( _
hProcess As Integer, _
dwFlags As UInt32, _
lpExeName As Ptr, _
ByRef lpdwSize As UInt32 _
) As Int32

Declare Function OpenProcess Lib "Kernel32.dll" ( _
dwDesiredAccess As UInt32, _
bInheritHandle As Int32, _
dwProcessId As UInt32 _
) As Integer

Declare Function CloseHandle Lib "Kernel32.dll" ( _
hObject As Integer _
) As Int32

Const PROCESS_QUERY_LIMITED_INFORMATION = &h1000
Const S_OK = 0

Dim hForegroundWindow As Integer = GetForegroundWindow()
Dim pidForegroundWindow As Integer 'this will store our PID
Dim hThread As Integer = GetWindowThreadProcessId(hForegroundWindow, pidForegroundWindow)

Dim hProcess As Integer = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pidForegroundWindow)

If hProcess <> 0 Then
  Dim sz As UInt32 = 40000 'usually MAX_PATH but just in case we are using long file names
  Dim mb As New MemoryBlock(40000)
  Dim ok As UInt32 = QueryFullProcessImageName(hProcess, 0, mb, sz)
  
  If ok <> 0 Then
    Dim name As String = mb.WString(0)
    system.DebugLog(name)
  End If
  
  Call CloseHandle(hProcess)
End If
1 Like

And if you want to strip off the path and just leave the exe name, call this on name to convert it, just change the type of name from String to WString:

Declare Sub PathStripPath Lib "Shlwapi.dll" Alias "PathStripPathW" (w_outpszPath As WString)
PathStripPath(name)

Ty very much.
How i can catch window chaged event ? I wrote it in C++ using byt SetWinEventHook. How can I translate it to Xojo ?

If you simply want to track what app the user has moved to when moving away from your app then you can call the code above in the Windows.Deactivated or App.Deactivated event or do you want to track every app the user visits?

i want to track every app changes activies. I did it with the following code in C++.

HWINEVENTHOOK hEventHook = SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS, NULL, &windowChangeHook, 0, 0, WINEVENT_OUTOFCONTEXT);

Ty.

https://www.dropbox.com/s/w8snzbkc9lr5w6g/WinEventFunc.xojo_binary_project?dl=1

Edit: Added unhooking to be polite

2 Likes

Thank You.

1 Like