通过Xlib枚举指定进程下所有窗体

在windows系统下如果想要枚举指定进程的窗体,我们可以通过EnumWindows加上自己实现的回调函数进行实现,那么在linux下该如何做呢?

其实也很简单,在linux下,我们可以通过xlib中提供的API进行实现,关于xlib后面会专门写一篇文章讲解。

一、实现思路

从root窗体开始逐层遍历每一个窗体,将这些窗体所属进程与给定进程比较从而进行筛选。

二、实现代码

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <QList>

class WindowsMatchingPid
{
public:
    WindowsMatchingPid(Display *display, Window wRoot, unsigned long pid)
        : _display(display)
        , _pid(pid)
    {
        _atomPID = XInternAtom(display, "_NET_WM_PID", True);
        if(_atomPID == None)
        {
            return;
        }

        search(wRoot);
    }

    const QList<Window> result() const { return _result; }

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

    void search(Window w)
    {
        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(_pid == *((unsigned long *)propPID))
                    _result.append(w);
                XFree(propPID);
            }
        }

        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]);
        }
    }
};

这里主要使用XGetWindowProperty和XQueryTree进行窗体树遍历以及窗体属性获取。

XGetWindowProperty:获取目标窗体属性信息

XQueryTree:获取目标窗体的窗体树结构

接着就利用这个类去获取进程窗体

int pid = getpid();
Display *display = XOpenDisplay(0);
WindowsMatchingPid match(display, XDefaultRootWindow(display), pid);
const QList<Window> result = match.result();
for(int i=0; i<result.count();i++)
{
    unsigned long winId = (unsigned long)(result.at(i));
    QWidget* win = QWidget::find(winId);
    if(win!=NULL&&win->isWindow()&&win->isVisible()){
        m_pformList->append((QObject*)win);
    }
}
XCloseDisplay(display);

PS:每次调用XOpenDisplay获取x-server连接之后要记得调用XCloseDisplay关闭连接,否则连接泄露会导致程序异常退出。

原文地址:https://www.cnblogs.com/blackwatch1206/p/12323089.html

时间: 2024-10-13 11:58:27

通过Xlib枚举指定进程下所有窗体的相关文章

Windows下如何枚举所有进程

Windows下如何枚举所有进程 Posted on 13:37:00 by 晓月 and filed under Coding, Windows, Windows Mobile 要编写一个类似于 Windows 任务管理器的软件,首先遇到的问题是如何实现枚举所有进程.暂且不考虑进入核心态去查隐藏进程一类的,下面提供几种方法.请注意每种方法的使用局限,比如使用这些 API 所需要的操作系统是什么(尤其是是否能在 Windows Mobile 下使用). 本文参考用户态枚举进程的几种方法,原文对于

【C#】指定进程关闭&amp;闪讯下的Wifi共享

要在目前版本的闪讯中共享网络首先需要关闭闪讯附带的singleNet.exe进程. 而在密密麻麻的进程列表里找到指定进程是件非常考验眼力的事情(即使按‘s’定位也足够眼花缭乱了). 这边花几分钟时间写了个进程结束的小工具,在这里分享一下 Github源程序(项目文件): https://github.com/Blz-Galaxy/KillSX 因为主函数使用了参数列表,使用的时候在快捷方式中加入需要结束的进程名字就好- C#实现 很简单的几行代码 using System; using Syst

zabbix使用自己编写脚本模板和zabbix自带模板两种方法添加对指定进程和端口的监控

zabbix使用自己编写脚本模板和zabbix自带模板两种方法添加对指定进程和端口的监控 1.自带监控模板进行os的监控 进入/usr/local/zabbix/etc/zabbix_agentd.conf 配置文件修改 LogRemoteCommands=1     ###开启脚本功能 Server=192.168.5.129     ##修改zabbix指向的服务器: 重启zabbix_agentd.zabbix_server服务 在配置-->主机-->添加主机--> 配置主机信息主

通过zipfile解压指定目录下的zip文件

代码: # -*- coding: utf-8 -*- import os import zipfile import platform import multiprocessing # 解压后的文件夹与原来的zip文件同名且在相同目录下 # 确保windows下解压后的文件夹名不乱码 file_encoding = "utf-8" if platform.system() == "Windows": file_encoding = "gbk"

iOS案例:读取指定目录下的文件列表

// // main.m // 读取指定目录下的文件列表 // // Created by Apple on 15/11/24. // Copyright © 2015年 Apple. All rights reserved. // /* *读取指定目录下的文件列表 */ #import <Foundation/Foundation.h> void myQuickMethod(); int main(int argc, const char * argv[]) { //文件操作对象 NSFil

linux下自动ftp到服务器对比拷贝指定目录下文件

#!/bin/bash process=8 PWD=`pwd` DAT=`date` ftpip="192.168.1.1" user="ftp_username" password="ftp_password" local_dir="/home/" getlist() { ftp -n $ftpip <<EOF |awk '{print $9}'|sed '/^$/d' >$PWD/list user $u

Android Studio如何选择查看指定进程的log?

今天说一个简单的东东,关于Android Studio在logcat中如何查看指定进程的log. 关于过滤你自己所开发的应用的log,在这篇文章中:Android Studio如何给log添加过滤项(Filters)?有提及.当 然很多时候可能我们会有这样的场景,我们想看某一个进程的log,比如我想看酷狗的log,但是如果process那栏的进 程很多,这个时候logo也会非常多,这种情况下,你很难分辨出哪个logo是属于酷狗的. 其实,Android Studio还是有和Eclipse一样的选

加载指定包下的所有类

package util; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.net.JarURLConnection; import java.net.URL; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import java.util.jar.JarEnt

ectouch手机商城首页调用指定分类下的商品

ECTouch是国内市面上唯一开源的ECSHOP移动商城系统,为广大电商以最低的成本快速搭建移动商城.最近最一商城实例,手机版首页需要调用指定分类下的商品,ECtouch商城默认好像没有此调用方式,只能自己动手添加了. 方法如下: 1.打开mobile\include\apps\default\model\IndexModel.class.php 在最下面 } 之前添加以下代码 /**      * 获得指定分类下的商品      */      function assign_cat_good