VC2008中用CTabSheet实现专业级Tab页容器
简介本资源是面向VC初学者与MFC开发者的实用窗口界面示例聚焦于在Visual Studio 2008环境下基于CTabSheet类实现多标签页Tab对话框的完整工程实践。它解决了传统单窗口界面信息承载有限、交互效率低的问题适用于需要构建配置面板、设置向导或多页面管理工具的桌面应用开发场景。压缩包共23个文件含8个头文件.h定义类结构与消息映射、6个源文件.cpp实现CTabSheet派生类及属性页逻辑、1个可执行程序.exe开箱即用演示效果以及sln/vcproj/suo等VS工程配置文件和ico/rc等资源文件整体仅200KB轻量易学。已有307人学习下载提供从CPropertySheet初始化、CTabSheet子类重写、DoDataExchange数据绑定到多页AddPage集成的全链路代码实现目录结构清晰含ReadMe说明与标准MFC资源组织规范便于快速理解Tab控件封装原理并复用于自有项目。1. VC2008里用CTabSheet做Tab页不是MFC自带控件但能绕过CPropertySheet的硬限制你刚在VC2008里拖了个CPropertySheet进去想加个带图标、可拖拽、支持关闭按钮的Tab页——结果发现它连“关闭X”都得自己重绘更别说响应鼠标中键关闭、双击标题栏最大化子窗口这种需求。这时候翻MFC文档会发现CPropertySheet本质是向导式对话框的变体设计初衷就不是做主界面Tab容器。而CTabSheet这个类恰恰是某开发者在2005年前后为解决这一痛点写的轻量级替代方案它不依赖CPropertyPage生命周期管理所有子窗口用CreateWindowEx直接创建Tab条用自绘实现消息路由走WM_NOTIFY而非ON_COMMAND从而把“Tab页切换”和“子窗口生存期”彻底解耦。它适合需要高频切换、动态增删Tab、子窗口含复杂控件如ActiveX、OpenGL视图的桌面应用。如果你正在维护一个VC2008老项目又不想升级到VS2015改用CMFCTabCtrl这份CTabSheet源码包就是血泪经验沉淀下来的“后悔药”——它没用任何非标API纯Win32MFC封装编译即用但必须亲手补全三处资源ID绑定逻辑否则运行时必崩。2. CTabSheet核心机制解析为什么它比CPropertySheet更适合主窗口Tab化2.1 Tab页容器的本质矛盾CPropertySheet的设计枷锁CPropertySheet强制要求每个Tab页继承自CPropertyPage而CPropertyPage的OnSetActive()和OnKillActive()被设计成“向导步骤控制钩子”其内部会调用UpdateData()并触发DDX/DDV校验。当你把一个含编辑框、列表框、树控件的完整功能页塞进去时每次切换Tab都会触发一次无意义的数据校验且CPropertyPage的窗口句柄m_hWnd在非激活状态下会被MFC框架自动销毁重建——这直接导致你在Tab页里启动的定时器、注册的热键、挂载的COM对象全部失效。CTabSheet绕开了这个死结它把每个Tab页视为独立CWnd派生类比如CMyView通过SetParent()将其m_hWnd挂到CTabSheet的客户区切换时仅调用ShowWindow(SW_SHOW/SW_HIDE)子窗口句柄全程存活。这种设计让CTabSheet天然支持“后台Tab持续运行”场景比如监控软件里某个Tab页跑着实时串口数据接收线程切走再切回数据流完全不中断。2.2 源码结构与关键类职责拆解下载包解压后你会看到4个核心文件CTabSheet.h/cpp主容器类负责Tab条绘制、鼠标事件分发、子窗口布局管理CTabCtrlEx.h/cpp增强型Tab控件支持图标、右键菜单、拖拽排序注意此非系统TCM_*消息而是自绘鼠标捕获实现CTabSheetPage.h抽象基类定义InitPage()、OnTabActivated()等钩子所有业务页必须继承它Resource.h必须手动补全的资源ID映射表这是后续踩坑的根源之一。提示CTabSheet不使用资源脚本(.rc)里的Dialog模板所有子窗口均代码创建。这意味着你不能用ClassWizard生成页面类必须手写CMyPage : public CTabSheetPage并在OnInitDialog()里调用GetTabControl()-InsertItem()注册自身。2.3 消息路由机制如何让Tab页响应WM_COMMAND而不炸掉CPropertySheet用ON_COMMAND_RANGE将所有子页的控件ID映射到父窗口而CTabSheet采用“两级委托”主窗口CMainFrame重载PreTranslateMessage()捕获WM_COMMAND后检查当前激活Tab页的m_hWnd是否有效若有效则调用该页的OnCommand()虚函数由业务页自行处理ID控件消息。这种设计避免了CPropertySheet里常见的“控件ID冲突”问题——比如两个Tab页都有IDC_EDIT1CPropertySheet会把消息发给第一个匹配的页而CTabSheet确保消息只送达当前激活页。实际编码时你在CMyPage::OnCommand()里写BOOL CMyPage::OnCommand(WPARAM wParam, LPARAM lParam) { UINT nID LOWORD(wParam); if (nID IDC_BTN_REFRESH) { // 只有当前Tab页的刷新按钮被点击才执行 RefreshData(); return TRUE; } return CTabSheetPage::OnCommand(wParam, lParam); // 继续向上委托 }关键点在于RefreshData()这类业务函数必须声明为public因为主框架可能通过指针调用如菜单命令触发后台Tab刷新。3. 工程集成实操从零配置VC2008项目接入CTabSheet3.1 头文件与库依赖注入在你的主框架类如CMainFrame头文件顶部添加// CMainFrame.h #include CTabSheet.h #include CTabSheetPage.h // 注意顺序必须先包含CTabSheetPage否则CTabSheet.h里对基类的前向声明会失败在CMainFrame.cpp的构造函数中初始化成员变量// CMainFrame.cpp CMainFrame::CMainFrame() { m_pTabSheet NULL; // CTabSheet* 成员变量 m_hIcon AfxGetApp()-LoadIcon(IDR_MAINFRAME); }参数说明m_hIcon用于Tab页图标显示若不需要图标可设为NULLCTabSheet默认使用系统字体绘制Tab文字无需额外设置LOGFONT。3.2 创建CTabSheet实例并嵌入主窗口客户区在CMainFrame::OnCreate()中插入以下代码务必放在CreateControlBar()之后、m_wndStatusBar.Create()之前int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) -1) return -1; // 创建CTabSheet控件 m_pTabSheet new CTabSheet(); if (!m_pTabSheet-Create(WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, CRect(0, 0, 1, 1), this, IDC_TABSHEET)) { delete m_pTabSheet; m_pTabSheet NULL; return -1; } // 设置Tab条高度像素默认30建议26-32之间 m_pTabSheet-SetTabHeight(28); // 启用Tab页右键菜单需自行实现OnTabContextMenu() m_pTabSheet-EnableTabContextMenu(TRUE); return 0; }关键参数解析IDC_TABSHEET必须在Resource.h中定义为大于0的整数如#define IDC_TABSHEET 1001这是CTabSheet窗口的控件ID用于后续消息路由WS_CLIPSIBLINGS强制裁剪兄弟窗口重叠区域避免Tab页内容溢出到Tab条上CRect(0,0,1,1)初始尺寸设为1x1后续由OnSize()调整这是MFC窗口创建惯例。3.3 动态添加Tab页的完整流程以添加一个名为“设备监控”的Tab页为例假设已建好CDeviceMonitorPage类// 在CMainFrame::OnCreate()末尾或OnInitialUpdate()中调用 void CMainFrame::AddDeviceMonitorTab() { CDeviceMonitorPage* pPage new CDeviceMonitorPage(); pPage-Create(IDD_DEVICE_MONITOR, m_pTabSheet); // IDD_DEVICE_MONITOR为对话框资源ID // 关键设置Tab页标题和图标 pPage-SetTabText(_T(设备监控)); pPage-SetTabIcon(m_hIcon); // 使用主窗口图标也可LoadIcon单独加载 // 插入到CTabSheet索引0表示第一个Tab m_pTabSheet-AddPage(pPage, 0); // 强制重绘Tab条 m_pTabSheet-Invalidate(); }注意Create()的第二个参数必须传m_pTabSheet而非this否则子窗口父句柄错误会导致OnSize()计算错位。AddPage()内部会调用pPage-ShowWindow(SW_SHOW)无需手动调用。3.4 响应Tab页切换事件的正确姿势CTabSheet不发送BN_CLICKED这类标准通知而是通过虚函数回调。在CMainFrame中重载// CMainFrame.h 声明 protected: afx_msg void OnTabActivated(int nTabIndex); DECLARE_MESSAGE_MAP() // CMainFrame.cpp 实现 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_NOTIFY(TCN_SELCHANGE, IDC_TABSHEET, CMainFrame::OnTabActivated) END_MESSAGE_MAP() void CMainFrame::OnTabActivated(int nTabIndex) { // 获取当前激活页指针 CTabSheetPage* pActivePage m_pTabSheet-GetPage(nTabIndex); if (pActivePage) { // 通知业务页已激活可在此触发数据刷新 pActivePage-OnTabActivated(); // 示例根据Tab页类型设置状态栏文本 CString strStatus; if (dynamic_castCDeviceMonitorPage*(pActivePage)) strStatus _T(设备监控就绪); else if (dynamic_castCLogViewerPage*(pActivePage)) strStatus _T(日志查看中); m_wndStatusBar.SetPaneText(0, strStatus); } }这里TCN_SELCHANGE是CTabSheet自定义的通知码非系统TCN_*定义在CTabSheet.h中#define TCN_SELCHANGE (TCN_FIRST - 10)。必须用ON_NOTIFY宏绑定不能用ON_COMMAND。4. 避坑指南CTabSheet在VC2008中必踩的五个边界问题4.1 现象程序启动后Tab页空白调试发现子窗口m_hWnd为NULL原因CDeviceMonitorPage::Create()调用时传入的父窗口句柄错误。常见误写为pPage-Create(IDD_DEVICE_MONITOR, this)导致子窗口父句柄指向CMainFrame而CTabSheet的客户区坐标系与主窗口不一致OnSize()无法正确缩放。解决严格按3.3节代码第二个参数必须是m_pTabSheet并在CDeviceMonitorPage::OnCreate()中添加断言int CDeviceMonitorPage::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) -1) return -1; ASSERT(::IsWindow(GetParent()-m_hWnd)); // 确保父窗口有效 return 0; }4.2 现象切换Tab页时原Tab页的编辑框内容丢失焦点消失原因CTabSheet默认不保存子窗口焦点状态。当Tab页被Hide时其内部控件失去输入焦点但MFC未记录哪个控件曾拥有焦点。解决在每个CTabSheetPage派生类中重载OnTabDeactivated()手动保存焦点控件void CDeviceMonitorPage::OnTabDeactivated() { // 保存当前获得焦点的控件ID CWnd* pFocus GetFocus(); if (pFocus ::IsChild(m_hWnd, pFocus-m_hWnd)) { m_nLastFocusID pFocus-GetDlgCtrlID(); } } void CDeviceMonitorPage::OnTabActivated() { // 恢复焦点 if (m_nLastFocusID) { GetDlgItem(m_nLastFocusID)-SetFocus(); } }注意m_nLastFocusID需在头文件中声明为int m_nLastFocusID;并在构造函数中初始化为0。4.3 现象右键Tab页弹出菜单后点击菜单项无响应原因CTabSheet的右键菜单消息WM_COMMAND未路由到主框架。CTabSheet本身不处理菜单命令需在CMainFrame中捕获。解决在CMainFrame::OnCommand()中增加转发逻辑BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) { // 先尝试由CTabSheet处理如Tab页关闭命令 if (m_pTabSheet m_pTabSheet-OnCommand(wParam, lParam)) return TRUE; // 再交由基类处理 return CFrameWnd::OnCommand(wParam, lParam); }同时在CTabSheet.cpp的OnCommand()中对ID_TAB_CLOSE等命令返回TRUE表示已处理。4.4 现象高DPI显示器下Tab文字模糊图标错位原因CTabSheet使用GDI绘制Tab条未启用DPI感知。VC2008默认编译的程序DPI缩放模式为“系统 DPI”而CTabSheet的字体大小、图标坐标均按96DPI硬编码。解决在CMainFrame::OnCreate()中添加DPI适配// 获取系统DPI缩放比例 HDC hDC ::GetDC(NULL); int dpiX ::GetDeviceCaps(hDC, LOGPIXELSX); ::ReleaseDC(NULL, hDC); float scale dpiX / 96.0f; // 动态调整Tab高度和字体 m_pTabSheet-SetTabHeight((int)(28 * scale)); LOGFONT lf; ::GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), lf); lf.lfHeight -MulDiv(12, dpiX, 72); // 12pt字体 m_pTabSheet-SetFont(lf, TRUE);4.5 现象动态删除Tab页后再次AddPage崩溃在CTabCtrlEx::DrawItem()原因CTabCtrlEx内部维护了一个Tab项数组删除操作未清理对应索引的缓存指针导致DrawItem()访问已释放内存。解决在CTabSheet::RemovePage()后强制重置CTabCtrlEx状态// 修改CTabSheet.cpp中的RemovePage() void CTabSheet::RemovePage(int nIndex) { // ... 原有删除逻辑 if (m_pTabCtrl) { // 清空CTabCtrlEx内部缓存 m_pTabCtrl-Invalidate(); m_pTabCtrl-UpdateWindow(); } }更彻底的方案是在CTabCtrlEx.h中为m_items数组添加RemoveAt()安全调用但需修改源码此处给出兼容性更强的UI刷新方案。5. 进阶技巧实现Tab页拖拽排序与双击关闭附完整参数对照表5.1 启用Tab页拖拽排序的三步改造CTabSheet默认禁用拖拽需手动开启并处理消息。首先在CMainFrame::OnCreate()中m_pTabSheet-EnableTabDrag(TRUE); // 启用拖拽 m_pTabSheet-SetDragThreshold(10); // 像素阈值超过此距离才触发拖拽然后在CTabSheet.cpp中找到OnLButtonDown()修改拖拽触发条件void CTabSheet::OnLButtonDown(UINT nFlags, CPoint point) { // 原逻辑仅在Tab条内点击才处理 CRect rectTab; m_pTabCtrl-GetWindowRect(rectTab); ScreenToClient(rectTab); if (rectTab.PtInRect(point)) { // 新增判断是否在Tab项上点击 int nHitTab m_pTabCtrl-HitTest(point); if (nHitTab ! -1) { m_bDragging TRUE; m_nDragStartTab nHitTab; SetCapture(); } } CWnd::OnLButtonDown(nFlags, point); }最后实现拖拽结束逻辑在OnMouseMove()和OnLButtonUp()中void CTabSheet::OnLButtonUp(UINT nFlags, CPoint point) { if (m_bDragging) { ReleaseCapture(); m_bDragging FALSE; // 计算目标位置索引 int nTargetTab m_pTabCtrl-HitTest(point); if (nTargetTab ! -1 nTargetTab ! m_nDragStartTab) { // 执行Tab页交换需修改m_pages数组和CTabCtrlEx的项顺序 SwapPages(m_nDragStartTab, nTargetTab); } } CWnd::OnLButtonUp(nFlags, point); }关键点SwapPages()需同步更新m_pagesCTabSheetPage*数组和m_pTabCtrl-m_itemsCTabItem数组否则视觉与数据错位。5.2 双击Tab页标题关闭功能实现在CTabSheet.cpp中重载OnLButtonDblClk()void CTabSheet::OnLButtonDblClk(UINT nFlags, CPoint point) { int nTab m_pTabCtrl-HitTest(point); if (nTab ! -1) { // 发送自定义关闭消息 GetParent()-PostMessage(WM_COMMAND, MAKEWPARAM(ID_TAB_CLOSE, 0), (LPARAM)m_pTabCtrl-m_hWnd); } CWnd::OnLButtonDblClk(nFlags, point); }在CMainFrame::OnCommand()中捕获并处理BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) { if (HIWORD(wParam) ID_TAB_CLOSE) { int nSel m_pTabSheet-GetActiveIndex(); if (nSel 0) { CTabSheetPage* pPage m_pTabSheet-GetPage(nSel); if (pPage AfxMessageBox(_T(确定关闭当前Tab页), MB_YESNO) IDYES) { m_pTabSheet-RemovePage(nSel); delete pPage; } } return TRUE; } // ... 其他逻辑 }5.3 CTabSheet核心参数与行为对照表参数/方法名默认值可设范围影响范围调试建议SetTabHeight(int nHeight)3020~60Tab条整体高度影响文字垂直居中若文字被截断优先调小此值而非改字体EnableTabContextMenu(BOOL bEnable)FALSETRUE/FALSE是否响应右键弹出菜单必须配合CMainFrame::OnTabContextMenu()实现SetDragThreshold(int nPixels)51~50触发拖拽的鼠标移动距离阈值设为0则点击即拖拽易误操作SetTabIcon(HICON hIcon)NULL有效图标句柄Tab页左侧图标图标尺寸建议16x16过大导致文字挤压EnableTabCloseButton(BOOL bEnable)FALSETRUE/FALSE是否显示Tab页右侧关闭X按钮需重绘CTabCtrlEx的DrawItem()添加关闭按钮区域从那以后我每次集成CTabSheet都会在CMainFrame::OnCreate()末尾加一段强制校验// 校验Tab页数量与CTabCtrlEx项数是否一致 ASSERT(m_pTabSheet-GetPageCount() m_pTabSheet-GetTabControl()-GetItemCount());只要这条断言不崩基本能避开80%的Tab页显示异常。遇到崩溃先看它比翻堆栈快得多。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

基于 .NET 与 Aspire 构建 Streamable HTTP 远程 MCP 服务器:从本地 stdio 到 Azure 云端部署

基于 .NET 与 Aspire 构建 Streamable HTTP 远程 MCP 服务器:从本地 stdio 到 Azure 云端部署

教程文档人工智能 【免费下载链接】mcp-for-beginners This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for deve…

2026/10/13 2:00:33 阅读更多 →
大模型应用落地指南:从RAG到Agent的企业AI转型实战

大模型应用落地指南:从RAG到Agent的企业AI转型实战

简介:面向企业管理者、技术负责人及人工智能从业者的《火山引擎大模型应用落地白皮书》,系统梳理大模型从探索走向业务深度融合的现状,剖析企业在落地中普遍面临的高成本、选型困难、部署复杂与安全风险等挑战,并提出分阶段构建业…

2026/10/13 2:00:37 阅读更多 →
微博评论爬虫实战:登录协议解析与热评增量抓取

微博评论爬虫实战:登录协议解析与热评增量抓取

简介:本资源是一份面向Python初学者与爬虫入门者的实战教程,手把手讲解如何抓取微博平台的评论数据,解决社交媒体舆情分析、粉丝行为研究等实际场景中的数据采集需求。内容涵盖登录模拟(含RSA加密、预登陆参数获取、验证码处理&am…

2026/10/13 2:00:41 阅读更多 →

最新新闻

Java实现GB28181 RTP PS流解包与RTMP推流实战

Java实现GB28181 RTP PS流解包与RTMP推流实战

1. 项目背景与整体设计思路1.1 为什么要在Java里做RTP PS流解包推RTMP做过安防流媒体对接的朋友应该都有体会,GB28181协议在国内安防行业几乎是绕不开的存在。摄像头、NVR、平台之间信令走SIP,媒体流走RTP承载PS封装,这套组合拳已经跑了很多年…

2026/10/13 7:00:55 阅读更多 →
宁波执业律师张娟:离婚后孩子判给谁——抚养权判断规则与争取要点梳理

宁波执业律师张娟:离婚后孩子判给谁——抚养权判断规则与争取要点梳理

结论先行:抚养权不归收入高的一方,也不默认归母亲,而是按年龄分档、以孩子利益为轴心综合判断。民法典第1084条确立了不满两周岁以母亲直接抚养为原则、已满八周岁尊重孩子真实意愿、两至八周岁按有利于未成年子女原则裁判的基本框架。本文由…

2026/10/13 7:00:55 阅读更多 →
共享汽车调度落地实践:LSTM需求预测+GA-SA多目标优化

共享汽车调度落地实践:LSTM需求预测+GA-SA多目标优化

简介:本资源是一篇聚焦单向共享电动汽车(OW-EC)运营优化的学术论文,面向新能源汽车领域研究者、智能交通系统开发者及高校交通运输/车辆工程专业师生,旨在解决因用户需求潮汐性与不均衡性导致的站点车辆库存失衡这一行…

2026/10/13 7:00:55 阅读更多 →
Agent沙箱全解析:从隔离原理到容器、进程级与代码级落地实践

Agent沙箱全解析:从隔离原理到容器、进程级与代码级落地实践

做Agent开发的朋友聚在一起聊天时,“沙箱”这个词出现的频率高得吓人。无论你是搭一个能自动写代码的助手,还是让模型按流程调用外部工具的系统,文档里几乎必有一章在讲“沙箱”。我最早接触它时,以为就是一个“把环境隔离开”的省…

2026/10/13 7:00:55 阅读更多 →
Kafka分布式日志原理与实时链路工程实践

Kafka分布式日志原理与实时链路工程实践

1. 为什么“Kafka从入门到精通”不是一句空话,而是工程落地的必经阶梯很多人第一次听说Kafka,是在面试被问到“消息队列选型”时,听到“高吞吐、低延迟、可持久化”这几个词;也有人是在排查线上数据延迟告警时,发现日志…

2026/10/13 7:00:55 阅读更多 →
学习 Python 基础语法与工程环境操作流程

学习 Python 基础语法与工程环境操作流程

前言一、基础概念虚拟环境:可以理解成每个项目专属的「Python 独立工具箱」。每个项目单独一套 Python 解释器和第三方安装包,项目之间互不干扰,不会出现 A 项目装的包覆盖 B 项目依赖的情况,删掉环境文件夹就能一键重置&#xff…

2026/10/13 6:59:55 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/12 21:05:09 阅读更多 →
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/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →