MFC CSplitterWnd实现三窗格界面:原理、架构与实战技巧
1. 项目概述为什么需要三窗格界面在开发桌面应用程序尤其是像代码编辑器、数据管理工具或资源管理器这类复杂工具时单一视图往往捉襟见肘。想象一下你正在开发一个类似Visual Studio的IDE左边是项目文件树中间是代码编辑区右边是属性面板或调试信息窗口。如果这三个区域都挤在一个窗口里用户要么需要频繁切换标签页要么就得忍受混乱的布局。这时一个稳定、可自由调整、逻辑清晰的多窗格界面就成了提升用户体验和生产力的关键。VC这里特指基于MFC框架的C开发作为Windows桌面开发的经典技术栈其内置的CSplitterWnd类是实现这类拆分窗口的利器。但官方文档往往只告诉你“是什么”和“怎么用”对于如何构建一个左、中、右三个固定窗格的复杂布局以及其中可能遇到的坑却鲜有详述。今天我就结合自己十多年的客户端开发经验来拆解如何用CSplitterWnd稳健地实现一个三窗格界面并分享那些只有踩过坑才知道的实战技巧。2. 核心思路与CSplitterWnd深度解析在动手之前我们必须吃透CSplitterWnd的核心机制。它本质上是一个窗口容器负责管理其内部子窗口即窗格的布局和大小调整。根据微软的TN029技术文档它支持两种模式静态拆分和动态拆分。我们的三窗格布局通常属于静态拆分。2.1 静态拆分 vs. 动态拆分静态拆分在创建拆分器窗口时就一次性创建好所有窗格。窗格的数量和顺序是固定的用户只能拖动分割条来调整各窗格的大小但不能动态创建或删除窗格。Visual Studio的资源编辑器、Windows文件管理器的左右分栏就是典型例子。这种模式适合布局固定的多视图应用。动态拆分初始只有一个窗格用户通过菜单或分割框主动拆分可以动态创建新的窗格视图。像老版本的Excel或Word允许你将同一个文档拆分成多个视图进行对照。这种模式更灵活但逻辑也更复杂。对于“左中右三窗格”这种明确需求静态拆分是我们的不二之选。它的行为可预测性能开销小实现起来也更直接。2.2 理解窗格、行、列与拆分条CSplitterWnd使用一个行和列的网格模型来管理窗格。创建一个2行1列的拆分器你会得到上下两个窗格创建1行2列则是左右两个窗格。那么左中右三个窗格是1行3列吗理论上是的但这里有一个关键点一个CSplitterWnd实例只能管理一个方向行或列的拆分。这意味着如果你直接创建一个1行3列的CSplitterWnd你只能得到两条垂直分割条管理三个垂直排列的窗格。这虽然也是“左中右”但如果你还希望某个窗格比如中间的编辑区内部能再进行水平拆分例如上方代码区下方输出窗口单个CSplitterWnd就无能为力了。因此实现复杂嵌套布局的黄金法则是嵌套使用多个CSplitterWnd对象。这也是实现我们目标架构的核心。3. 架构设计与实现步骤我们的目标是主窗口客户区被分为左、中、右三个主要区域。其中中间区域可能还需要进一步拆分为上下两个部分例如代码编辑区和输出控制台。下面我们来一步步构建。3.1 第一步规划整体布局我们采用两级嵌套拆分器一级拆分器水平负责将主窗口客户区划分为左和右两个大区域。我们称它为m_wndHSplitter。二级拆分器嵌套在右侧将第一步得到的右侧区域再次垂直拆分为中和右两个区域。我们称它为m_wndVSplitter。三级拆分器可选嵌套在中间如果需要将中间区域再水平拆分如上文所述则在m_wndVSplitter的左侧窗格内再创建一个水平拆分器。这样通过两个拆分器的嵌套我们就得到了左、中、右三个窗格。如果需要中间窗格还能继续复杂化。3.2 第二步在框架窗口中创建拆分器通常我们在主框架窗口类CMainFrame派生自CFrameWnd或CMDIFrameWnd的OnCreateClient成员函数中创建拆分器。这是MFC框架推荐的初始化位置。BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { // 1. 创建一级水平拆分器1行2列 if (!m_wndHSplitter.CreateStatic(this, 1, 2)) // 将主窗口拆分为1行2列 { TRACE0(Failed to create horizontal splitter\n); return FALSE; } // 2. 在一级拆分器的第0列左侧创建视图窗格 // 假设CLeftView是你的左侧树形视图或文件列表视图类 if (!m_wndHSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(200, 100), pContext)) { TRACE0(Failed to create left pane view\n); return FALSE; } // 3. 在一级拆分器的第1列右侧创建二级垂直拆分器 // 注意这里创建的不是视图而是另一个CSplitterWnd对象 if (!m_wndVSplitter.CreateStatic(m_wndHSplitter, // 父窗口是水平拆分器 2, 1, // 将右侧区域拆分为2行1列上下结构 WS_CHILD | WS_VISIBLE | WS_BORDER, // 样式通常需要WS_BORDER来看到分割条 m_wndHSplitter.IdFromRowCol(0, 1))) // 关键获取右侧窗格的ID { TRACE0(Failed to create nested vertical splitter\n); return FALSE; } // 4. 在二级拆分器的第0行第0列上侧即“中间”主区域创建视图 // 假设CCenterView是你的主编辑区视图类 if (!m_wndVSplitter.CreateView(0, 0, RUNTIME_CLASS(CCenterView), CSize(0, 0), pContext)) { TRACE0(Failed to create center pane view\n); return FALSE; } // 5. 在二级拆分器的第1行第0列下侧即“右边”区域创建视图 // 假设CRightView是你的属性面板或输出窗口视图类 if (!m_wndVSplitter.CreateView(1, 0, RUNTIME_CLASS(CRightView), CSize(0, 0), pContext)) { TRACE0(Failed to create right pane view\n); return FALSE; } // 设置初始窗格大小可选在下一步详细说明 m_wndHSplitter.SetColumnInfo(0, 200, 100); // 左侧窗格初始宽度200最小宽度100 m_wndHSplitter.SetColumnInfo(1, 600, 300); // 右侧区域初始宽度600最小宽度300 m_wndVSplitter.SetRowInfo(0, 400, 200); // 中间窗格初始高度400最小高度200 m_wndVSplitter.SetRowInfo(1, 200, 100); // 底部窗格初始高度200最小高度100 m_wndHSplitter.RecalcLayout(); m_wndVSplitter.RecalcLayout(); return TRUE; // 返回TRUE表示我们已自行创建客户区框架不必再处理 }关键点解析CreateStatic参数第一个参数是父窗口指针。嵌套时子拆分器的父窗口必须是容纳它的那个拆分器窗格通过IdFromRowCol获取的ID对应的窗口。IdFromRowCol这是嵌套拆分器的灵魂。它获取指定行、列位置的窗格的子窗口ID。将这个ID作为子拆分器创建时的nID参数MFC的消息路由和焦点管理才能正确工作。CreateView用于在拆分器中创建视图窗格。pContext参数包含了文档模板信息对于文档/视图架构至关重要。窗格不一定非得是CView虽然例子中用了CView派生类但CreateView内部通过pContext-m_pNewViewClass创建。如果你想放入一个普通的CWnd派生控件如CListCtrl需要更复杂的处理通常重写CreateView或使用Create方法。一个更简单的替代方案是创建一个空的CView派生类在其OnCreate中创建你需要的控件作为子窗口。3.3 第三步精细控制窗格尺寸与行为创建好只是第一步让界面好用还得精细调校。3.3.1 设置初始和最小尺寸使用SetRowInfo和SetColumnInfo来控制行高/列宽。函数原型void SetRowInfo(int row, int cyIdeal, int cyMin);row: 行索引。cyIdeal: 理想高度像素。系统会尽量满足但受限于总空间。cyMin: 最小高度。用户无法将分割条拖拽到使该行高度小于此值。调用时机在OnCreateClient中创建所有窗格后调用RecalcLayout()之前设置。// 设置水平拆分器的列信息 m_wndHSplitter.SetColumnInfo(0, 250, 150); // 左栏理想250px最小150px m_wndHSplitter.SetColumnInfo(1, -1, 300); // 右栏理想值-1表示剩余空间最小300px // 设置垂直拆分器的行信息 m_wndVSplitter.SetRowInfo(0, -1, 200); // 上栏中间主区域占满剩余空间最小200px m_wndVSplitter.SetRowInfo(1, 150, 80); // 下栏右下方区域理想150px最小80px // 必须调用使设置生效 m_wndHSplitter.RecalcLayout(); m_wndVSplitter.RecalcLayout();实操心得 将某一栏的理想尺寸设为-1是一个常用技巧表示“占据所有剩余空间”。这能确保当主窗口大小变化时核心工作区如中间的编辑区能自动填充而侧边栏保持相对固定或按比例调整。3.3.2 保存与恢复布局状态一个专业的应用应该记住用户调整后的窗格大小。这可以通过在框架窗口中序列化拆分器状态来实现。// 在CMainFrame类中添加成员变量保存比例或直接保存像素值 int m_nLeftPaneWidth; int m_nBottomPaneHeight; // 在窗口销毁时如OnDestroy或OnClose保存 void CMainFrame::OnDestroy() { CRect rect; m_wndHSplitter.GetColumnInfo(0, m_nLeftPaneWidth, m_nLeftPaneMin); m_wndVSplitter.GetRowInfo(1, m_nBottomPaneHeight, m_nBottomPaneMin); // 将m_nLeftPaneWidth, m_nBottomPaneHeight保存到注册表或配置文件 CFrameWnd::OnDestroy(); } // 在窗口创建后OnCreateClient末尾或首次显示时OnShowWindow恢复 BOOL CMainFrame::OnCreateClient(...) { // ... 创建拆分器和视图的代码 ... // 从配置读取保存的值 m_nLeftPaneWidth LoadFromConfig(LeftPaneWidth, 250); m_nBottomPaneHeight LoadFromConfig(BottomPaneHeight, 150); // 应用保存的尺寸 m_wndHSplitter.SetColumnInfo(0, m_nLeftPaneWidth, 100); // 计算右侧初始宽度总宽度-左侧宽度-分割条宽度这里简化处理 m_wndHSplitter.SetColumnInfo(1, -1, 300); m_wndVSplitter.SetRowInfo(1, m_nBottomPaneHeight, 80); m_wndVSplitter.SetRowInfo(0, -1, 200); // 中间区域占据剩余空间 m_wndHSplitter.RecalcLayout(); m_wndVSplitter.RecalcLayout(); return TRUE; }4. 高级技巧与避坑指南掌握了基础创建和尺寸控制下面这些经验能让你避开90%的坑并实现更高级的功能。4.1 处理窗格内的滚动条同步当左右或上下的窗格内容需要联动滚动时例如左边是大纲右边是文档滚动文档时大纲高亮跟随CSplitterWnd支持共享滚动条。在创建拆分器时指定WS_HSCROLL或WS_VSCROLL样式即可。// 创建带垂直共享滚动条的水平拆分器 if (!m_wndHSplitter.CreateStatic(this, 1, 2, WS_CHILD | WS_VISIBLE | WS_VSCROLL)) { // ... error handling }重要限制共享滚动条机制是为CScrollView或自行处理WM_VSCROLL/WM_HSCROLL消息的CView派生类设计的。如果窗格内是普通控件如CEdit滚动条可能无法正确同步。此时你需要手动在窗格视图类中处理滚动消息并调用CSplitterWnd的SetScrollPos等函数来同步其他窗格。4.2 自定义分割条外观默认的分割条就是一个细线拖动时是一个虚线框。你可以通过重写CSplitterWnd的虚函数来定制它们。class CMySplitterWnd : public CSplitterWnd { public: virtual void OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect rect); virtual void OnInvertTracker(const CRect rect); }; void CMySplitterWnd::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect rect) { // nType 可以是 splitBox, splitBar, splitIntersection if (nType splitBar) { // 自定义分割条绘制例如画一个渐变色的条 CBrush br(RGB(220, 230, 240)); pDC-FillRect(rect, br); // 画两条细边线 pDC-Draw3dRect(rect, RGB(180, 190, 200), RGB(255, 255, 255)); } else { // 其他部分使用默认绘制 CSplitterWnd::OnDrawSplitter(pDC, nType, rect); } } void CMySplitterWnd::OnInvertTracker(const CRect rect) { // 自定义拖动时的跟踪矩形例如画一个实心半透明矩形 CWindowDC dc(this); CBrush br(HS_DIAGCROSS, RGB(0, 0, 255)); // 蓝色斜线画刷 dc.FrameRect(rect, br); }然后在CMainFrame中使用CMySplitterWnd类型声明m_wndHSplitter和m_wndVSplitter即可。4.3 动态显示/隐藏窗格有时我们需要临时隐藏某个窗格比如关闭右侧属性面板。CSplitterWnd没有直接的ShowPane函数但可以通过设置其最小尺寸为0并调整其他窗格尺寸来实现“隐藏”。void CMainFrame::ToggleRightPane(bool bShow) { int nCurSize, nMinSize; m_wndHSplitter.GetColumnInfo(1, nCurSize, nMinSize); if (bShow) { // 显示恢复之前保存的宽度或设置一个默认宽度 m_wndHSplitter.SetColumnInfo(1, m_nSavedRightPaneWidth, 100); } else { // 隐藏记录当前宽度然后将理想和最小宽度都设为0 m_nSavedRightPaneWidth nCurSize; m_wndHSplitter.SetColumnInfo(1, 0, 0); } m_wndHSplitter.RecalcLayout(); // 需要重画客户区 m_wndHSplitter.RedrawWindow(); }更彻底的方法是调用ShowWindow(SW_HIDE)隐藏整个窗格视图但这需要你同时处理拆分条的逻辑并重写CSplitterWnd的布局计算更为复杂。上述“最小尺寸设为0”的方法在大多数情况下是简单有效的。4.4 处理键盘导航与焦点在多窗格界面中用户期望能用Tab键或快捷键如F6在窗格间切换焦点。MFC为CView提供了ID_NEXT_PANE和ID_PREV_PANE这两个默认命令ID。你可以在框架窗口的加速键表或菜单中绑定它们例如将CtrlTab映射到ID_NEXT_PANE。CSplitterWnd与CView协作会自动处理这些命令将焦点在相邻窗格间循环移动。如果你的窗格不是CView或者需要自定义导航逻辑可以重写框架窗口的ActivateNext或相关函数。5. 常见问题与实战排查即使按照步骤来也难免会遇到问题。这里记录几个我踩过的典型深坑和解决方法。5.1 问题嵌套拆分器创建失败程序断言或崩溃可能原因1嵌套拆分器创建时CreateStatic的父窗口参数或ID参数错误。必须使用父拆分器窗格的ID通过IdFromRowCol获取。排查检查CreateStatic调用。确保第一个参数父窗口指向了正确的父拆分器对象指针第四个参数nID使用了父拆分器.IdFromRowCol(row, col)。可能原因2在OnCreateClient中创建顺序混乱。必须先创建父拆分器及其窗格才能获取其子窗格ID用于创建嵌套拆分器。排查严格按照“先外后内先创建后获取ID”的顺序编写代码。5.2 问题分割条拖动不流畅或窗格内容闪烁严重可能原因窗格视图的OnDraw或OnPaint函数绘制效率低下或者没有正确处理背景擦除。解决方案优化绘制在视图的OnDraw中只绘制必要区域避免全屏重绘。对于复杂视图考虑使用双缓冲。禁止背景擦除在视图类中重写OnEraseBkgnd函数并直接返回TRUE让OnDraw完全负责绘制可以避免拖动时的闪烁。BOOL CMyView::OnEraseBkgnd(CDC* pDC) { return TRUE; // 告诉系统背景已擦除 }设置窗口扩展样式在视图创建前尝试添加WS_EX_COMPOSITED扩展样式Windows XP及以上它可以使用双缓冲技术合成整个窗口有效减少闪烁但可能有轻微性能影响。5.3 问题窗格内的控件如编辑框无法正常接收焦点或鼠标消息可能原因拆分器窗口和窗格视图之间的消息路由或父子窗口关系出现问题。特别是如果你在窗格视图内手动创建了控件。解决方案确保控件是以窗格视图CYourPaneView为父窗口创建的而不是以主框架或拆分器为父窗口。在窗格视图的OnCreate函数中创建控件并确保传递正确的父窗口句柄this-m_hWnd。如果问题依旧检查是否在某个地方错误地禁用了控件或视图。可以在Spy等工具中查看窗口的父子关系和样式。5.4 问题程序退出时调试输出显示有内存泄漏CWnd对象可能原因MFC的CSplitterWnd在销毁时会自动销毁其管理的所有窗格视图。但如果你的窗格视图内动态创建了其他对象如CImageList,HBITMAP等并且没有在视图的析构函数中正确释放就会报告泄漏。解决方案仔细检查每个窗格视图类CLeftView,CCenterView等的析构函数确保释放了所有动态分配的资源。对于MFC对象使用DeleteObject()或Delete()对于GDI对象使用DeleteObject()对于纯指针使用delete。5.5 问题在高DPI显示器上分割条位置和窗格尺寸错乱可能原因代码中使用了硬编码的像素值来设置初始尺寸或最小尺寸没有考虑DPI缩放。解决方案对于现代Windows应用支持Per-Monitor DPI V2应该使用与DPI无关的单元。将像素值转换为DPI感知值使用MulDiv函数或者通过GetDeviceCaps获取逻辑DPI进行计算。int GetDPIScaledSize(int nBaseSize, CWnd* pWnd) { HDC hDC ::GetDC(pWnd-GetSafeHwnd()); int dpiX GetDeviceCaps(hDC, LOGPIXELSX); ::ReleaseDC(pWnd-GetSafeHwnd(), hDC); // 假设nBaseSize是在96DPI下的设计尺寸 return MulDiv(nBaseSize, dpiX, 96); }在OnCreateClient中调用用GetDPIScaledSize(200, this)代替硬编码的200。处理DPI变化如果支持运行时DPI更改还需要响应WM_DPICHANGED消息并在此消息处理中重新计算和设置所有窗格的尺寸。实现一个稳定、美观、易用的三窗格界面远不止调用几个API那么简单。它涉及到对MFC窗口管理机制的深刻理解以及对用户体验细节的持续打磨。从规划布局、嵌套拆分器到控制尺寸、保存状态再到处理焦点、优化绘制每一步都需要仔细考量。希望这篇结合了原理、步骤和大量实战经验的分享能帮你绕过我当年踩过的那些坑更高效地构建出强大的桌面应用界面。记住好的界面是沉默的助手它不打扰用户却在用户需要时提供恰到好处的支持。

相关新闻

深入解析Unreal引擎Binned2内存分配器:原理、优化与实战调试

深入解析Unreal引擎Binned2内存分配器:原理、优化与实战调试

1. 项目概述:深入Unreal引擎的内存腹地 如果你在开发大型Unreal项目时,曾被编辑器吃掉十几个G内存的场景震撼过,或者为打包后游戏在移动设备上频繁崩溃而头疼,那么你很可能已经触及了引擎内存管理的冰山一角。内存,这个…

2026/9/15 12:28:20 阅读更多 →
DSPE-PEG-FITC-IgG复合物的构建与应用解析

DSPE-PEG-FITC-IgG复合物的构建与应用解析

1. 理解DSPE-PEG-FITC-IgG复合物的基本构成 DSPE-PEG-FITC-IgG这个看似复杂的名称实际上由四个关键部分组成,每个部分都在生物医学应用中扮演着独特角色。让我们拆解这个分子复合物的结构,就像拆解一台精密仪器的各个组件一样。 二硬脂酰磷脂酰乙醇胺&a…

2026/9/17 17:07:29 阅读更多 →
KKS-HF_Patch:Koikatsu Sunshine终极增强补丁安装与使用指南

KKS-HF_Patch:Koikatsu Sunshine终极增强补丁安装与使用指南

KKS-HF_Patch:Koikatsu Sunshine终极增强补丁安装与使用指南 【免费下载链接】KKS-HF_Patch Automatically translate, uncensor and update Koikatsu Sunshine! 项目地址: https://gitcode.com/gh_mirrors/kk/KKS-HF_Patch KKS-HF_Patch是为《Koikatsu Suns…

2026/9/17 4:23:51 阅读更多 →

最新新闻

Maestro Cloudflare隧道完全指南:tunnel-manager如何实现一键安全远程访问

Maestro Cloudflare隧道完全指南:tunnel-manager如何实现一键安全远程访问

Maestro Cloudflare隧道完全指南:tunnel-manager如何实现一键安全远程访问 【免费下载链接】Maestro Agent Orchestration Command Center 项目地址: https://gitcode.com/GitHub_Trending/maestro41/Maestro Maestro 是一款 Agent 编排指挥中心(…

2026/9/18 10:48:13 阅读更多 →
AllData data-integration(数据服务集成)容器化部署实战:从本地镜像构建到私有云仓库全流程

AllData data-integration(数据服务集成)容器化部署实战:从本地镜像构建到私有云仓库全流程

AllData data-integration(数据服务集成)容器化部署实战:从本地镜像构建到私有云仓库全流程 【免费下载链接】alldata 🔥🔥 AllData可定义数据中台,以数据平台为底座,以数据中台为桥梁&#xff…

2026/9/18 10:48:13 阅读更多 →
AIBrix 基于指标的自动扩缩容(Metric-based Autoscaling)实战指南:HPA、KPA 与 APA 的配置与原理

AIBrix 基于指标的自动扩缩容(Metric-based Autoscaling)实战指南:HPA、KPA 与 APA 的配置与原理

AIBrix 基于指标的自动扩缩容(Metric-based Autoscaling)实战指南:HPA、KPA 与 APA 的配置与原理 【免费下载链接】aibrix Cost-efficient and pluggable Infrastructure components for GenAI inference 项目地址: https://gitcode.com/Gi…

2026/9/18 10:48:13 阅读更多 →
CCS代码补全与快捷键故障排查:从索引器到头文件路径的完整指南

CCS代码补全与快捷键故障排查:从索引器到头文件路径的完整指南

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

2026/9/18 10:48:13 阅读更多 →
MAC地址漂移不是故障,是生成树协议的网络呼吸

MAC地址漂移不是故障,是生成树协议的网络呼吸

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

2026/9/18 10:48:13 阅读更多 →
seo优化技巧有哪些速查手册

seo优化技巧有哪些速查手册

网站被黑挂马?这份保姆级建站教程里的SEO技巧救你命 昨晚刚上线的新站,今天打开全是博彩广告?别慌,这种网站被黑挂马不知道怎么办的问题,90%是因为底层代码没写好,SEO结构太烂导致被恶意脚本利用。很多新手朋友一上来就喊救命,其实根源在于你压根没搞懂SEO优化技巧有哪些,把安全漏洞当成了流量入口。…

2026/9/18 10:47:17 阅读更多 →

日新闻

Matlab手写逻辑回归:从数学原理到多变量概率预测模型实现

Matlab手写逻辑回归:从数学原理到多变量概率预测模型实现

很多朋友第一次看到"逻辑回归"这四个字,第一反应就是——这玩意儿是个回归模型吧?我当年也是在Matlab里跑完一段代码,看着输出的0.73、0.86这种概率值,才回过神来:这家伙其实是披着回归外衣的分类神器&#…

2026/9/18 0:00:28 阅读更多 →
高值医用耗材研报PDF:用Python完成字段抽取、清洗与趋势预测

高值医用耗材研报PDF:用Python完成字段抽取、清洗与趋势预测

简介:这份报告是2023-2028年高值医用耗材行业调研及发展前景趋势预测报告,面向医疗器械企业管理者、投资机构、行业研究人员及关注政策变化的从业者,用于把握行业监管动向、市场格局与未来趋势。报告以PDF格式呈现,共1个文件、整体…

2026/9/18 0:00:28 阅读更多 →
三维高斯场赋能世界模型:几何语义蒸馏与机器人决策实战

三维高斯场赋能世界模型:几何语义蒸馏与机器人决策实战

先把我自己的背景交代一下:我之前在搞具身智能和机器人导航相关的项目,很长一段时间里都被“环境表示”这件事卡着。传统做法是用点云或者网格做几何建模,语义信息另外再跑分割模型,两套东西各管各的,时间一长就会发现…

2026/9/18 0:00:28 阅读更多 →

周新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/16 19:03:19 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/17 7:57:36 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/17 10:19:14 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/16 22:31:27 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/15 21:39:18 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/16 22:32:59 阅读更多 →