feat: 添加监听系统聚焦窗口变化
This commit is contained in:
@@ -32,12 +32,15 @@ add_subdirectory(ElaWidgetTools)
|
||||
# 导出src下的cpp文件
|
||||
file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS src/*.cpp src/UI/*.cpp)
|
||||
|
||||
qt_add_executable(cbh
|
||||
qt_add_executable(${PROJECT_NAME}
|
||||
MANUAL_FINALIZATION
|
||||
${SRC_FILES}
|
||||
)
|
||||
|
||||
target_link_libraries(cbh PRIVATE
|
||||
# 添加宏定义,输出日志所处文件位置
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE QT_MESSAGELOGCONTEXT)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
Qt6::Widgets
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
@@ -50,7 +53,7 @@ set(cbh_resource_files
|
||||
"assets/icon.png"
|
||||
)
|
||||
|
||||
qt_add_resources(cbh "cbh"
|
||||
qt_add_resources(${PROJECT_NAME} "cbh"
|
||||
PREFIX
|
||||
"/"
|
||||
FILES
|
||||
@@ -63,7 +66,7 @@ qt_add_resources(cbh "cbh"
|
||||
if(${QT_VERSION} VERSION_LESS 6.1.0)
|
||||
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.cbh)
|
||||
endif()
|
||||
set_target_properties(cbh PROPERTIES
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
${BUNDLE_ID_OPTION}
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
||||
@@ -72,10 +75,10 @@ set_target_properties(cbh PROPERTIES
|
||||
)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS cbh
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
BUNDLE DESTINATION .
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
qt_finalize_executable(cbh)
|
||||
qt_finalize_executable(${PROJECT_NAME})
|
||||
|
||||
16
src/main.cpp
16
src/main.cpp
@@ -1,15 +1,25 @@
|
||||
#include "ElaApplication.h"
|
||||
#include <QScreen>
|
||||
#include <QApplication>
|
||||
#include "window.h"
|
||||
#include "clipboard.h"
|
||||
#include "winSpy.h"
|
||||
#include "window.h"
|
||||
#include <QApplication>
|
||||
#include <QScreen>
|
||||
#ifdef Q_OS_WIN
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QApplication a(argc, argv);
|
||||
// 设置消息模式:输出时间、类型、文件、行号和消息本身
|
||||
#ifdef QT_MESSAGELOGCONTEXT
|
||||
qSetMessagePattern("[%{time yyyy-MM-dd HH:mm:ss.zzz}] [%{type}] %{file}:%{line} - %{message}");
|
||||
#else
|
||||
qSetMessagePattern("[%{time yyyy-MM-dd HH:mm:ss.zzz}] [%{type}] - %{message}");
|
||||
#endif
|
||||
// 设置监听剪贴板
|
||||
ClipboardMonitor cbm(&a);
|
||||
// 设置监听系统窗口焦点变化
|
||||
WinSpy spy;
|
||||
eApp->init();
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
103
src/winSpy.cpp
Normal file
103
src/winSpy.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include <QDebug.h>
|
||||
#include <QString>
|
||||
#include <windows.h>
|
||||
|
||||
#include "winSpy.h"
|
||||
|
||||
// 全局变量,保存钩子句柄
|
||||
static HWINEVENTHOOK hook = NULL;
|
||||
|
||||
// 获取窗口标题的辅助函数
|
||||
QString GetWindowTitle(HWND hwnd) {
|
||||
char title[256];
|
||||
if (GetWindowTextA(hwnd, title, sizeof(title))) {
|
||||
return QString(title);
|
||||
}
|
||||
return "Untitled";
|
||||
}
|
||||
|
||||
// 获取窗口所属进程名的辅助函数
|
||||
QString GetWindowProcessName(HWND hwnd) {
|
||||
DWORD processId;
|
||||
GetWindowThreadProcessId(hwnd, &processId);
|
||||
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
|
||||
if (hProcess) {
|
||||
char processName[MAX_PATH];
|
||||
DWORD size = sizeof(processName);
|
||||
if (QueryFullProcessImageNameA(hProcess, 0, processName, &size)) {
|
||||
CloseHandle(hProcess);
|
||||
QString fullPath(processName);
|
||||
// 只返回可执行文件名称
|
||||
qsizetype lastSlash = fullPath.lastIndexOf("\\");
|
||||
if (lastSlash != -1) {
|
||||
return fullPath.mid(lastSlash + 1);
|
||||
}
|
||||
return fullPath;
|
||||
}
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
// 事件回调函数
|
||||
void CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread,
|
||||
DWORD dwmsEventTime) {
|
||||
|
||||
// 确保事件对象是窗口且事件是前台窗口改变
|
||||
if (idObject != OBJID_WINDOW || idChild != CHILDID_SELF) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == EVENT_SYSTEM_FOREGROUND) {
|
||||
HWND foregroundWindow = GetForegroundWindow(); // 获取当前前景窗口
|
||||
if (foregroundWindow) {
|
||||
QString title = GetWindowTitle(foregroundWindow);
|
||||
QString processName = GetWindowProcessName(foregroundWindow);
|
||||
// 记录信息,这里示例为输出到控制台
|
||||
qDebug() << "Foreground Window Changed:";
|
||||
qDebug() << " Handle: " << foregroundWindow;
|
||||
qDebug() << " Title: " << title;
|
||||
qDebug() << " Process: " << processName;
|
||||
qDebug() << "----------------------------------------";
|
||||
// TODO: 处理窗口数据保存
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WinSpy::setHook() {
|
||||
if (hook) {
|
||||
qDebug() << "Already monitoring.";
|
||||
return;
|
||||
}
|
||||
// 设置事件钩子,监听前台窗口变化事件
|
||||
hook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, // 最小事件值
|
||||
EVENT_SYSTEM_FOREGROUND, // 最大事件值
|
||||
NULL, // 钩子函数所在的DLL句柄(NULL表示当前进程)
|
||||
WinEventProc, // 事件回调函数指针
|
||||
0, // 感兴趣的进程ID(0表示所有进程)
|
||||
0, // 感兴趣的线程ID(0表示所有线程)
|
||||
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS // 标志:上下文外,跳过自身进程事件
|
||||
);
|
||||
|
||||
if (!hook) {
|
||||
qWarning() << "Failed to set win event hook!";
|
||||
return;
|
||||
}
|
||||
qDebug() << "Start monitoring foreground window changes";
|
||||
// // 消息循环是必须的,否则回调函数不会被调用
|
||||
// MSG msg;
|
||||
// while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
// TranslateMessage(&msg);
|
||||
// DispatchMessage(&msg);
|
||||
// }
|
||||
}
|
||||
|
||||
void WinSpy::freeHook() {
|
||||
// 程序退出前卸载钩子
|
||||
if (hook) {
|
||||
UnhookWinEvent(hook);
|
||||
}
|
||||
}
|
||||
|
||||
WinSpy::WinSpy() { setHook(); }
|
||||
WinSpy::~WinSpy() { freeHook(); }
|
||||
13
src/winSpy.h
Normal file
13
src/winSpy.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class WinSpy {
|
||||
public:
|
||||
WinSpy();
|
||||
~WinSpy();
|
||||
|
||||
private:
|
||||
void setHook();
|
||||
void freeHook();
|
||||
};
|
||||
Reference in New Issue
Block a user