通过Xlib枚举指定进程下所有窗体
标签:type format 枚举 自己 prope 连接 oid opp 树结构
在windows系统下如果想要枚举指定进程的窗体,我们可以通过EnumWindows加上自己实现的回调函数进行实现,那么在linux下该如何做呢?
其实也很简单,在linux下,我们可以通过xlib中提供的API进行实现,关于xlib后面会专门写一篇文章讲解。
一、实现思路
从root窗体开始逐层遍历每一个窗体,将这些窗体所属进程与给定进程比较从而进行筛选。
二、实现代码
#include
#include
#include 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 result() const { return _result; }
private:
unsigned long _pid;
Atom _atomPID;
Display *_display;
QList _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 )
search(wChild[i]);
}
}
};
这里主要使用XGetWindowProperty和XQueryTree进行窗体树遍历以及窗体属性获取。
XGetWindowProperty:获取目标窗体属性信息
XQueryTree:获取目标窗体的窗体树结构
接着就利用这个类去获取进程窗体
int pid = getpid();
Display *display = XOpenDisplay(0);
WindowsMatchingPid match(display, XDefaultRootWindow(display), pid);
const QList result = match.result();
for(int i=0; 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关闭连接,否则连接泄露会导致程序异常退出。
通过Xlib枚举指定进程下所有窗体
标签:type format 枚举 自己 prope 连接 oid opp 树结构
原文地址:https://www.cnblogs.com/blackwatch1206/p/12323089.html
评论