- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想知道我的 QMainWindow
当前是否可见并且没有被另一个应用程序的另一个窗口重叠。
我需要为 Windows、Linux 和 Mac 实现这一目标。
最佳答案
我不久前写了一个小型库,用于在 Windows、Mac OS X 和 Linux 上读取前景或最顶层的窗口信息,主要是窗口标题。你可以在这里找到源代码: https://github.com/pcmantinker/Qt-Window-Title-Reader
我在 Windows 上使用原生 Windows API,在 Linux 上使用 X11 库,在 Mac OS X 上使用 Cocoa。
下面是一个关于如何使用 Objective-C++ 在 Mac OS X 中获取事件窗口的小示例:
Mac.h
/*
Mac/Cocoa specific code for obtaining information about the frontmost window
*/
#ifndef MAC_H
#define MAC_H
#include <QtCore>
#include "windowinfo.h"
class Mac {
public:
Mac();
QList<WindowInfo> getActiveWindows();
};
#endif // MAC_H
Mac.mm
/*
Mac/Cocoa specific code for obtaining information about the frontmost window
*/
#include "mac.h"
#include "Cocoa/Cocoa.h"
Mac::Mac()
{
}
QList<WindowInfo> Mac::getActiveWindows()
{
QList<WindowInfo> windowTitles;
// get frontmost process for currently active application
ProcessSerialNumber psn = { 0L, 0L };
OSStatus err = GetFrontProcess(&psn);
CFStringRef processName = NULL;
err = CopyProcessName(&psn, &processName);
NSString *pname = (NSString *)processName;
// loop through all application windows
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
for (NSMutableDictionary* entry in (NSArray*)windowList)
{
NSString* ownerName = [entry objectForKey:(id)kCGWindowOwnerName];
NSString *name = [entry objectForKey:@"kCGWindowName" ];
NSInteger ownerPID = [[entry objectForKey:(id)kCGWindowOwnerPID] integerValue];
NSInteger layer = [[entry objectForKey:@"kCGWindowLayer"] integerValue];
if(layer == 0)
{
if([ownerName isEqualToString:pname])
{
NSRange range;
range.location = 0;
range.length = [ownerName length];
unichar *chars = new unichar[range.length];
[ownerName getCharacters:chars range:range];
QString owner = QString::fromUtf16(chars, range.length);
range.length = [name length];
chars = new unichar[range.length];
[name getCharacters:chars range:range];
QString windowTitle = QString::fromUtf16(chars, range.length);
delete[] chars;
long pid = (long)ownerPID;
WindowInfo wi;
wi.setProcessName(owner);
wi.setWindowTitle(windowTitle);
wi.setPID(pid);
windowTitles.append(wi);
}
}
}
CFRelease(windowList);
CFRelease(processName);
return windowTitles;
}
请注意,在 Cocoa 中,没有直接的方法只获取最顶层的窗口。您会获得一组窗口并循环浏览它们以找到您想要的窗口。
以下是 Windows API 的代码:
win.h
/*
Windows API specific code for obtaining information about the frontmost window
*/
#ifndef WIN_H
#define WIN_H
#include <QtCore>
#include "qt_windows.h"
#include "psapi.h"
#include "windowinfo.h"
class win : public QObject
{
Q_OBJECT
public:
win();
QList<WindowInfo> getActiveWindows();
private:
TCHAR buf[255];
};
#endif // WIN_H
win.cpp
#include "win.h"
win::win()
{
}
QList<WindowInfo> win::getActiveWindows()
{
QList<WindowInfo> windowTitles;
HWND foregroundWindow = GetForegroundWindow();
DWORD* processID = new DWORD;
GetWindowText(foregroundWindow, buf, 255);
GetWindowThreadProcessId(foregroundWindow, processID);
DWORD p = *processID;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, p);
TCHAR szProcessName[MAX_PATH];
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
}
}
CloseHandle(hProcess);
long pid = (long)p;
QString windowTitle, processName;
#ifdef UNICODE
windowTitle = QString::fromUtf16((ushort*)buf);
processName = QString::fromUtf16((ushort*)szProcessName);
#else
windowTitle = QString::fromLocal8Bit(buf);
processName = QString::fromLocal8Bit(szProcessName);
#endif
WindowInfo wi;
wi.setPID(pid);
wi.setWindowTitle(windowTitle);
wi.setProcessName(processName);
windowTitles.append(wi);
return windowTitles;
}
这是 Linux/X11 的代码:
linux_x11.h
/*
Linux/X11 specific code for obtaining information about the frontmost window
*/
#ifndef LINUX_X11_H
#define LINUX_X11_H
#include <QtCore>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include "windowinfo.h"
class linux_x11
{
public:
linux_x11();
QList<WindowInfo> getActiveWindows();
private:
Window* active(Display *disp, unsigned long *len);
char *name (Display *disp, Window win);
int *pid(Display *disp, Window win);
QString processName(long pid);
};
#endif // LINUX_X11_H
linux_x11.cpp
/*
Linux/X11 specific code for obtaining information about the frontmost window
*/
#include "linux_x11.h"
#include <sstream>
#include <stdlib.h>
#include <stdio.h>
linux_x11::linux_x11()
{
}
/**
* Returns the window name for a specific window on a display
***/
char *linux_x11::name (Display *disp, Window win) {
Atom prop = XInternAtom(disp,"WM_NAME",False), type;
int form;
unsigned long remain, len;
unsigned char *list;
if (XGetWindowProperty(disp,win,prop,0,1024,False,AnyPropertyType, &type,&form,&len,&remain,&list) != Success)
return NULL;
return (char*)list;
}
/**
* Returns the pid for a specific window on a display
***/
int* linux_x11::pid(Display *disp, Window win) {
Atom prop = XInternAtom(disp,"_NET_WM_PID",False), type;
int form;
unsigned long remain, len;
unsigned char *list;
if (XGetWindowProperty(disp,win,prop,0,1024,False,AnyPropertyType, &type,&form,&len,&remain,&list) != Success)
return NULL;
return (int*)list;
}
/**
* Returns the active window on a specific display
***/
Window * linux_x11::active (Display *disp, unsigned long *len) {
Atom prop = XInternAtom(disp,"_NET_ACTIVE_WINDOW",False), type;
int form;
unsigned long remain;
unsigned char *list;
if (XGetWindowProperty(disp,XDefaultRootWindow(disp),prop,0,1024,False,XA_WINDOW, &type,&form,len,&remain,&list) != Success)
return NULL;
return (Window*)list;
}
/**
* Returns process name from pid (processes output from /proc/<pid>/status)
***/
QString linux_x11::processName(long pid)
{
// construct command string
QString command = "cat /proc/" + QString("%1").arg(pid) + "/status";
// capture output in a FILE pointer returned from popen
FILE * output = popen(command.toStdString().c_str(), "r");
// initialize a buffer for storing the first line of the output
char buffer[1024];
// put the contents of the buffer into a QString
QString line = QString::fromUtf8(fgets(buffer, sizeof(buffer), output));
// close the process pipe
pclose(output);
// take right substring of line returned to get process name
return line.right(line.length() - 6).replace("\n", "");
}
QList<WindowInfo> linux_x11::getActiveWindows()
{
QList<WindowInfo> windowTitles;
unsigned long len;
Display *disp = XOpenDisplay(NULL);
Window *list;
char *n;
int* p;
list = (Window*)active(disp,&len);
if((int)len > 0)
{
for (int i=0;i<(int)len;i++) {
n = name(disp,list[i]);
p = pid(disp, list[i]);
long p_id = 0;
QString pName;
QString windowTitle;
if(p!=NULL)
{
p_id = *p; // dereference pointer for obtaining pid
pName = processName(p_id);
}
if(n!=NULL)
windowTitle = QString::fromUtf8(n);
WindowInfo wi;
wi.setWindowTitle(windowTitle);
wi.setProcessName(pName);
wi.setPID(p_id);
windowTitles.append(wi);
delete n;
delete p;
}
}
delete list;
XCloseDisplay (disp);
return windowTitles;
}
X11 代码可能会变得非常丑陋且难以理解,但这应该能让您入门。自从我直接处理 X11 以来已经有一段时间了,所以我现在不能准确地告诉您每个辅助方法的作用。
我对代码进行了抽象,使得每个特定于平台的代码片段都具有相同的方法签名。然后我检查它是否在 Mac OS X、Windows 或 Linux 上编译并实例化正确的类。以下是所有内容的关联方式:
#include "windowtitlereader.h"
WindowTitleReader::WindowTitleReader()
{
qDebug() << "WindowTitleReader::WindowTitleReader()";
// refresh window reading every 10ms
timer = new QTimer(this);
timer->setInterval(10);
timer->start();
connect(timer, SIGNAL(timeout()), this, SLOT(getWindowTitle()));
}
WindowTitleReader::~WindowTitleReader()
{
delete timer;
delete m_pid;
delete m_processName;
}
void WindowTitleReader::getWindowTitle()
{
qDebug() << "WindowTitleReader::getWindowTitle()";
#ifdef Q_WS_WIN
win w;
m_activeWindows = w.getActiveWindows();
#endif
#ifdef Q_WS_MACX
Mac m;
m_activeWindows = m.getActiveWindows();
#endif
#ifdef Q_WS_X11
linux_x11 l;
m_activeWindows = l.getActiveWindows();
#endif
for(int i = 0; i < m_activeWindows.count(); i++)
qDebug() << "PID: " << m_activeWindows[i].getPID() << " Process Name: " << m_activeWindows[i].getProcessName() << " Window Title: " << m_activeWindows[i].getWindowTitle();
}
如果需要,您可以将刷新率更改为较慢的刷新率,但我每 10 毫秒运行一次更新,以便在窗口聚焦上获得近乎实时的更新。
我编写这个库主要是为了读取网络浏览器和视频游戏的窗口标题,这样我就可以估计人们在计算机上玩某些游戏的时间。我将此作为我正在构建的游戏指标应用程序的一部分进行编写。
关于c++ - 检查我的 QMainWindow 当前在 Qt 中是否可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18183190/
我试图通过这段代码读取未知数量的整数: while (1) { int c = getchar (); if (c == EOF) break;
我正试图找到一个类似于谷歌分析日期选择器的日期选择器: 知道 jQuery 是否提供了类似的东西吗? 最佳答案 这个 Twitter Bootstrap 风格的日期范围选择器非常接近。 https:/
我正在使用 javascript。如何获取当前 URL 的路径并将其分配给我的代码?这是我的代码: $(document).ready(function() { $(".share").hides
如何获得今天的Julian day number (JDN)相等的?或任何日期? 我看了又看,但只发现了一些产生“year-dayOfYear”的函数,而不是:2457854。 最佳答案 在 bash
我有相当简单的 UDP 服务器写在 c 上。 有时我需要知道在套接字中排队的所有 udp 数据包(字节)的当前长度。 据我了解,getsockopt 没有得到这样的信息。 欢迎使用 Linux 和 F
我一直在寻找几个小时来找到一个可以在图像中添加诸如“填充:5px”之类的东西的插件。每个人都通过纯 html 做到这一点吗?我们的客户需要一种方法来简单地使用按钮或右键单击上下文菜单来添加它。有什么建
是否有可能获得当前正在执行的 TCL 脚本的完整路径? 在 PHP 中,它将是:__FILE__ 最佳答案 根据“当前正在执行的 TCL 脚本”的含义,您实际上可能会寻找 info script ,甚
我最近从直接使用 ISession 转向了包装的 ISession,即工作单元类型模式。 我曾经使用 SQL Lite(内存中)对此进行测试。我有一个简单的帮助器类,它配置我的 SessionFact
我按照步骤操作 here在 WebStorm 中配置代码完成和其他内容,但我仍然收到以下语法错误。 我该如何解决这个问题? 最佳答案 通过相应地将“JavaScript 语言版本”(Settings/
我可以为我团队的 TFS 当前 Sprint 任务板添加书签吗?我们有两周的冲刺,因此 URL 每两周更改一次。 默认 URL 的形式为: http://[Server]/tfs/[Project]/
是否有 Subversion 命令可以显示当前版本号? 在svn checkout之后,我想启动一个脚本并需要变量中的修订号。如果有像 svn info get_revision_number 这样的
我正在编写表单的一个组件 首次安装组件时,sources={{}} ,一本空字典。由于该组件包装了现有的 Javascript 库,因此我正在实现一个自定义比较函数。为了让这个 diffing 函数
无论系统时间设置为多少以及机器所在的时区,我都需要正确的 UTC 时间。 (即使我必须打电话到互联网才能同步......) 是否有一些库或其他方法可以优雅地做到这一点? 最佳答案 如果您想获得准确可靠
我一边编码,一边拿出一些我和 friend 建立的旧网站来重新开始工作。我已经有一段时间没有做过任何 AJAX 了,当我试图找出我的代码失败的地方时,我发现没有显示很多资源。我猜这是因为我使用的是旧方
由于对性能的巨大影响,我从不怀疑我现在的桌面CPU是否有分支预测。当然可以。但各种 ARM 产品又如何呢? iPhone或Android手机有分支预测吗?较旧的任天堂 DS?基于 PowerPC 的
我有一个具有以下有效负载的 JWT: { "id": "394a71988caa6cc30601e43f5b6569d52cd7f6df", "jti": "394a71988caa6cc30
从其他一些帖子中,我能够通过以下方式获取当前 URI: 但是以下方法不起作用: 我很好奇为什么上面的方法不起作用,以及如何将当前 URI 分配给字符串。 最佳答案 每the javadocs ,g
我在表格 View 中有几个单元格。现在在任何给定的时间点,我想计算 View 中单元格的当前高度,即如果它是 View 的 3/4,它应该返回 (cellheight)*3/4 高度。 我通过以下方
这是网站的身份验证脚本。这安全吗?是最近的节目吗?它已经过时了吗?是否有“更好更安全的方法”我很新,但我没有看到太多地方使用 header 授权。 如有任何帮助,我们将不胜感激!这是我制作的第一个登录
我已经在其他 stackoverflow 线程上检查过这个错误,但在我的代码中没有发现任何错误。也许我累了,但我觉得还好。 网站.urls.py: from django.conf.urls impo
我是一名优秀的程序员,十分优秀!