Python检测Windows窗口句柄信息:枚举、解析与避坑指南
简介Python自动化开发中窗口句柄获取是桌面端自动化测试与系统监控的常见需求。面向有Python基础、正着手Windows窗体交互开发的学习者或测试工程师内容演示如何通过pywin32封装库枚举窗口、依据标题或类名匹配句柄并支持对窗口执行显示、隐藏、最大化等常规操作用于解决GUI自动化中窗口定位与控制的实际问题。压缩包共6个文件体积约14KB其中Py脚本为可直接运行的示例代码直观呈现句柄枚举与匹配逻辑ico为窗口图标文件3张png图片和txt说明文档分别用于界面展示与项目背景介绍便于对照代码快速学习。已有237人浏览学习适合需要掌握窗口句柄检测思路、Windows API封装用法及回调函数编写技巧的读者。通过脚本与说明文档的组合可了解EnumWindows回调机制、句柄判断条件及多窗口匹配场景下的处理方式为桌面自动化项目提供可直接改造的代码基础。1. 从拿句柄到懂句柄python 检测窗口程序句柄信息到底在查什么做 Windows 桌面自动化的人最常翻车的往往不是点击逻辑而是连窗口都找不对。python 检测窗口程序句柄信息本质上是查 Windows 给每个顶层窗口发的“身份证号”——HWND。这份资源把枚举窗口、读标题、读类名、读进程号 PID、判断可见状态的完整脚本都拆开了还附带一个拿句柄做窗口存活监控的 Demo。不是只有自动化才用得上句柄。排查程序为什么没弹窗、判断某应用是否在前台、给后台窗口发消息第一步都是先拿到句柄并读懂它。适合谁写自动化脚本的、做桌面监控的、被“找不到窗口”卡住的人。后半部分是踩坑实录新手照着能跑通熟手可以直接翻到边界条件那几节。2. 通道选型ctypes 直调与 pywin32 封装怎么挑才不后悔2.1 ctypes 直调 user32不装第三方依赖也能枚举窗口Python 操作 Windows 窗口句柄底层只有一条路调 user32.dll 里的 EnumWindows、FindWindowW、GetWindowTextW 这一组 API。区别只在于你直接写 ctypes还是用 pywin32 的 win32gui 帮你把类型声明包好。先说 ctypes 通道它在标准库里就能跑目标机器上有 Python 就能执行不用 pip install 任何东西对一个要散给同事的排查脚本来说非常省事。import ctypes from ctypes import wintypes user32 ctypes.windll.user32 # 声明回调类型EnumWindows 走的是 stdcall 约定必须用 WINFUNCTYPE EnumWindowsProc ctypes.WINFUNCTYPE( wintypes.BOOL, # 返回值True 继续枚举False 停止 wintypes.HWND, # 第一个参数窗口句柄 wintypes.LPARAM # 第二个参数外部透传的 lparam ) hwnds [] EnumWindowsProc def on_enum(hwnd, lparam): hwnds.append(hwnd) return True ok user32.EnumWindows(on_enum, 0) if not ok: raise ctypes.WinError() print(顶层窗口数量:, len(hwnds)) print(首个句柄:, hwnds[0] if hwnds else 0)逻辑说明EnumWindows 按 Z 序从上到下遍历所有顶层窗口每遇到一个就把句柄交给回调。回调里只做两件事——把 hwnd 追加进列表、返回 True 表示继续。这里有个关键点回调函数对象必须被命名变量或装饰器持有如果写成临时 lambda 并且没有引用Python 的垃圾回收可能把它收掉导致枚举中途崩掉或者枚举结果不完整这类问题非常难查。参数说明回调返回 True 表示继续枚举返回 False 是提前终止的开关适合“找到目标就停”的场景。lparam 是枚举时透传的上下文参数单次枚举传 0 就行如果要分批处理可以把自定义的计数结构体指针传进去回调里直接往那个结构体里写结果。另外注意 EnumWindows 返回非零只代表“枚举过程顺利完成”不代表“有窗口”如果你发现句柄列表为空先怀疑这个再怀疑是不是真的没有带标题的顶层窗口。2.2 pywin32 的 win32gui封装顺手但有两个隐藏限制如果环境允许安装第三方包win32gui 能帮你省掉一大段类型声明。枚举的写法更接近普通 Python 代码回调逻辑和 ctypes 版完全一致返回值同样是“True 继续、False 停止”。import win32gui def on_enum(hwnd, lparam): print(窗口句柄:, hwnd, 透传参数:, lparam) return True win32gui.EnumWindows(on_enum, 0)这段代码和 ctypes 版是同一个调用链win32gui 内部把回调类型、句柄类型都处理好了后续的 GetWindowText、GetClassName 也都是现成封装不需要自己再 create_unicode_buffer。但封装顺手不代表没有坑我踩过两个隐藏限制第一是位数必须匹配。pywin32 的 32 位包和 64 位包不能混装Python 解释器是 32 位的就必须装 32 位版本否则 import 阶段直接抛 ImportError错误信息还不太友好新人容易误判成“包没装好”。第二是错误信息被吞掉一部分。win32gui 部分函数抛出的 OSError 参数给不全你拿不到 GetLastError 的精确错误码遇到诡异行为时我一般会回退到 ctypes 重新调一遍同一个 API用 ctypes.WinError() 把底层错误翻出来。简单说pywin32 适合“跑得通就行”的场景ctypes 适合“我要知道为什么跑不通”的场景。2.3 选型对照一次性脚本与长期维护工具的分水岭场景ctypes 直调pywin32 封装一次性排查脚本优先无依赖可用内网离线环境批量下发优先标准库即可不推荐装包困难长期运行的窗口监控服务可用要把 argtypes 封装成工具函数优先代码更短需要读注册表、操作文件等更多 win32 能力不选会很痛苦优先我的习惯是预计三天之内跑完就删的脚本一律用 ctypes要长期巡检定时的工具用 pywin32 省维护成本因为枚举、取文本、查类名这些高频操作都有现成接口出错时定位到封装层就行。这份资源里两个版本各留了一份枚举脚本实际用的时候按目标机器的 Python 环境挑一个不必两套都部署。2.4 句柄的本质别把 HWND 当普通整数算句柄是 Windows 给窗口对象发的“票据”底层其实是一个指针宽度的整数值可以打印、可以比较但你不能对它做加减乘除也不能假设值大的窗口就一定排在后面。更值得警惕的是句柄复用机制——窗口销毁后系统可能把同一个句柄值分配给之后新建的另一个窗口。很多人说这是玄学其实官方就是这么设计的句柄只在“窗口存活期间”有效存下来的句柄隔一段时间再拿来用完全可能操作到另一个程序。所以后面所有脚本里我都在“用句柄之前先验证句柄”这也是资源里反复出现的一个主题。3. 实战枚举一次拉全量顶层窗口并解析标题、类名与 PID3.1 带完整类型声明的枚举脚本第 2 章的最小脚本只拿到了句柄这章把它补齐到“能直接用”的完整版本。核心是 5 个 APIGetWindowTextLengthW 取标题长度、GetWindowTextW 取标题、GetClassNameW 取类名、GetWindowThreadProcessId 取 PID 和线程号、GetWindowLongW 取窗口样式。import ctypes from ctypes import wintypes user32 ctypes.windll.user32 # 显式声明参数和返回值类型这一步在 64 位系统上是必须的 EnumWindowsProc ctypes.WINFUNCTYPE( wintypes.BOOL, wintypes.HWND, wintypes.LPARAM ) user32.GetWindowTextLengthW.argtypes [wintypes.HWND] user32.GetWindowTextLengthW.restype ctypes.c_int user32.GetWindowTextW.argtypes [wintypes.HWND, wintypes.LPWSTR, ctypes.c_int] user32.GetWindowTextW.restype ctypes.c_int user32.GetClassNameW.argtypes [wintypes.HWND, wintypes.LPWSTR, ctypes.c_int] user32.GetClassNameW.restype ctypes.c_int user32.GetWindowThreadProcessId.argtypes [ wintypes.HWND, ctypes.POINTER(wintypes.DWORD) ] user32.GetWindowThreadProcessId.restype wintypes.DWORD user32.GetWindowLongW.argtypes [wintypes.HWND, ctypes.c_int] user32.GetWindowLongW.restype ctypes.c_long GWL_STYLE -16 WS_VISIBLE 0x10000000 windows [] EnumWindowsProc def _on_enum(hwnd, lparam): # 先取标题长度动态分配缓冲区避免 256 字节截断 length user32.GetWindowTextLengthW(hwnd) if length 0: return True # 空标题窗口先跳过后面会说明为什么不直接丢弃 buf ctypes.create_unicode_buffer(length 1) user32.GetWindowTextW(hwnd, buf, length 1) cls_buf ctypes.create_unicode_buffer(256) user32.GetClassNameW(hwnd, cls_buf, 256) pid wintypes.DWORD() thread_id user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid)) style user32.GetWindowLongW(hwnd, GWL_STYLE) 0xFFFFFFFF windows.append({ hwnd: hwnd, title: buf.value, class: cls_buf.value, pid: pid.value, thread: thread_id, visible: bool(style WS_VISIBLE), }) return True user32.EnumWindows(_on_enum, 0) print(f共 {len(windows)} 个带标题的顶层窗口) for w in sorted(windows, keylambda x: x[pid]): print(w)逻辑说明回调里先查标题长度是为了避免固定缓冲区把长标题截断标题是用户随时能改的动态内容窗口切换时长度可能变。类名缓冲区固定开 256 就够Windows 类名有上限。GetWindowThreadProcessId 接受一个 DWORD 指针通过 byref 传地址返回值是线程号PID 写到 pid 变量里。最后用 GetWindowLongW 读 GWL_STYLE和 WS_VISIBLE 按位与判断窗口带不带可见样式。参数说明WS_VISIBLE 的十六进制值是 0x10000000判断可见性还有一种更直接的方式是调 IsWindowVisible但注意两者语义不完全一样后者会沿父窗口链逐级检查前者只看窗口自身的样式位。资源包里的脚本默认用样式位判断原因见第 4 章“最小化窗口”那一节。GetWindowLongW 返回的是有符号 long在 Python 里和 0x10000000 按位与时先做 0xFFFFFFFF转成无符号否则高位符号位会干扰判断结果。3.2 字段含义与常见用途字段含义常见用途hwnd窗口句柄64 位整数值后续 SendMessage、SetForegroundWindow 的入参title窗口标题Unicode 字符串按标题匹配窗口注意是完全匹配还是模糊匹配class窗口类名区分“标题相同但类型不同”的窗口pid所属进程号反查进程、判断程序是否存活thread创建窗口的线程号判断窗口属于哪个线程配合输入模拟使用visible是否带 WS_VISIBLE 样式过滤掉隐藏的托盘窗口和消息窗口这张表对应的是资源里数据结构的完整解释。实际拿到的结果里title 为空的窗口占了绝大多数它们大多是系统的隐藏消息窗口、托盘图标窗口或者已经销毁但句柄还没回收的残留。脚本里我选择返回 True 跳过是为了让结果聚焦到“人眼能看到”的窗口上如果你在做后台自动化反而要保留空标题窗口因为有些程序的主窗口就是设计成不可见但接收消息的。3.3 过滤、分组与排序让结果可读全量枚举结果可能上百条直接打印没法看。我一般会做两层处理第一层过滤掉不可见窗口第二层按 PID 分组看每个进程到底开了几个顶层窗口。from collections import defaultdict # 第一层过滤只要可见并且标题非空 visible_named [ w for w in windows if w[visible] and w[title].strip() ] # 第二层按 PID 分组统计每个进程的窗口数 by_pid defaultdict(list) for w in visible_named: by_pid[w[pid]].append(w[title]) print(可见且有标题的窗口数:, len(visible_named)) for pid, titles in sorted(by_pid.items()): print(fPID {pid}: {len(titles)} 个窗口 - {titles[:3]})这段代码的价值在于很多程序会开不止一个顶层窗口比如主窗口加一个隐藏的更新检查窗口。如果你只按“找到第一个窗口”来判断程序状态大概率踩进“窗口在但功能没起来”的误判。按 PID 分组后一眼就能看出哪些是主窗口、哪些是辅助窗口。排序时我用 sorted 的 key 指定 pid输出顺序固定后续做差异对比时不会被枚举顺序干扰。要注意的是visible 字段来自样式位判断隐藏窗口不一定没作用过滤时想想你的目标是“看得到”还是“存在”。4. 精确查找FindWindow 定位、后台窗口与 PID 反查的三个进阶场景4.1 FindWindow 与 FindWindowEx按标题和类名锁定唯一窗口全量枚举适合“不知道窗口叫什么”的阶段一旦你确定目标窗口的标题或类名直接用 FindWindowW 更高效。这个 API 的参数是类名和标题都可以传 None 表示不限制。import ctypes from ctypes import wintypes user32 ctypes.windll.user32 user32.FindWindowW.argtypes [wintypes.LPCWSTR, wintypes.LPCWSTR] user32.FindWindowW.restype wintypes.HWND hwnd user32.FindWindowW(None, 设置) if hwnd: title_buf ctypes.create_unicode_buffer(256) user32.GetWindowTextW(hwnd, title_buf, 256) print(命中句柄:, hwnd, 实际标题:, title_buf.value) else: print(未找到窗口注意 FindWindow 要求标题完全一致不是子串匹配)这里最容易翻车的点是匹配规则。FindWindowW 对标题做的是完全匹配不是模糊匹配。你以为传“设置”能命中“设置 - 快捷方式”结果是 NULL。更麻烦的是标题带不带空格、全角半角、是否包含隐藏字符都会影响匹配结果。所以我的习惯是能确定类名就用类名标题双条件把误命中率压到最低标题不确定时老老实实回到第 3 章的枚举脚本用 startswith 或包含判断自己做模糊匹配。FindWindowExW 是它的子窗口版本适合在已知父窗口里找按钮、编辑框这类控件窗口。user32.FindWindowExW.argtypes [ wintypes.HWND, wintypes.HWND, wintypes.LPCWSTR, wintypes.LPCWSTR ] user32.FindWindowExW.restype wintypes.HWND # 在 parent_hwnd 下找第一个类名为 Button、文本为 确定 的子窗口 child user32.FindWindowExW(parent_hwnd, None, Button, 确定) if child: print(子窗口句柄:, child)第一个参数是父窗口句柄第二个参数是“从哪个子窗口之后继续找”传 None 表示从头找。想遍历同类的多个子窗口就不断把上一次的结果传给第二个参数循环直到返回 0。这个技巧在自动化点按钮场景里很实用一个对话框可能有两个按钮文本相同第二个参数配合窗口顺序能精确定位到我们要的那个。4.2 可见性、最小化与消息窗口三种状态不要搞混IsWindowVisible 这个名字很有误导性。它检查的是窗口自身带不带 WS_VISIBLE并且父窗口链上的每一级都可见。一个最小化的顶层窗口如果它带 WS_VISIBLE 样式IsWindowVisible 照样返回 True。要判断“是不是最小化”得用 IsIconic。user32.IsWindowVisible.argtypes [wintypes.HWND] user32.IsWindowVisible.restype wintypes.BOOL user32.IsIconic.argtypes [wintypes.HWND] user32.IsIconic.restype wintypes.BOOL visible bool(user32.IsWindowVisible(hwnd)) minimized bool(user32.IsIconic(hwnd)) if visible and not minimized: state 正常显示 elif visible and minimized: state 最小化但样式仍可见 else: state 隐藏 print(窗口状态:, state)这三者必须分开记样式可见、实际显示、最小化是正交的状态。资源包里有一个状态判断函数就是把它们组合起来输出成“正常/最小化/隐藏”三态监控脚本里据此决定要不要对窗口做后续操作。另外要特别注意一类“消息窗口”它们用 HWND_MESSAGE 这类特殊父句柄EnumWindows 根本枚举不到FindWindow 也找不到如果你确定程序在跑却怎么都查不到窗口先怀疑是不是这种特殊窗口。4.3 PID 反查窗口从进程号回到窗口列表另一条常见路径是反过来的你已经知道目标进程的 PID想知道它开了哪些窗口、有没有弹主界面。实现不复杂在第 3 章收集的 windows 列表上做一次过滤即可。def find_windows_of_pid(target_pid, windows): return [w for w in windows if w[pid] target_pid] target_pid 12345 hits find_windows_of_pid(target_pid, windows) print(该进程的顶层窗口数量:, len(hits)) for w in hits: print(hex(w[hwnd]), w[title], 可见 if w[visible] else 隐藏)一个进程拥有多个顶层窗口是常态。比较典型的是某些聊天类软件主窗口之外还会维护一个隐藏的消息窗口句柄。如果监控逻辑只认第一个窗口就可能出现“进程活着、主窗口没起来”的漏判。我的做法是先按 PID 过滤再按 visible 字段区分至少存在一个可见窗口才算业务意义上的“前台起来了”。这比单纯判断进程是否存在要准确得多也算把句柄信息和进程状态打通了。5. 避坑通告句柄失效、中文乱码与权限不足的五个真实现场5.1 现场一64 位 Python 下 PID 读成 0枚举还偶尔崩溃现象同一段脚本在 32 位 Python 下跑得好好的换成 64 位后GetWindowThreadProcessId 写回 pid 的值变成 0甚至偶尔整个进程崩溃退出。原因ctypes.windll 默认不检查参数类型64 位系统上句柄和指针都是 64 位的而 ctypes 默认把参数按 32 位处理传进去的 DWORD 指针被截断了底层 API 往错误地址写数据轻则写到不存在的内存位置重则直接访问冲突。解决调用前必须显式声明 argtypes 和 restype就是第 3 章代码里那一长串声明。特别是 GetWindowThreadProcessId第二参数必须声明成ctypes.POINTER(wintypes.DWORD)然后用ctypes.byref(pid)传地址。从那以后我写这类脚本的先手动作就是先把涉及句柄、指针的 API 声明齐了再写业务代码这已经成了肌肉记忆。5.2 现场二窗口标题里的中文显示成乱码现象EnumWindows 拿到的 title 字段英文正常中文全是问号或者把 UTF-8 字节当拉丁字符解完全没法做匹配。原因用了 ANSI 版本的 GetWindowTextA 而不是 Unicode 版本的 GetWindowTextW或者虽然用了 W 版却用 ctypes.create_string_buffer 去接返回值把 UTF-16 当成了单字节串。解决窗口 API 一律优先 W 后缀缓冲区用 create_unicode_buffer。这里有个细节GetWindowTextW 的第二个参数类型要声明成wintypes.LPWSTR而不是c_char_p否则 ctypes 会自动做字节串转换中文标题照样坏。资源包里的脚本统一走 W 版就是这个原因Windows 10 之后几乎所有窗口标题都是 UTF-16A 版在中文系统上就是个定时炸弹。5.3 现场三回调里做耗时操作枚举过程慢得像卡死现象把网络请求、数据库写入直接写进 EnumWindows 的回调里结果枚举一个窗口要几百毫秒全量跑完要几十秒界面就像假死。原因EnumWindows 是同步枚举回调里每一步慢操作都会被放大几十甚至上百倍还有一个更隐蔽的问题如果在回调里再次调用枚举相关 API会形成递归栈一深就爆。解决回调里只做一件事——把 hwnd 收集进列表。所有耗时操作放到主流程里等枚举完全结束后再统一处理。第 3 章的写法就是这么拆的回调只 build 列表排序、过滤、分组全在主流程。这个设计看似多了一步实际是给后续所有业务逻辑留了余地我强烈建议别省。5.4 现场四窗口已经关了句柄还能查到并操作“错窗口”现象脚本先存下句柄几分钟后再拿它发消息结果窗口标题对不上有时候干脆操作到了别的程序。原因句柄是动态票据窗口销毁后句柄就失效了而且系统会复用句柄值新窗口可能拿到同一个数字。你操作的是“这个数字现在代表的新窗口”。解决每次使用前做两步校验。第一步调 IsWindow(hwnd) 确认句柄还对应一个有效窗口第二步重读标题或者类名和期望值比对第三步最好再用 GetWindowThreadProcessId 确认 PID 也一致。三层都过了才继续操作。这看起来啰嗦但监控类脚本挂一晚上不崩靠的就是这种防御性检查。资源里的监控 Demo 集成了这套校验逻辑可以直接复用。5.5 现场五EnumWindows 枚举不到目标程序或漏掉托盘图标现象目标进程明明在运行EnumWindows 的结果里却没有它的任何窗口有时候又反过来托盘图标程序枚举出了窗口但全部是隐藏状态。原因EnumWindows 只管顶层窗口且不包含消息窗口。很多常驻程序故意把主窗口设为隐藏只在托盘留个图标还有一些程序把窗口创建在别的会话或桌面里当前会话的枚举根本看不到。解决先确认进程本身在不在用 OpenProcess 或任务管理器核对 PID如果进程在但没有可见窗口多半是程序设计成驻留后台这时要接受“没有可见窗口”这个结果而不是怀疑枚举代码坏了。如果涉及多会话场景比如服务程序在 Session 0 里弹窗普通用户会话的脚本根本拿不到那个句柄这是会话隔离机制在作怪换个思路从服务端查而不是跟枚举 API 较劲。6. 把句柄检查养成三步习惯IsWindow、重读标题、验 PID 存活最后一个技巧是把第 5 章的三层校验做成一个可复用的小函数配合轮询就能变成一个简单的窗口存活监控器。核心逻辑是句柄有效、标题符合预期、进程还活着三者同时满足才认为窗口可用。import ctypes from ctypes import wintypes user32 ctypes.windll.user32 kernel32 ctypes.windll.kernel32 SYNCHRONIZE 0x00100000 WAIT_TIMEOUT 0x00000102 user32.IsWindow.argtypes [wintypes.HWND] user32.IsWindow.restype wintypes.BOOL user32.GetWindowTextW.argtypes [wintypes.HWND, wintypes.LPWSTR, ctypes.c_int] user32.GetWindowThreadProcessId.argtypes [ wintypes.HWND, ctypes.POINTER(wintypes.DWORD) ] kernel32.OpenProcess.argtypes [wintypes.DWORD, wintypes.BOOL, wintypes.DWORD] kernel32.OpenProcess.restype wintypes.HANDLE kernel32.WaitForSingleObject.argtypes [wintypes.HANDLE, wintypes.DWORD] kernel32.WaitForSingleObject.restype wintypes.DWORD def window_alive(hwnd, expect_title): # 第一步句柄本身是否还指向有效窗口 if not user32.IsWindow(hwnd): return False # 第二步重读标题防止句柄被系统复用后指向别的窗口 buf ctypes.create_unicode_buffer(256) user32.GetWindowTextW(hwnd, buf, 256) if buf.value ! expect_title: return False # 第三步确认所属进程还活着OpenProcess WaitForSingleObject(0) pid wintypes.DWORD() user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid)) if pid.value 0: return False handle kernel32.OpenProcess(SYNCHRONIZE, False, pid.value) if not handle: return False wait_result kernel32.WaitForSingleObject(handle, 0) kernel32.CloseHandle(handle) # WAIT_TIMEOUT 表示进程未退出仍然存活 return wait_result WAIT_TIMEOUT import time hwnd user32.FindWindowW(None, 目标程序) for i in range(5): print(i, window_alive(hwnd, 目标程序)) time.sleep(1)这个函数把三件事串成了一条链路IsWindow 只回答“句柄这个数字还有没有效”不回答“是不是原来那个窗口”所以第二步必须重读标题做比对第三步用 OpenProcess 打开进程句柄WaitForSingleObject 的超时时间传 0意思是“进程退出时信号会立刻触发不阻塞”返回 WAIT_TIMEOUT 就代表进程仍在运行。三层下来误判的概率被压缩到极小。从那以后我每次写窗口检测脚本都强制走一遍这个三步校验先 IsWindow 验句柄再重读标题验身份最后验 PID 存活。第 2 章说句柄可能是“骗你的”这章就是那个后悔药的最终形态。整套带注释的脚本连同监控 Demo 都在分享的资源包里直接改改窗口标题和目标 PID 就能用希望帮到你。本文还有配套的精品资源点击获取

相关新闻

计算机网络综合实验方案:VLAN、OSPF、NAT与抓包分析全链路

计算机网络综合实验方案:VLAN、OSPF、NAT与抓包分析全链路

简介:这份华北电力大学计算机网络综合实验报告配套资料,面向计算机、网络工程等专业学生及需要完成课程设计的学习者,聚焦网络设备配置与协议分析两大实践方向。资源包内含1个doc文档,约21.91MB,完整呈现实验任务书、设…

2026/10/18 20:44:14 阅读更多 →
用Unity打造透明桌面挂件:Win32窗口与点击穿透详解

用Unity打造透明桌面挂件:Win32窗口与点击穿透详解

做桌面挂件、桌面时钟、动态壁纸这类需求时,很多人第一反应是用WPF、Electron或者Qt去写,但真到要精细控制3D渲染、粒子特效、骨骼动画的时候,这些方案一个比一个难受。绕一圈之后你会发现,用Unity来做“透明软件背景、显示桌面内…

2026/10/18 20:44:14 阅读更多 →
UE5蓝图截图实战:从HighResShot到RenderTarget完整指南

UE5蓝图截图实战:从HighResShot到RenderTarget完整指南

不是跟AI对话,下面直接放正文。这篇文章我按自己这些年做UE项目的习惯来写,聊的全是蓝图里和截屏死磕的实战经验,希望对为截图功能纠结过的同学有点用。1. 截图功能的应用场景与方案选型先说一句大实话:截图这件事,在U…

2026/10/18 20:44:14 阅读更多 →

最新新闻

OpenHarmony奖品详情页开发:从数据模型到状态管理全解析

OpenHarmony奖品详情页开发:从数据模型到状态管理全解析

我先把前面五篇的进度简单对一下,免得有读者是从这一篇才跟上来的:目前这个幸运大转盘项目已经完成了转盘主界面、抽奖动画、奖品管理、中奖记录和中奖弹窗这几个核心模块。这一篇要补上的奖品详情,其实是把"用户点开某个奖品图标之后看…

2026/10/18 21:47:12 阅读更多 →
React Native键盘避让在OpenHarmony上的适配实践

React Native键盘避让在OpenHarmony上的适配实践

1. 为什么键盘避让在 OpenHarmony 上会成为问题?做跨端开发的人最头疼的一类问题,莫过于软键盘弹起来之后,输入框被死死挡住。在 React Native 项目里,大家的第一反应就是用官方提供的 KeyboardAvoidingView 组件;可一…

2026/10/18 21:47:12 阅读更多 →
量化投研遇上大模型:研究记忆的风险边界与工程实践

量化投研遇上大模型:研究记忆的风险边界与工程实践

1. 当量化投研遇上大模型:一个正在被重新定义的边界做量化投研的人这两年应该都有一个共同的感受:数据获取的门槛在肉眼可见地降低,但真正拉开差距的东西,反而越来越模糊了。以前我们拼的是谁的因子库更全、谁的行情清洗更干净、谁…

2026/10/18 21:47:12 阅读更多 →
PL/SQL Developer导出表全攻略:从选项拆解到踩坑排查

PL/SQL Developer导出表全攻略:从选项拆解到踩坑排查

很多PL/SQL Developer用户都会卡在“导出表”这一步。明明菜单里有个Export Tables,可真点进去又不知道该勾哪些选项,导出来的SQL文件拿去别的库一执行就报错,或者数据缺了一半。这问题特别常见,尤其在Oracle DBA和开发人员之间来…

2026/10/18 21:47:12 阅读更多 →
降低AIGC率有哪些方法?AIGC检测里摘要、综述AI率高分别怎么改!

降低AIGC率有哪些方法?AIGC检测里摘要、综述AI率高分别怎么改!

降低AIGC率有哪些方法?AIGC检测里摘要、综述AI率高分别怎么改! 拿到知网AIGC检测报告,你可能会看到这样的情况:全文AI率不算夸张,可摘要那一页的AIGC疑似度超过50%,第二章文献综述连着三四页大段标红&…

2026/10/18 21:47:12 阅读更多 →
Select模型详解:Windows Socket TCP服务端实现与优化

Select模型详解:Windows Socket TCP服务端实现与优化

聊到Windows下的网络编程,“五种I/O模型”绝对是一个绕不开的话题。很多人在面试或者做项目的时候第一次接触这个概念,当场就被Select、WSAAsyncSelect、WSAEventSelect、重叠I/O、完成端口这一串名词搞懵了。说实话,这五个模型确实容易让人望…

2026/10/18 21:46:11 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →