1

I found the following code on StackOverflow:

def getForegroundWindowTitle() -> Optional[str]:
    hWnd = windll.user32.GetForegroundWindow()
    length = windll.user32.GetWindowTextLengthW(hWnd)
    buf = create_unicode_buffer(length + 1)
    windll.user32.GetWindowTextW(hWnd, buf, length + 1)

    # 1-liner alternative: return buf.value if buf.value else None
    if buf.value:
        return buf.value
    else:
        return None

This works great except I was wondering if I could use the PID to achieve the same effect as I have a way to get the PID. Perhaps some way to convert the PID to the window handle? I've tried different functions in the win32 API docs but none work. I'm reluctant to use win32gui because it hasn't been updated in some time.

  • 2
    Enumerate windows by calling EnumWindows. Then in the callback use GetWindowThreadProcessId to check if each window belongs to the target process. It's fine to use win32gui. There's no need for it to be updated. These functions haven't changed in over 20 years. – David Heffernan Apr 12 '20 at 06:52
  • Does this answer your question? [How can I use EnumWindows to find windows with a specific caption/title?](https://stackoverflow.com/questions/19867402/how-can-i-use-enumwindows-to-find-windows-with-a-specific-caption-title) – Joe Apr 12 '20 at 07:57
  • [\[SO\]: Get the title of a window of another program using the process name (@CristiFati's answer)](https://stackoverflow.com/questions/31278590/get-the-title-of-a-window-of-another-program-using-the-process-name/31280850#31280850) ? – CristiFati Apr 12 '20 at 13:07
  • 2
    Also: "*I'm reluctant to use win32gui because it hasn't been updated in some time*": That's incorrect (last change is from 7 months ago) and also irrelevant, as the functions that wraps are there for quite some time. – CristiFati Apr 12 '20 at 13:43
  • @Joe that looks like it could work. But I'm not familiar with C# or the Windows API, would you mind briefly explaining it so that I can translate it into Python? Thanks! – AviatingFotographer Apr 12 '20 at 16:38
  • Why don't you use an existing example, of which there are surely many, using pywin32? A quick websearch reveals plenty of examples? – David Heffernan Apr 12 '20 at 16:49
  • I am also not familiar with that particular function you need. But usually the win32 functions have a very similar or exactly the same name in all languages. So you should be able to adapt the example. – Joe Apr 12 '20 at 17:19
  • 2
    @AviatingFotographer [`EnumWindows`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumwindows) and [`GetWindowThreadProcessId`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowthreadprocessid) both also in `user32.dll`, similar way like you call `windll.user32.GetForegroundWindow()`. – Rita Han Apr 13 '20 at 07:50

1 Answers1

0
from ctypes import create_unicode_buffer, windll
from typing import Dict

import win32gui  # pip install pywin32


def get_title(hWnd) -> str:
    if not hWnd: hWnd = windll.user32.GetForegroundWindow()
    length = windll.user32.GetWindowTextLengthW(hWnd)
    buf = create_unicode_buffer(length + 1)
    windll.user32.GetWindowTextW(hWnd, buf, length + 1)
    return buf.value


def EnumWindowsProc(hWnd, pid_windows):
    pid = windll.user32.GetWindowThreadProcessId(hWnd, 0)
    print('pid', pid, hWnd, get_title(hWnd))
    if pid not in pid_windows: pid_windows[pid] = []
    pid_windows[pid].append(hWnd)


if __name__ == '__main__':
    pid_windows: Dict[int, int] = {}
    win32gui.EnumWindows(EnumWindowsProc, pid_windows)
    print(pid_windows)
Cees Timmerman
  • 17,623
  • 11
  • 91
  • 124