fix: 修复 Qt 5.12 MinGW 中 win_hotkey.cpp 的多个兼容性问题

1. nativeEventFilter 签名: qintptr* → long* (Qt 5 API)
2. QGuiApplication::instance()->winId() → QGuiApplication::topLevelWindows() (Qt 5 无此方法)
3. GlobalAddAtom → GlobalAddAtomW (MinGW 默认 ANSI 版本)
4. MOD_NOREPEAT 手动定义为 0x4000 (MinGW 7.3.0 SDK 未定义)
5. 添加 #include <QThread> 和 <QWindow> (避免不完整类型错误)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alvin Young 2026-05-13 18:02:05 +08:00
parent aa8bb18550
commit f9df226772

View File

@ -5,6 +5,14 @@
#include <windows.h>
#include <QAbstractNativeEventFilter>
#include <QGuiApplication>
#include <QThread>
#include <QMetaObject>
#include <QWindow>
// MOD_NOREPEAT 在 MinGW 7.3.0 的 Windows SDK 中未定义Windows 8+ 引入)
#ifndef MOD_NOREPEAT
#define MOD_NOREPEAT 0x4000
#endif
#endif
static const char* const kTag = "CapsLockVoiceHotkey";
@ -32,7 +40,7 @@ public:
: hotkey_(hotkey) {}
bool nativeEventFilter(const QByteArray& eventType, void* message,
qintptr* /*result*/) override {
long* /*result*/) override {
if (eventType == "windows_generic_MSG" || eventType == "windows_dispatcher_MSG") {
auto* msg = static_cast<MSG*>(message);
if (msg->message == WM_HOTKEY) {
@ -63,9 +71,12 @@ bool CapsLockVoiceHotkey::start() {
if (active_) return true;
#ifdef Q_OS_WIN
HWND hwnd = reinterpret_cast<HWND>(QGuiApplication::instance()->winId());
HWND hwnd = nullptr;
QWindow* window = QGuiApplication::topLevelWindows().value(0, nullptr);
if (window) {
hwnd = reinterpret_cast<HWND>(window->winId());
}
if (!hwnd) {
// Try to get the top-level widget's window handle
hwnd = GetForegroundWindow();
}
@ -77,7 +88,7 @@ bool CapsLockVoiceHotkey::start() {
// 注册 CapsLock (VK_CAPITAL = 0x14) 全局快捷键
// MOD_NOREPEAT 防止按住时重复触发
const int vkCapsLock = 0x14;
impl_->hotkeyId = GlobalAddAtom(L"ImpressVoiceHotkey");
impl_->hotkeyId = GlobalAddAtomW(L"ImpressVoiceHotkey");
BOOL ok = RegisterHotKey(hwnd, impl_->hotkeyId, MOD_NOREPEAT, vkCapsLock);
if (!ok) {
@ -146,7 +157,14 @@ void CapsLockVoiceHotkey::stop() {
}
// 注销快捷键
HWND hwnd = reinterpret_cast<HWND>(QGuiApplication::instance()->winId());
HWND hwnd = nullptr;
QWindow* stopWindow = QGuiApplication::topLevelWindows().value(0, nullptr);
if (stopWindow) {
hwnd = reinterpret_cast<HWND>(stopWindow->winId());
}
if (!hwnd) {
hwnd = GetForegroundWindow();
}
if (hwnd && impl_->hotkeyId) {
UnregisterHotKey(hwnd, impl_->hotkeyId);
GlobalDeleteAtom(impl_->hotkeyId);