修微信[S-A]读到侧栏文件列表而非聊天消息: _read_message_list加位置过滤>窗口45%右半侧才接受; 修QQ NT(Electron)新类名查找失败: EnumWindows加Chrome类名+标题含QQ搜索; config.py默认qq_enabled=True

This commit is contained in:
youpaishidifu
2026-07-26 18:15:50 +08:00
parent 0775ceaea7
commit 7aa3c9398e
2 changed files with 42 additions and 5 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ DEFAULT_CONFIG = {
"knowledge_base_path": "",
"poll_interval_seconds": 2.0,
"wechat_enabled": True,
"qq_enabled": False,
"qq_enabled": True,
"auto_reply_enabled": False,
"auto_reply_min_score": 0.35,
}
+41 -4
View File
@@ -175,7 +175,7 @@ class MessageMonitor:
except Exception:
pass
elif platform == "qq":
# 1. Win32 FindWindow 直搜 TXGuiFoundation(不走 UIA 枚举,不挂死)
# 1. Win32 FindWindow 直搜 TXGuiFoundation(旧版 QQ)
try:
hwnd = win32gui.FindWindow("TXGuiFoundation", None)
if hwnd:
@@ -191,12 +191,26 @@ class MessageMonitor:
return top
except Exception:
pass
# 2. Win32 EnumWindows 兜底(FindWindow 只返回第一个,多实例时用)
# 2. Win32 EnumWindows 兜底 — 类名+标题搜索
# QQ NT (Electron) 类名 Chrome_WidgetWin_1, 传统 QQ 类名 TXGuiFoundation
qq_titles = ("QQ", "TIM")
def _enum_callback(hwnd, results):
try:
cls = win32gui.GetClassName(hwnd)
title = win32gui.GetWindowText(hwnd)
title_upper = title.upper()
# 类名匹配(传统 QQ / TIM)
if cls == "TXGuiFoundation":
results.append(hwnd)
return True
# QQ NT Electron: 类名含 Chrome,标题含 QQ/TIM
if "Chrome" in cls and ("QQ" in title_upper or "TIM" in title_upper):
results.append(hwnd)
return True
# 标题完全匹配 QQ / TIM
if title_upper in qq_titles:
results.append(hwnd)
return True
except Exception:
pass
return True
@@ -212,7 +226,7 @@ class MessageMonitor:
self._app_variant[platform] = "tim" if "TIM" in title.upper() else "qq_nt"
self._cached_hwnd[platform] = top
self._cached_pid[platform] = win32process.GetWindowThreadProcessId(top)[1]
logger.info(f"[{platform}] 窗口已定位(Win32 Enum TXGuiFoundation): {title} top={top}")
logger.info(f"[{platform}] 窗口已定位(Win32 Enum): {title} top={top}")
return top
except Exception:
pass
@@ -1281,10 +1295,22 @@ class MessageMonitor:
return []
def _read_message_list(self, window) -> list:
# 只接受窗口右半侧(>45%)的 ListControl,避开侧栏/文件列表用同名控件
try:
wr = window.BoundingRectangle
boundary = wr.left + wr.width() * 0.45
except Exception:
boundary = 0
for name in ["消息", "Message"]:
try:
lst = window.ListControl(Name=name)
if lst.Exists(maxSearchSeconds=0.2):
try:
cr = lst.BoundingRectangle
if cr.left < boundary:
continue # 左侧的"消息"列表(文件/笔记预览)跳过
except Exception:
pass
self._scroll_to_bottom(lst)
texts = self._extract_last_line(lst)
if texts:
@@ -1295,10 +1321,21 @@ class MessageMonitor:
return []
def _read_conversation_list(self, window) -> list:
try:
wr = window.BoundingRectangle
boundary = wr.left + wr.width() * 0.45
except Exception:
boundary = 0
for name in ["会话", "聊天", "Chat"]:
try:
lst = window.ListControl(Name=name)
if lst.Exists(maxSearchSeconds=0.2):
try:
cr = lst.BoundingRectangle
if cr.left < boundary:
continue
except Exception:
pass
self._scroll_to_bottom(lst)
texts = self._extract_second_line(lst)
if texts:
@@ -1468,7 +1505,7 @@ class MessageMonitor:
# 1. 确保窗口句柄(带超时保护,防止 UIA COM 调用挂死不返回)
hwnd = self._ensure_hwnd_with_timeout(platform, timeout=12.0)
if not hwnd:
if counter % 10 == 0:
if counter % 10 == 0 or (counter == 1 and platform == "qq"):
logger.debug(f"[{platform}] 窗口未找到")
return