浅谈Excel阅读模式(聚光灯)实现的部分技术细节

 

一、废话

阅读模式(聚光灯)功能不用多介绍了,很多插件已经实现了该功能,也是很多“表哥、表姐”热爱的功能。

二、我的插件iCells

iCells汇集了平时自己常用的功能,当然也实现了聚光灯的功能,并且支持32位和64各个版本的Excel和Windows,功能演示地址:iCells(Excel插件)类似WPS的阅读模式(聚光灯) 

三、参考

实现该功能,可以参的的的几篇文章和插件如下:

(一)[原创] 【重磅发布】:聚光灯——我的加载宏系列小工具【单元格小工具】之四 (https://club.excelhome.net/thread-1395812-1-1.html)

(二)简单介绍Excel单元格行列指示的实现原理(俗称聚光灯功能)( https://www.cnblogs.com/Charltsing/p/CellLight.html)

(三)Excel阅读模式/单元格行列指示/聚光灯开发 技术要点再分享(https://www.cnblogs.com/yinhe-Helloworld/p/10047542.html)

(四)主要参考的Excel插件有方方格子、KutoolsforExcel。

四、实现步骤

能够不影响Excel使用情况下,实现的原理在上面提到的几篇文章中已经有了比较深入的介绍,简单概括就三个步骤,但是每一个步骤都值得去细细打磨,每一个地方都很容易存在bug,特别是跨Excel版本、跨Windows版本以及32位和64的区别。

(一)设计一个窗体作为“聚光灯”的载体。类似于屏幕贴膜的原理,在Excel窗口上面,设计一个透明的窗体作为“手机膜”,然后再在这层膜上面擦除和画画。

(二)用系统API和EXCEL提供的函数来计算“聚光灯”的形状,即画画的内容。

(三)拦截系统消息,触发“聚光灯”形状的变化。

四、细节分享(VSTO)

以下分享的全部是基于VSTO开发,但其他的思路理应也是一样的。

(一)窗体载体

1.关键点是鼠标能穿透、无焦点,可以借助各种api实现。在VSTO中,由于Forms类提供的窗体已经是封装好了的,如果用Forms类,会发现有抢焦点的情况,DotNet是有特殊的类支持无焦点窗体的,当然这得益于ExcelPower_Helper作者隐鹤对我的帮助。

2.由于从Excle2013版本开始,Excel中多个工作簿,会有多个“XLMAIN”窗体,这就必须处理当有多个工作簿的情况,聚光灯窗体是需要跟着Excel的窗体进行变化的。

3.聚光灯窗体和Excel窗体的关系,这个在“Excel阅读模式/单元格行列指示/聚光灯开发 技术要点再分享”,这篇文章中有提到,但是并没有给出具体的API,设置的无非就是父子关系,可实现的其中一个API是“SetParent”。

(二)位置的计算

1. PointsToScreenPixelsX/Y计算单元格的屏幕坐标时,其对象一定是Pane,所以是Pane. PointsToScreenPixelsX/Y,而不是Window. PointsToScreenPixelsX/Y。

2.注意聚光灯窗体的大小(长度和高度)以及起点,可以在Excel找一个固定的窗体,参照这个窗体,从而来计算聚光灯窗体的大小以及起点,多观察,每个版本都可以找到一个参考窗体。聚光灯的起点,如果包括行、列标签,参考“EXCEL7” 窗体的起点坐标,如不想包括,参考visiblerange的起点坐标。

3.多窗格的情况,其实不用想得很复杂,可以当成一个来处理。在Excel2010前的版本,由于分割栏有宽度,如果不想聚光灯覆盖他,可以参考SplitHorizontal、SplitVertical。

(三)消息的拦截

1.Hook技术,网上很多,先看看基础原理。

2. WH_CALLWNDPROCRET完全能够实现。

3.剩下的就是多调试消息,很多Bug都是拦截的消息导致的。

五、写在最后

我写的插件iCells的阅读模式只是其中的一个小小的功能,iCells与众不同的地方是尽量减少交互操作,以最少的步骤可实现相应的功能。

iCells QQ交流群:

 

 

 

posted @ 2022-10-10 12:52  iCells  阅读(1320)  评论(0编辑  收藏  举报