杰瑞科技汇

Python FindWindowEx如何跨进程查找窗口句柄?

Of course! The FindWindowEx function is a key part of the Windows API (specifically user32.dll) used to find child windows within a parent window by their class name and/or window title.

Python FindWindowEx如何跨进程查找窗口句柄?-图1
(图片来源网络,侵删)

While there isn't a built-in Python function named FindWindowEx, you can easily access it using the pywin32 library, which provides Python access to many Windows-specific APIs.

Here’s a complete guide on how to use it.

Prerequisites: Install pywin32

First, you need to install the pywin32 library. You can do this using pip:

pip install pywin32

Understanding FindWindowEx

The FindWindowEx function has the following signature:

Python FindWindowEx如何跨进程查找窗口句柄?-图2
(图片来源网络,侵删)
HWND FindWindowEx(
  HWND   hWndParent,      // Handle to the parent window
  HWND   hWndChildAfter,  // Handle to a child window
  LPCSTR lpszClass,       // Class name of the window to find
  LPCSTR lpszWindow       // Window title (text) of the window to find
);

Let's break down the parameters for Python:

Parameter Python (pywin32) Type Description
hWndParent int or None A handle to the parent window. If you pass 0 or None, it searches the top-level windows.
hWndChildAfter int or None A handle to a child window to start searching after. If you pass None, the search starts from the first child window. This is useful for finding multiple controls with the same class/title.
lpszClass str or None The class name of the window to find (e.g., "Edit", "Button", "Notepad"). You can use tools like Spy++ (included with Visual Studio) or AutoIt Window Info to find these.
lpszWindow str or None The window title (the text displayed on the window/control). This is often the most user-friendly parameter.

Return Value:

  • Returns a handle (int) to the window if found.
  • Returns 0 or None if the window is not found.

Finding a Child Window: A Practical Example

Let's find the text input field in the Windows Calculator application.

Step 1: Open the Calculator. Step 2: Use Spy++ or a similar tool to find the window class. If you use Spy++ to inspect the Calculator's display, you'll find its class name is ApplicationFrameWindow.

Python FindWindowEx如何跨进程查找窗口句柄?-图3
(图片来源网络,侵删)

Here is the Python code to find that display field:

import win32gui
import win32con
# The title of the main Calculator window
calculator_title = "Calculator"
# The class name of the display control
display_class = "Windows.UI.Core.CoreWindow" # This is the class for the display in modern calculator
# Alternatively, for older versions, it might be "Static"
# Let's try a more robust approach by finding the main window first.
def find_calculator_display():
    """Finds the display window of the Calculator application."""
    try:
        # 1. Find the main Calculator window by its title
        hwnd_main = win32gui.FindWindow(None, calculator_title)
        if not hwnd_main:
            print(f"Could not find main window with title '{calculator_title}'. Is Calculator open?")
            return None
        print(f"Found main Calculator window. Handle: {hwnd_main}")
        # 2. Find the child window (the display) within the main window.
        # We'll search by its class name. For modern Calculator, it's "Windows.UI.Core.CoreWindow"
        # We pass hwnd_main as the parent.
        hwnd_display = win32gui.FindWindowEx(hwnd_main, 0, "Windows.UI.Core.CoreWindow", None)
        if not hwnd_display:
            # Fallback for older calculator versions
            hwnd_display = win32gui.FindWindowEx(hwnd_main, 0, "Static", None)
            if not hwnd_display:
                print("Could not find the display control. Class name might be different.")
                return None
        print(f"Found display window. Handle: {hwnd_display}")
        return hwnd_display
    except Exception as e:
        print(f"An error occurred: {e}")
        return None
# --- Main execution ---
if __name__ == "__main__":
    display_handle = find_calculator_display()
    if display_handle:
        # You can now use this handle for other operations, like getting text or sending messages
        print(f"Successfully found the display handle: {display_handle}")
        # Example: Get the window text (the current calculation)
        window_text = win32gui.GetWindowText(display_handle)
        print(f"Current display text: '{window_text}'")

Finding Multiple Child Windows (e.g., all buttons)

If you want to find all buttons in a window, you can loop. The trick is to pass the handle of the last found window as the hWndChildAfter parameter in the next call.

import win32gui
def find_all_buttons_in_notepad():
    """Finds all 'Button' controls in a Notepad window."""
    try:
        # Find a Notepad window. We use the class name "Notepad" as it's more reliable.
        hwnd_notepad = win32gui.FindWindow("Notepad", None)
        if not hwnd_notepad:
            print("Could not find a Notepad window. Please open Notepad.")
            return
        print(f"Found Notepad window. Handle: {hwnd_notepad}")
        button_handles = []
        last_found_handle = None # Start with None to search from the beginning
        while True:
            # Find the next button after the one we just found
            hwnd_button = win32gui.FindWindowEx(hwnd_notepad, last_found_handle, "Button", None)
            if hwnd_button == 0: # No more buttons found
                break
            button_handles.append(hwnd_button)
            last_found_handle = hwnd_button # Update the search to start from here
        print(f"\nFound {len(button_handles)} buttons:")
        for i, handle in enumerate(button_handles):
            # Get the button's text
            text = win32gui.GetWindowText(handle)
            print(f"  Button {i+1}: Handle={handle}, Text='{text}'")
    except Exception as e:
        print(f"An error occurred: {e}")
# --- Main execution ---
if __name__ == "__main__":
    find_all_buttons_in_notepad()

Important Tools for Finding Window Information

To use FindWindowEx effectively, you need to know the class names and titles of the windows you're looking for. These tools are indispensable:

  1. Spy++: Comes with Visual Studio. It's a powerful tool that lets you inspect the window hierarchy, find window handles, class names, and styles in real-time.
  2. AutoIt Window Info: A free tool that is excellent for this purpose. It gives you a simple list of all windows, their properties (handle, class, title, etc.), and even allows you to hover over controls to see their details.
  3. Microsoft Inspect: A modern tool from Microsoft for inspecting UI Automation elements. It's very powerful for modern WinUI and WPF applications.

Summary: FindWindowEx Cheat Sheet

Goal hWndParent lpszClass lpszWindow hWndChildAfter
Find a top-level window (e.g., Notepad) None "Notepad" None None
Find a child by its title Parent Handle None "My Button" None
Find a child by its class Parent Handle "Edit" None None
Find a child by both class & title Parent Handle "Button" "OK" None
Find all buttons Parent Handle "Button" None Loop with last found handle
分享:
扫描分享到社交APP
上一篇
下一篇