热血江湖 YGOnline.exe —— 组队窗口(7034/7035)实测 与 窗口弹出判定修正 时间:2026-09-28 14:2x 目标:D:\rxjh2025\client\YGOnline.exe(32位,无ASLR,模块基址恒 0x400000) 本次 PID:14256 ================================================================================ 【2026-09-28 14:34 二次修正】本文第四节公式的"条件① 窗口对象自身 +0x40 == 1" 已被删除,不能用:交易窗口关闭后它仍 = 1(粘滞),会把关着的窗口判成"还开着"。 正确判据只剩一条 ——【类型码 24 的内容面板 +0x40 == 1】。 ★ 定稿版公式、全窗口面板偏移速查表、可直接粘贴的易语言子程序,见 《窗口弹出判定_通用方法_0928.txt》。本文第五节里那个 窗口是否显示 子程序已作废。 一、7034 / 7035 的归属(活体反查结果) -------------------------------------------------------------------------------- 父窗口 → IFManager + 0x4E8 (十进制 1256) = InterParty(组队窗口) 窗口对象 = 0x3769FA70 id = 7029 你给的按钮: 7034 = 组队窗口 + 0x3B8 (952) ButtonClass 位置 85,178 大小 18x60 7035 = 组队窗口 + 0x3C0 (960) ButtonClass 位置 156,178 大小 18x60 ★ 关于"父窗口 7030 / 子窗口 7034 7035"——实测澄清(重要,影响怎么写代码): 内存里的父子关系,和界面上看到的层级【不是一回事】。实测数据: InterParty 对象 = 0x3769FA70 id=7029 7030 面板 = 0x577C46B8 id=7030 类型 24(InterWindow) 虚表 010F26CC 7034 按钮 = 0x572C9D00 id=7034 类型 34(ButtonClass) 虚表 010F1EE4 7035 按钮 = 0x572C28D8 id=7035 类型 34(ButtonClass) 虚表 010F1EE4 · 7034/7035 的 +0x04 父指针 → 0x3769FA70 =【InterParty 接口对象】(7029),不是 7030; · 把 7030 面板的 0x000~0x400 全扫一遍,它里面【没有】7034/7035,只有 +0x04 指回父; · 反过来把 7034 的 +0x00~0x300 全扫一遍,只有 +0x04 出现 InterParty 地址, 【没有任何位置指向 7030】。 也就是说:7030 面板和 7034/7035 按钮在内存里是【兄弟】,都挂在 InterParty 对象的 并列子槽上(面板在 +0x330,按钮在 +0x3B8 / +0x3C0)。它们只是画在一起(按钮显示在 面板范围内),CE 的界面树才把它们归成父子。 ⇒ 取按钮【不要从 7030 往下找】,直接从组队窗口对象按固定偏移拿: 按钮7034 = 读整数(读整数(#IFManager基址) + 1256 + 0x3B8) 按钮7035 = 读整数(读整数(#IFManager基址) + 1256 + 0x3C0) 顺带把这一批子控件的槽位对齐(本次实例): win+0x330 → id 7030 (InterWindow 面板) win+0x3A4 → id 7031 (InterSTATIC) win+0x3A8 → id 7032 (Button 中, 119,178) win+0x3B4 → id 7033 (InterSTATIC) win+0x3B8 → id 7034 (Button 左, 85,178) win+0x3C0 → id 7035 (Button 右, 156,178) 即 ID 是连续分配的:7029(窗口) → 7030(面板) → 7031..7035(各子控件)。 参照:交易窗口 0x4D4 的按钮是 6700/6701,同样落在 85,178 / 156,178 —— 两个窗口 用的是同一套对话框模板(并排两根竖长条按钮),所以位置完全一样。 二、★ 重大修正:窗口对象自身的 +0x40 不是"当前是否显示" -------------------------------------------------------------------------------- 这次实测把原来的判定公式打翻了: InterParty(组队窗口,你确认现在正显示): 窗口对象 +0x40 = 0 ← 按老公式会判成"没弹出",但它在屏幕上 同一次读数里(全部 86 个槽): slot id self+40 +0x330 子对象 +0x334 子对象 3AC 108 1 (HUD,无 InterWindow) 3B0 904 1 (HUD) 3C4 1297 1 (HUD) 4D4 6695 1 InterWindow 6707 vis=0 InterWindow 6696 vis=0 ← 交易窗:已关 4E8 7029 0 InterWindow 7030 vis=1 - ← 组队窗:正显示 ...其余 40+ 个窗口的 InterWindow 子对象 vis 全部 = 0 ★ 真正表示"当前在屏幕上"的是【内容面板 InterWindow(类型码 24)子对象的 +0x40】: 交易窗口:面板在 +0x330(大页 475x280) 和 +0x334(申请页 220x300) 上午 pid 16164 交易窗开着时 → +0x334 面板 vis = 1 本次 pid 14256 交易窗已关 → +0x330 / +0x334 面板 vis 都 = 0 组队窗口:面板在 +0x330(220x300) 本次正显示 → vis = 1 三者互相印证,闭环。 ⇒ 窗口对象自身的 +0x40 是"曾激活过"的粘滞标志(一旦打开过就保持 1,关窗不清零), 不能用来判断"此刻是否弹出"。 三、★ 另一条修正:子控件的 +0x40 也完全不能当可见性用 -------------------------------------------------------------------------------- 本次扫描里,一大堆【从未打开过】的窗口,其子按钮/列表的 +0x40 也是 1,例如: 3B8 InterInventory 的 +0x330/+0x334 按钮 vis=1(背包根本没开) 400 InterLuckyBox 的 +0x334 按钮 vis=1 4F8 InterWar 的 +0x334 TextBox vis=1 534/538/540/544/548 的 +0x334 ListCtrl vis=1 → 子控件的 +0x40 更接近"已创建/已启用",与是否显示无关。 → 唯一干净、有区分度的是【类型码 24 = InterWindow 的内容面板】这一个信号。 四、修正后的通用判定公式(定稿) -------------------------------------------------------------------------------- 窗口对象 = 读整数( 读整数(#IFManager基址) + 槽偏移 ) 已弹出: ① 读整数(窗口对象 + 0x40) == 1 ' 常驻 HUD 用这条 ② 或 在该窗口的全部子槽里,存在 类型码==24 的子对象 且 读整数(该子对象 + 0x40) == 1 ' 对话框类(交易/组队)用这条 满足任一即视为"正在显示"。 实测校验:这条公式对当前屏上三个 HUD + 组队窗口 全部判"显示", 对已关闭的交易窗口和其余 80 多个接口 全部判"未显示"。 ★★ 换窗口实测复核(2026-09-28 14:3x,同一客户端 pid 14256,公式一次通过): 状态 InterParty(0x4E8)面板7030 InterExchange(0x4D4)面板6696 ----------------- -------------------------- ----------------------------- 组队窗弹着 vis = 1 vis = 0 (换成交易窗后) vis = 0 vis = 1 两个信号精确互补翻转,与屏幕上实际显示完全一致。 同一时间段里 InterExchange 的 self+0x40 始终 = 1 —— 若按旧公式, 组队窗关闭后根本区分不出来,这再次印证了修正的必要性。 换窗口后交易窗口的当前可点按钮(本次实例): +0x38C id = 6700 ButtonClass 85,178 18x60 左按钮(可见) +0x394 id = 6701 ButtonClass 156,178 18x60 右按钮(可见) +0x37C id = 6698 ButtonClass 119,178 18x60 中按钮(vis=0,本阶段未启用) 同排的 +0x378 / +0x388 是 InterSTATIC 文字标签(6697 / 6699)。 五、易语言子程序 ================================================================================ .版本 2 .常量 IFManager基址, "25740828" .常量 窗口显示标志, "64" .常量 交易窗口槽, "1236" .常量 组队窗口槽, "1256" .版本 2 .子程序 窗口是否显示, 逻辑型, , 通用:传 IFManager 槽偏移,判断该窗口此刻是否在屏幕上 .参数 槽偏移, 整数型 .局部变量 接口管理, 整数型 .局部变量 窗口对象, 整数型 .局部变量 i, 整数型 .局部变量 子对象, 整数型 接口管理 = 内存_读整数型 (全局_进程句柄, #IFManager基址) .如果真 (接口管理 ≤ 65536) 返回 (假) .如果真结束 窗口对象 = 内存_读整数型 (全局_进程句柄, 接口管理 + 槽偏移) .如果真 (窗口对象 ≤ 65536) 返回 (假) .如果真结束 .如果真 (内存_读整数型 (全局_进程句柄, 窗口对象 + #窗口显示标志) = 1) 返回 (真) .如果真结束 .计次循环首 (73, i) 子对象 = 内存_读整数型 (全局_进程句柄, 窗口对象 + 768 + (i - 1) × 4) .如果真 (子对象 > 65536) .如果真 (内存_读整数型 (全局_进程句柄, 子对象 + 8) = 24) .如果真 (内存_读整数型 (全局_进程句柄, 子对象 + #窗口显示标志) = 1) 返回 (真) .如果真结束 .如果真结束 .如果真结束 .计次循环尾 () 返回 (假) .版本 2 .子程序 组队窗口是否弹出, 逻辑型 返回 (窗口是否显示 (#组队窗口槽)) .版本 2 .子程序 交易窗口是否弹出, 逻辑型 返回 (窗口是否显示 (#交易窗口槽)) .版本 2 .子程序 点击组队窗口按钮, , , 序号 1=左按钮(7034, 85,178) 2=右按钮(7035, 156,178) .参数 序号, 整数型 .局部变量 接口管理, 整数型 .局部变量 组队窗口, 整数型 .局部变量 按钮对象, 整数型 .局部变量 偏移, 整数型 接口管理 = 内存_读整数型 (全局_进程句柄, #IFManager基址) 组队窗口 = 内存_读整数型 (全局_进程句柄, 接口管理 + #组队窗口槽) .如果真 (组队窗口 ≤ 65536) 返回 () .如果真结束 .如果 (序号 = 1) 偏移 = 952 .否则 偏移 = 960 .如果结束 按钮对象 = 内存_读整数型 (全局_进程句柄, 组队窗口 + 偏移) 按钮点击call (内存_读整数型 (全局_进程句柄, 按钮对象 + 12)) (按钮点击call 子程序 = 派发事件 0x409 + 控件ID 给 [0x0188C60C],机器码见 《窗口弹出状态与遍历_0928.txt》第八节。控件ID 必须从 按钮对象 + 0x0C 现读。) 六、InterParty(组队窗口)完整子控件表 —— 本次实测 -------------------------------------------------------------------------------- 窗口对象 0x3769FA70 id=7029 偏移 对象 类型 控件ID 可见 位置x,y 大小cx,cy 说明 +0x330 577C46B8 InterWindow 7030 1 362,95 220,300 ★内容面板(显示中) +0x3A4 5774C0B0 InterSTATIC 7031 0 0,0 0,0 (标签,未用) +0x3A8 572C5518 ButtonClass 7032 0 119,178 18,60 (中按钮,未用) +0x3B4 577502C8 InterSTATIC 7033 1 0,0 0,0 (标签) +0x3B8 572C9D00 ButtonClass 7034 1 85,178 18,60 ★你给的按钮A +0x3C0 572C28D8 ButtonClass 7035 1 156,178 18,60 ★你给的按钮B +0x3D4 57C73260 InterWindow 7308 0 1,132 15,70 (队员格1) +0x3D8 57C76868 InterWindow 7309 0 1,132 43,70 (队员格2) +0x3DC 56EFCD30 接口 7312 0 2,2 26,26 (小状态格1) +0x3E0 56EF7F80 接口 7313 0 30,2 26,26 (小状态格2) +0x3E4 56EF7160 接口 7314 0 58,2 26,26 (小状态格3) +0x3E8 56EF8690 接口 7315 0 86,2 26,26 (小状态格4) +0x3EC 56EFD0B8 接口 7316 0 114,2 26,26 (小状态格5) +0x3F0 56EFC9A8 接口 7317 0 142,2 26,26 (小状态格6) +0x3F4 56EF9838 接口 7318 0 170,2 26,26 (小状态格7) +0x3F8 56EF9BC0 接口 7319 0 198,2 26,26 (小状态格8) +0x400 57B13970 ButtonClass 7310 1 0,0 15,70 (侧按钮) +0x404 57B107A8 ButtonClass 7311 1 0,28 15,70 (侧按钮) 结构特点:组队窗口没有 TextBox 子控件(交易窗口有 8 个);它的 7030 面板 + 8 个 队员/状态格 + 2~3 个按钮,是"申请入队/组队确认"这类简洁对话框。 七、对交易窗口按钮 6700/6701 的重新确认(同一次读数) -------------------------------------------------------------------------------- 交易窗口 0x4D4 对象 0x47DA8A98,本次(窗口已关): +0x37C id=6698 vis=0 (119,178) +0x38C id=6700 vis=1 (85,178) +0x394 id=6701 vis=1 (156,178) +0x330 面板 id=6707 vis=0 +0x334 面板 id=6696 vis=0 按钮 vis 仍是 1,但面板 vis=0 —— 再次说明按钮 vis 不可信、面板 vis 才可信。 ================================================================================ 实测脚本(D:\ce_mcp\) _t6.py 反查指定控件ID 落在哪个窗口 _t7.py 交易/组队/通知三个窗口的结构对比 _t8.py 窗口对象头 0x00~0x7C 全字段横向对比(找显示标志) _t10.py 父链验证 + 全窗口 self+0x40 与面板可见性 ================================================================================