获取窗口id

本文介绍在Linux和Windows系统中通过脚本及编程方式获取当前活动窗口ID的方法。具体包括使用xprop、xwininfo等工具的三种Linux命令行方法,以及提供了一段C++代码示例来展示如何在Windows和Linux环境下根据进程ID获取窗口ID。

(一)linux下脚本:

#!/bin/bash
#方法一
#xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)"| cut -d ' ' -f 5
#方法二
# xwininfo -name ShowAnimationProject | grep "Window id"| cut -d " " -f 4


#方法三
#!/bin/sh

# findpid=$1
# 
# known_windows=$(xwininfo -root -children|sed -e 's/^ *//'|grep -E "^0x"|awk '{ print $1 }')
# 
# for id in ${known_windows}
# do
#     xp=$(xprop -id $id _NET_WM_PID)
#     if test $? -eq 0; then
#         pid=$(xprop -id $id _NET_WM_PID|cut -d'=' -f2|tr -d ' ')
# 
#         if test "x${pid}" = x${findpid}
#         then
#             #echo "Windows Id: $id"
#             echo "$id"
#         fi
#     fi
# done


#@not used

(二)通过代码方式获取

#ifndef WINDOWIDUTIL_H
#define WINDOWIDUTIL_H


#include<QDebug>



// win
#ifdef Q_OS_WIN

#include <windows.h>


typedef struct
{
    HWND hWnd;
    DWORD dwPid;
}WNDINFO;



BOOL
CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
    WNDINFO* pInfo = (WNDINFO*)lParam;
    DWORD dwProcessId = 0;
    GetWindowThreadProcessId(hWnd, &dwProcessId);

    if(dwProcessId == pInfo->dwPid)
    {
     pInfo->hWnd = hWnd;
     return FALSE;
    }
    return TRUE;
}



WId
get_win_id_from_pid(DWORD dwProcessId)
{
    WNDINFO info = {0};
    info.hWnd = NULL;
    info.dwPid = dwProcessId;
    EnumWindows(EnumWindowsProc, (LPARAM)&info);
    return (WId)info.hWnd;
}



#else // linux


#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <iostream>
#include <list>
#include <stdlib.h>




class WindowsMatchingPid
{
public:
    WindowsMatchingPid(Display *display, Window wRoot, unsigned long pid)
        : _display(display),
          _pid(pid)
    {
        // Get the PID property atom.
        _atomPID = XInternAtom(display, "_NET_WM_PID", True);
        if(_atomPID == None)
        {
            std::cout << "No such atom" << std::endl;
            return;
        }

        search(wRoot);
    }

    const std::list<Window> &result() const { return _result; }

private:
    unsigned long  _pid;
    Atom           _atomPID;
    Display       *_display;
    std::list<Window>   _result;

    void
    search(Window w)
    {
        // Get the PID for the current Window.
        Atom           type;
        int            format;
        unsigned long  nItems;
        unsigned long  bytesAfter;
        unsigned char *propPID = 0;
        if(Success == XGetWindowProperty(
                    _display,
                    w,
                    _atomPID,
                    0,
                    1,
                    False,
                    XA_CARDINAL,
                    &type,
                    &format,
                    &nItems,
                    &bytesAfter,
                    &propPID))
        {
            if(propPID != 0)
            {
                // If the PID matches, add this window to the result set.
                if(_pid == *((unsigned long *)propPID))
                {
                    _result.push_back(w);
                }

                XFree(propPID);
            }
        }

        // Recurse into child windows.
        Window    wRoot;
        Window    wParent;
        Window   *wChild;
        unsigned  nChildren;
        if(0 != XQueryTree(_display, w, &wRoot, &wParent, &wChild, &nChildren))
        {
            for(unsigned i = 0; i < nChildren; i++)
                search(wChild[i]);
        }

        //XFree(propPID);
    }
};


unsigned long
get_win_id_from_pid(qint64 pid)
{
    //std::cout << "Searching for windows associated with PID " << pid << std::endl;

    // Start with the root window.
    Display *display = XOpenDisplay(0);

    WindowsMatchingPid match(display, XDefaultRootWindow(display), pid);

    // Print the result.
    const std::list<Window> &result = match.result();

    long win_id = 0;
    for(std::list<Window>::const_iterator pos = result.begin(); pos != result.end(); pos++)
    {
        std::cout << "Window #" << (unsigned long)(*pos) << std::endl;
        win_id = (unsigned long)(*pos);
    }

    return win_id;
}


#endif

#endif // WINDOWIDUTIL_H

在C语言中,要根据进程名获取窗口ID,可以通过以下步骤实现: 1. **枚举所有进程**:使用`CreateToolhelp32Snapshot`、`Process32First`和`Process32Next`等函数来枚举系统中的所有进程,获取每个进程的进程ID和进程名。 2. **匹配进程名**:在枚举进程的过程中,将获取到的进程名与目标进程名进行比较,如果匹配成功,则记录该进程的进程ID。 3. **枚举所有窗口**:使用`EnumWindows`函数枚举系统中的所有顶层窗口。 4. **获取窗口所属进程ID**:对于每个枚举到的窗口,使用`GetWindowThreadProcessId`函数获取创建该窗口的进程ID。 5. **比较进程ID**:将获取到的窗口所属进程ID与之前记录的目标进程ID进行比较,如果相等,则认为该窗口是目标进程的窗口,记录该窗口窗口ID。 以下是一个示例代码: ```c #include <windows.h> #include <tlhelp32.h> #include <stdio.h> // 比较进程名 BOOL CompareProcessName(const char* targetName, const char* processName) { return strcmp(targetName, processName) == 0; } // 获取进程ID DWORD GetProcessIdFromName(const char* processName) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) { return 0; } PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hSnapshot, &pe32)) { do { if (CompareProcessName(processName, pe32.szExeFile)) { CloseHandle(hSnapshot); return pe32.th32ProcessID; } } while (Process32Next(hSnapshot, &pe32)); } CloseHandle(hSnapshot); return 0; } // 枚举窗口的回调函数 BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { DWORD processId; GetWindowThreadProcessId(hwnd, &processId); if (processId == (DWORD)lParam) { printf("Found window ID: %p\n", hwnd); return FALSE; // 停止枚举 } return TRUE; // 继续枚举 } // 根据进程名获取窗口ID HWND GetWindowIdFromProcessName(const char* processName) { DWORD processId = GetProcessIdFromName(processName); if (processId == 0) { return NULL; } EnumWindows(EnumWindowsProc, (LPARAM)processId); return NULL; } int main() { const char* processName = "notepad.exe"; GetWindowIdFromProcessName(processName); return 0; } ``` 上述代码中,`GetProcessIdFromName`函数用于根据进程名获取进程ID,`EnumWindowsProc`是枚举窗口的回调函数,`GetWindowIdFromProcessName`函数用于根据进程名获取窗口ID。在`main`函数中,调用`GetWindowIdFromProcessName`函数并传入目标进程名,即可获取该进程的窗口ID
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值