
旺丁旺财杂货铺
生活/旅行/效率/电器/装修
🎯 前记 Intro
上个月写了独家开源!可能是全网首个Excel多标签插件:MultiTab.ExcelDNA 这篇文章。说实话,当时项目还是勉强实现,当时就没想到会有人下载试用。没想到还真有留言许愿聚光灯的功能。原先铺主,重构多年前手搓插件时就想过增加这个功能,既然要做便顺手移植到这这个开源项目了。后来有前辈吐槽我的多标签功能不伦不类的,偏再次重构了功能。这次就来聊聊更新吧

💡 聚光灯功能

这个功能多年来有很多不同的实践,有通过动态改动表格底色、使用条件格式实现的,也有早期Office 2010时候使用GDI技术绘图实现的,前两者影响既定的Excel单元格格式,后都在Office 2013后因为兼容性而闪瞎眼。铺主都没有,使用的是现行的HUD技术,算是较为完善的方案:
不影响活动行列的原数据的阅读; 不影响Excel单元格格式; 不影响Excel原生的功能使用; 适应表格的各种视图模式; 最大的兼容不同的Excel版本。
技术细节:透明叠加窗体的"硬核"实现
聚光灯HUD技术简单来说是在Excel工作表窗口上面,盖一层透明的、点击穿透的窗体,在上面画高亮矩形,但实际并无开源项目,做出来也不容易。为做出这个功能,特别调研了以下三篇文章:
浅谈Excel阅读模式(聚光灯)实现的部分技术细节 (https://club.excelhome.net/thread-1642276-1-1.html 出处: ExcelHome技术论坛) Excel阅读模式/单元格行列指示/聚光灯开发 技术要点再分享(https://www.cnblogs.com/yinhe-Helloworld/p/10047542.html "隐鹤-Hello_World”) 简单介绍Excel单元格行列指示的实现原理(俗称聚光灯功能) (https://www.cnblogs.com/Charltsing/p/CellLight.html)
窗体层级
这层透明窗体得是Excel工作表窗口(窗口类名叫EXCEL7)的子窗口,通过SetParent挂上去。位置和大小要精确对齐工作表客户区,不能偏一像素。
透明&点击穿透
窗体样式用了WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW这四个扩展样式组合:
WS_EX_LAYERED — 分层窗口,支持透明 WS_EX_TRANSPARENT — 鼠标点击穿透,让下面的Excel单元格正常响应 WS_EX_NOACTIVATE — 点击时不激活,不给Excel添乱 WS_EX_TOOLWINDOW — 不在任务栏显示,免得用户以为是另外一个窗口
绘图
用UpdateLayeredWindow把Format32bppArgb位图按AC_SRC_ALPHA混合上去。画两个矩形——行高亮和列高亮,交叉点就是当前选中单元格,6px圆角,抗锯齿,颜色和透明度均可配置。
坐标转换
这是最折磨人的部分。Excel的单元格坐标是Pane.PointsToScreenPixelsX/Y转成屏幕坐标,然后再用ClientToScreen转成EXCEL7客户区坐标。遇到冻结窗格(Freeze Panes)和拆分窗口(Split Windows)时,可见区域和实际滚动偏移要分开算,不然高亮条会跑偏。最近一次提交修的就是这个bug——冻结窗格下聚光灯断裂的问题。
COM线程安全
所有Excel对象操作都通过ExcelAsyncUtil.QueueAsMacro调度到Excel主线程,订阅SheetSelectionChange事件来刷新,防止COM重入导致崩溃。
说句实话,透明窗体+点击穿透这套组合拳,在Win32层面已经属于比较硬核的操作了。
📦 Ribbon 集成
上一版MultiTab只有标签栏,铺主懒得弄个Ribbon Tab。想开关功能、改设置,都得去改配置文件,不够直观。
这次铺主加了一个Fluent Ribbon选项卡,在Excel顶部菜单栏里多了一个"MultiTab"分组,里面放了聚光灯开关、标签设置、重新加载配置几个按钮。改了配置文件不用重启Excel,点一下就能热刷新。
Ribbon的实现用的是Excel-DNA的Fluent Ribbon XML + 回调机制,不需要VSTO那套注册表配置,清爽。按钮图标全部嵌入为资源文件,不依赖外部图片。
🧊架构重构——从"能跑"到"能维护"
上一版代码的多标签功能是用Workbook的Sheet.Active功能实现来着,被前辈痛批不伦不类。在前辈的提点下,以Excel窗口句柄为Key,改为每个XLMAIN独立创建标签栏。Excel 2013+的SDI模式下,每个工作簿有独立的XLMAIN窗口,多标签和聚光灯都能正确跟随,不会出现标签跑到另一个屏幕上的情况。
另外,由于之前只有多标签功能,所以所有逻辑都在几个文件里,牵一发动全身。这次趁加聚光灯功能,把整个项目结构彻底梳理了一遍:
现在每个模块各司其职,想改聚光灯就去Spotlight/目录,想改标签就去ExcelTab.cs,逻辑清晰,代码审计也方便。
🎨 配置升级——不止是改颜色
上一版的配置只有标签颜色的几项。这次扩展了不少,除了标签颜色,还加了聚光灯的开关、颜色,预设了16种Office 365风格色板(主题色10个+标准色6个),通过Ribbon上的颜色选择器点点鼠标就能换。
颜色选择器用的是OfficePickers.dll,这个库也是铺主从开源社区淘来的,一并打包在项目里。
配置文件的解析依然坚持零依赖,手写SimpleJsonParser,不引入Newtonsoft.Json。修改配置后重启Excel或者点Ribbon上的"重新加载配置"即可生效。
📝 WQ:后记
目前这边应该是第一个愿意开源多标签和聚光灯功能的项目,如果你需要在自己的插件中集成这个项目,希望得到你的一键五连,开源不易。这里要交待上篇文章许愿没有达成的去除多标签标题的事:由于铺主技术有限的关系还是使用CTP做多标签的容器,标题去除的需求没有实现,但也因为CTP是Office的原生组件,避免了OfficeTab使用底层技术让强制让窗口位置改动易引起连锁崩溃。项目插件下载地址依然放到文章最后,关于如何使用插件这次就不聊了,不懂的可以看回上一篇文章。独家开源!可能是全网首个Excel多标签插件:MultiTab.ExcelDNA好了,这次就聊到这了,若然觉得这篇文章能帮到你,希望大家点赞和评论留言,这能帮到我不少,有什么软件需要也可以留言给我,我会尽快回复,感谢感谢!!!

📥 项目地址:https://gitee.com/ginkdu/mutli-tab.-excel-dna/releases
夜雨聆风