通过进程名 获取窗口句柄

进程名取进程ID 进程ID取窗口句柄 通过进程名 获取窗口句柄 只知道进程名

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
通过进程名获取窗口句柄,可以借助windows API中的相关函数,以下是示例代码:

import win32gui
import win32process

def get_hwnd_from_pid(pid):
    """
    根据进程ID获取主窗口句柄
    """
    def callback(hwnd, hwnds):
        if win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd):
            _, found_pid = win32process.GetWindowThreadProcessId(hwnd)
            if found_pid == pid:
                hwnds.append(hwnd)
        return True
    hwnds = []
    win32gui.EnumWindows(callback, hwnds)
    return hwnds[0] if len(hwnds)>0 else None


def get_hwnd_from_name(name):
    """
    根据进程名获取主窗口句柄
    """
    hwnds = []
    win32gui.EnumWindows(lambda hwnd, param: param.append(hwnd) if name.lower() in win32gui.GetWindowText(hwnd).lower() else True, hwnds)
    if len(hwnds)>0:
        return hwnds[0]
    else:
        return None

其中,win32gui.EnumWindows函数用于枚举所有窗口,通过回调函数可以筛选出指定进程ID或窗口标题包含指定字符串的窗口句柄。win32process.GetWindowThreadProcessId则可用于获取某个窗口所属的进程ID。
如果我的回答解决了您的问题,请采纳!

可以借鉴下

// WinWnd.cpp : 定义 DLL 应用程序的导出函数。
//
 
#include "stdafx.h"
#include "WinWnd.h"
#include<stdio.h>
#include<Windows.h>
#include<TlHelp32.h>
#include<iostream>
 
using namespace std;
typedef struct tagWNDINFO
{
    DWORD dwProcessId;
    HWND hWnd;
} WNDINFO, *LPWNDINFO;
 
 
 
//2.枚举所有进程
 
BOOL CALLBACK MyEnumProc(HWND hWnd, LPARAM lParam)//枚举所有进程
{
    DWORD dwProcId;
    GetWindowThreadProcessId(hWnd, &dwProcId);
    LPWNDINFO pInfo = (LPWNDINFO)lParam;
    //cout << "dwProcId:" << dwProcId << " pInfo->dwProcessId:" << pInfo->dwProcessId << endl;
    if (dwProcId == pInfo->dwProcessId)
    {
 
        HWND p = GetParent(hWnd);
        HWND ph = GetParent(p);
        if (ph != 0) {
            pInfo->hWnd = ph;
            return FALSE;
        }
 
    }
 
    return TRUE;
}
 
 
 
//3.获取给定进程ID的窗口handle
 
HWND GetProcessMainWnd(DWORD dwProcessId)//获取给定进程ID的窗口handle
{
    WNDINFO wi;
    wi.dwProcessId = dwProcessId;
    wi.hWnd = NULL;
    EnumWindows(MyEnumProc, (LPARAM)&wi);
 
    return wi.hWnd;
}
 
HWND GetWndHwnd(char *strExeName)
{
    PROCESSENTRY32 pe32;
    //在使用这个结构前,先设置它的大小  
    pe32.dwSize = sizeof(pe32);
    //给系统内所有的进程拍个快照  
    HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        //printf("CreateToolhelp32Snapshot 调用失败.\n");  
        return NULL;
    }
    //遍历进程快照,轮流显示每个进程的信息  
    BOOL bMore = ::Process32First(hProcessSnap, &pe32);
    while (bMore)
    {
        //if(pe32.szExeFile == exeName)//找到了进程
        if (strcmp(_strdup(pe32.szExeFile), strExeName) == 0)
        {
 
            HWND game_window_hwnd = GetProcessMainWnd(pe32.th32ProcessID);
            if (NULL != game_window_hwnd)
            {
                ::CloseHandle(hProcessSnap);
                return game_window_hwnd;
            }
        }
        bMore = ::Process32Next(hProcessSnap, &pe32);
    }
    //不要忘记清除掉snapshot对象  
    ::CloseHandle(hProcessSnap);
    return NULL;
}
 
 
int GetWndFromPid(char * proName)
{
    return int(GetWndHwnd(proName));
}

引用chatGPT作答,在 C++ 中,可以使用 Windows API 函数来获取进程名和窗口句柄。下面是一些步骤,可以通过进程名获取窗口句柄:

1.使用 EnumWindows 函数枚举系统中的所有窗口。

2.对于每个窗口,使用 GetWindowThreadProcessId 函数获取与其关联的进程 ID。

3.如果进程 ID 与指定的进程名相符,则使用 GetWindowText 函数获取窗口标题,并检查是否与所需的窗口标题相符。如果匹配,则返回该窗口的句柄。

下面是一个示例代码,可以用来实现上述步骤:

#include <windows.h>
#include <string>
using namespace std;

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
    DWORD pid;
    GetWindowThreadProcessId(hwnd, &pid);
    if (pid == (DWORD)lParam) {
        char buf[1024];
        GetWindowTextA(hwnd, buf, sizeof(buf));
        string title(buf);
        if (title.find("desired window title") != string::npos) {
            *(HWND*)lParam = hwnd;
            return FALSE;
        }
    }
    return TRUE;
}

HWND GetWindowHandleFromProcessName(string processName) {
    DWORD pid = 0;
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (Process32First(snapshot, &pe)) {
        do {
            if (string(pe.szExeFile) == processName) {
                pid = pe.th32ProcessID;
                break;
            }
        } while (Process32Next(snapshot, &pe));
    }
    CloseHandle(snapshot);
    if (pid == 0) return NULL;
    HWND hwnd = NULL;
    EnumWindows(EnumWindowsProc, (LPARAM)&hwnd);
    return hwnd;
}

在上面的示例中,GetWindowHandleFromProcessName 函数接受一个进程名作为参数,并返回与该进程关联的窗口句柄。如果找不到匹配的窗口,则返回 NULL。