Совсем просто не получится, потому что:
- Может быть несколько процессов с одним именем (например, можно открыть несколько окон Блокнота).
- У процесса может быть несколько окон
Поэтому сначала нужно получить список процессов с заданными именем файла (или для простоты первый попавшийся процесс, подходящий по этому условию), потом список окон для данного процесса (процессов).
1. Получаем список процессов, у которых имя файла равно notepad.exe
Можно воспользоваться пакетом psutil
import psutil
# Список процессов с именем файла notepad.exe:
notepads = [item for item in psutil.process_iter() if item.name() == 'notepad.exe']
print(notepads) # [<psutil.Process(pid=4416, name='notepad.exe') at 64362512>]
# Просто pid первого попавшегося процесса с именем файла notepad.exe:
pid = next(item for item in psutil.process_iter() if item.name() == 'notepad.exe').pid
# (вызовет исключение StopIteration, если Блокнот не запущен)
print(pid) # 4416
2. Получаем список окон процесса с заданным pid
Чтобы получить список окон процесса, можно воспользоваться функцией EnumWindows.
Например, нужно получить все окна процесса с ID 4416:
import win32gui
import win32process
def enum_window_callback(hwnd, pid):
tid, current_pid = win32process.GetWindowThreadProcessId(hwnd)
if pid == current_pid and win32gui.IsWindowVisible(hwnd):
windows.append(hwnd)
# pid = 4416 # pid уже получен на предыдущем этапе
windows = []
win32gui.EnumWindows(enum_window_callback, pid)
# Выводим заголовки всех полученных окон
print([win32gui.GetWindowText(item) for item in windows])
Вывод:
['Безымянный — Блокнот']
Если в Блокноте открыть еще настройку параметров страницы, то список будет такой:
['Параметры страницы', 'Безымянный — Блокнот']
Python —- pywin32 How to get a window handle
- One: Introduce the library you want to use
- Two: Display the properties of the window
-
- 1. Get the handle of all windows
- 2. Get the sub-window handle of the window
- 3. Get the title of the handle
- 4. Get the window class name
- Third, actual operation
-
- Top and cancel
- 2. Display and hide the window
- Fourth, case demonstration
-
- Show and hide trays
Halo, readers, this column opens an expansion of “how to make PC software with python”.
When we want to handle Windows software windows, we often hit the top, hide and display the window, and readers want to hide the computer tray, taskbar, etc. This article is to lead the reader learning window handle, and how to apply the Win32 module of the Python band to read the handle of each window in the interface.
I hope that through this article, readers can make their own small software in this article.
One: Introduce the library you want to use
import sys
import win32gui
import win32con
Two: Display the properties of the window
1. Get the handle of all windows
def get_all_windows():
hWnd_list = []
win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWnd_list)
print(hWnd_list)
return hWnd_list
>>[66364, 66014, 65964, 65854, 65850, 65846, 65842, 65826, 65812, 65802, 65858, 65862, 65876, 65794, ....]
2. Get the sub-window handle of the window
def get_son_windows(parent):
hWnd_child_list = []
win32gui.EnumChildWindows(parent, lambda hWnd, param: param.append(hWnd), hWnd_child_list)
print(hWnd_child_list)
return hWnd_child_list
>>[66364, 66014, 65964, 65854, ...]
3. Get the title of the handle
def get_title(hwnd):
title = win32gui.GetWindowText(hwnd)
print('Window Title:% S' % (title))
return title
>>Window header:set up
4. Get the window class name
def get_clasname(hwnd):
clasname = win32gui.GetClassName(hwnd)
print('Window class name:% s' % (clasname))
return clasname
>>Window class name:ApplicationFrameWindow
Third, actual operation
Top and cancel
Window top
def set_top(hwnd):
win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0,
win32con.SWP_NOMOVE | win32con.SWP_NOACTIVATE | win32con.SWP_NOOWNERZORDER | win32con.SWP_SHOWWINDOW | win32con.SWP_NOSIZE)
Window cancels top
def set_down(hwnd):
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, 0, 0, 0, 0,
win32con.SWP_SHOWWINDOW | win32con.SWP_NOSIZE | win32con.SWP_NOMOVE)
2. Display and hide the window
Get the handle according to the window name
# Get the handle according to the window name
def get_hwnd_from_name(name):
hWnd_list = get_all_windows()
for hwd in hWnd_list:
title = get_title(hwd)
if title == name:
return hwd
Window display
def xianshi(name):
hwd = get_hwnd_from_name(name)
win32gui.ShowWindow(hwd, win32con.SW_SHOW)
Window hidden
def yingcang(name):
hwd = get_hwnd_from_name(name)
win32gui.ShowWindow(hwd, win32con.SW_HIDE)
Fourth, case demonstration
Show and hide trays
Get the task handle of the upper right corner tray
# Get the task handle of the pallet in the lower right corner
def get_tuopan_hwd():
handle = win32gui.FindWindow("Shell_TrayWnd", None)
hWnd_child_list = get_son_windows(handle)[1:]
tuopan_hwd_list = []
flag = False
for i in hWnd_child_list:
if get_clasname(i) == 'TrayNotifyWnd':
flag = True
if flag:
tuopan_hwd_list.append(i)
return tuopan_hwd_list
Hidden tray
def yingcang(name=''):
tuopan_hwd_list = get_tuopan_hwd()
if name == '':
for i in tuopan_hwd_list[:7] :# [: 7] Because some basic content should be retained, you can also hide
win32gui.ShowWindow(i, win32con.SW_HIDE)
else:
win32gui.ShowWindow(name, win32con.SW_HIDE)
Show tray
def xianshi(name = ''):
tuopan_hwd_list = get_tuopan_hwd()
if name == '':
for i in tuopan_hwd_list:
win32gui.ShowWindow(i, win32con.SW_SHOW)
else:
win32gui.ShowWindow(name, win32con.SW_SHOW)
how can I get the handle of a tkinter window?
I tried …
h = self._get_hwnd()
but it doesn’t work. I’m using Python
IDLE Shell 3.10.1 (OS: Windows 10).
Example:
import tkinter as tk
root=tk.Tk()
root.title=("Test")
text1=tk.Text(root, height=10, width=50)
text1.insert(tk.INSERT,self._get_hwnd())
text1.pack()
root.mainloop()
martineau
118k25 gold badges164 silver badges294 bronze badges
asked Dec 27, 2021 at 20:15
12
According to the official tk documentation, the winfo_id
method will return the HWND on windows.
From the official tcl/tk man page for the winfo
command:
winfo id window –
Returns a hexadecimal string giving a low-level platform-specific identifier for window. On Unix platforms, this is the X window identifier. Under Windows, this is the Windows HWND. On the Macintosh the value has no meaning outside Tk.
Translated to tkinter, winfo id window
is window.winfo_id()
.
answered Dec 27, 2021 at 21:44
Bryan OakleyBryan Oakley
366k52 gold badges532 silver badges679 bronze badges
3
win32 api with python
pywin32 is currently the best way to manipulate windows API.
It is maintained and the github source code is also public and available here :
pywin32 github
The imports used in this page are:
import win32com.client import win32gui import win32process
Find window functions
Find the first window which the window title matches and/or the class name of the window class
matches:
win32gui.FindWindow(class, title)
The FindWindow() functions return the handle id (int) of the first window matching to the
criteria we submit.
Its concrete signature is: win32gui.FindWindow(class: str=None, title: str=None)->int
Behavior:
– the class name and the title are optional, we can pass one or the other or
both.
– The case of the input is not sensitive.
– The text input has to match exactly with the title of the window, we cannot provide only a
part of the title as input.
Examples where we search only on the title
Suppose we have a window opened which the title is ‘david’, we can retrieve it in this way.
Note the 3rd example which doesn’t return any match because the input contains only a part of
the full title:
window = win32gui.FindWindow(None, 'david') print(f'window with title match(with input the exact case and characters)={window}') # window with title match(with input the exact case and characters)=281646 window = win32gui.FindWindow(None, 'davID') print(f'window with title match(with input the exact characters but different case )={window}') # window with title match(with input the exact characters but different case )=281646 window = win32gui.FindWindow(None, 'davi') print(f'window with title match(with input the exact case but with only a part of characters)=' f'{window}') # window with title match(with input the exact case but with only a part of characters)=0
Examples where we search only on the class
Suppose we have a window file explorer opened, we can retrieve it thanks to the class name that
is CabinetWClass
:
window = win32gui.FindWindow('CabinetWClass', None) window_text = win32gui.GetWindowText(window) print(f'window with CabinetWClass class. window={window}: window_text={window_text}')
Output:
window with CabinetWClass class. window=611882: window_text=PC
We may have multiple windows of file explorer but as seen previously the function will return
only the first result.
Examples where we search both on the class and the title
Beware: The 2 parameters have to match if we provide both of them.
window = win32gui.FindWindow('CabinetWClass', 'daviD') window_text = win32gui.GetWindowText(window) print(f'window with CabinetWClass class and title "daviD". window={window}: window_text={window_text}')
Output:
window with CabinetWClass class and title "daviD". window=87772: window_text=david
Find all windows which match with our input where our input maybe anything:
win32gui.EnumWindows(foo_callback, foo_input)
The function EnumWindows
accepts as parameter a callback and a
string that we can use in anyway to perform our matching in the callback function.
Beyond the parameter we can provide, with that function we have the hand to define how to
perform the match.
That is we can do a match on the title, on the class name or in any other attribute that defines
a window object such as the state of the window.
Behavior
– The function enumerates all windows and so doesn’t stop until the loop is finished.
It means that we have to store the handle information that interest us inside the callback to be
able to reuse it later.
Example: List all windows
Here is the callback function:
def window_enum_callback_print_all(hwnd, text): print(hex(hwnd), win32gui.GetWindowText(hwnd)) print(f'win32gui.GetClassName()={win32gui.GetClassName(hwnd)}')
Here is the code that calls the win32gui.EnumWindows()
function:
win32gui.EnumWindows(window_enum_callback_print_all, '')
Example: List windows which title contains ‘owertoys’ whatever the case.
Here is the callback function:
def window_enum_callback_set_if_text_matches(hwnd, part_of_title): """Set the handle of the current instance if text matches with the text title """ window_title = str(win32gui.GetWindowText(hwnd)) if part_of_title.lower() in window_title.lower(): matching_windows.append(hwnd)
We can notice that we store the window ids in a list.
Here is the code that calls the win32gui.EnumWindows()
function:
matching_windows: List[int] = [] win32gui.EnumWindows(window_enum_callback_set_if_text_matches, 'owertoys') print(f'matching_windows with loose title matching for owertoys={matching_windows}') handles_title: List[str] = [win32gui.GetWindowText(m) for m in matching_windows] print(f'handles_title={handles_title}')
Output:
matching_windows with loose title matching for owertoys=[66744, 66456, 66140] handles_title=['GDI+ Window (PowerToys.Awake.exe)', 'PowerToys Runner', 'GDI+ Window (PowerToys.exe)']
Example: List all windows matching a class name and a title if it is provided
It is an interesting case because the FindWindow()
function doesn’t return all
windows matching but only the first one matching a class name, so the EnumWindows()
function here solves this problem
We will we reuse the example of the file explorer class name seen previously
here is the callback function:
def window_enum_callback_set_for_file_explorer_window(hwnd, text: str): """Pass to win32gui.EnumWindows() to check all the opened windows""" # if win32gui.IsWindowVisible(hwnd): if win32gui.GetClassName(hwnd) == 'CabinetWClass': if not text: matching_windows.append(hwnd) else: window_text = win32gui.GetWindowText(hwnd) if text.lower() in window_text.lower(): matching_windows.append(hwnd)
The client code:
matching_windows: List[int] = [] win32gui.EnumWindows(window_enum_callback_set_for_file_explorer_window, None) print(f'matching_windows with explorer class match ={matching_windows}') handles_title: List[str] = [win32gui.GetWindowText(m) for m in matching_windows] print(f'handles_title={handles_title}') # If we want to, we can specify also as seen previously a text to match with the window title matching_windows: List[int] = [] win32gui.EnumWindows(window_enum_callback_set_for_file_explorer_window, 'DAvi') print(f'matching_windows with explorer class match and David as title match={matching_windows}') handles_title: List[str] = [win32gui.GetWindowText(m) for m in matching_windows] print(f'handles_title={handles_title}')
Output:
matching_windows with explorer class match =[18569228, 611882, 87772] handles_title=['AppData', 'PC', 'david'] matching_windows with explorer class match and David as title match=[87772] handles_title=['david']
focus on windows function
We can focus on a specific window if we know its handle id.
We achieve it with this function: win32gui.SetForegroundWindow(handle_id)
Important:
In some specific cases, we cannot focus on a window without sending a key on it before.
To send a key on a window, we can use this function: win32com.client.Dispatch("WScript.Shell")
that returns a shell object.
Example: find a google chrome window and focus on it
without sending a key:
window = win32gui.FindWindow('Chrome_WidgetWin_1', None) win32gui.SetForegroundWindow(window)
with sending a key:
window = win32gui.FindWindow('Chrome_WidgetWin_1', None) shell = win32com.client.Dispatch("WScript.Shell") shell.SendKeys('') win32gui.SetForegroundWindow(window)
Important:
Sending a key to the window we want to focus may be needed. But we cannot send any key because
some keys such as a letter or a modifier may have a side effect on the window which we want to
focus.
A good workaround to avoid any side effect is to send the ‘none’ key. This one may be not
recognized
in all windows versions but in windows 10 it is.
It is what we have done in the previous example:
shell.SendKeys('')
Retrieve a process id associated to a window
To achieve it, we need to know the window handle id of the window and to call the function:
win32process.GetWindowThreadProcessId(window_handle_id)
.
The function returns a tuple representing the thread id and the process id.
example
window = win32gui.FindWindow('Chrome_WidgetWin_1', None) threadid, pid = win32process.GetWindowThreadProcessId(window) print(f'threadid, pid ={threadid, pid} for window with class name Chrome_WidgetWin_1 and window handle id {window}')
Output:
threadid, pid =(6636, 8756) for window with class name Chrome_WidgetWin_1 and window handle id 460658
Ce contenu a été publié dans Non classé. Vous pouvez le mettre en favoris avec ce permalien.
Question:
How to get hwnd of a window by process name. For example, I can get hwnd by the window name
hwnd = win32gui.FindWindow(None, "Notepad")
Is it just as easy to get hwnd by process name?
Answer:
It just won’t work, because:
- There can be multiple processes with the same name (for example, you can open multiple Notepad windows).
- A process can have multiple windows
Therefore, first you need to get a list of processes with a given file name (or, for simplicity, the first available process that matches this condition), then a list of windows for this process (processes).
1. We get a list of processes for which the file name is equal to notepad.exe
You can use the psutil package
import psutil
# Список процессов с именем файла notepad.exe:
notepads = [item for item in psutil.process_iter() if item.name() == 'notepad.exe']
print(notepads) # [<psutil.Process(pid=4416, name='notepad.exe') at 64362512>]
# Просто pid первого попавшегося процесса с именем файла notepad.exe:
pid = next(item for item in psutil.process_iter() if item.name() == 'notepad.exe').pid
# (вызовет исключение StopIteration, если Блокнот не запущен)
print(pid) # 4416
2. Get a list of process windows with a given pid
You can use the EnumWindows function to get a list of windows in a process.
For example, you need to get all windows of the process with ID 4416:
import win32gui
import win32process
def enum_window_callback(hwnd, pid):
tid, current_pid = win32process.GetWindowThreadProcessId(hwnd)
if pid == current_pid and win32gui.IsWindowVisible(hwnd):
windows.append(hwnd)
# pid = 4416 # pid уже получен на предыдущем этапе
windows = []
win32gui.EnumWindows(enum_window_callback, pid)
# Выводим заголовки всех полученных окон
print([win32gui.GetWindowText(item) for item in windows])
Conclusion:
['Безымянный — Блокнот']
If you also open the page settings setting in Notepad, the list will be as follows:
['Параметры страницы', 'Безымянный — Блокнот']
Post Views: 72