原始出处:www.cnblogs.com/Charltsing/p/CellLight.html
QQ:564955427
Excel单元格行列指示的实现原理(俗称聚光灯功能)
单元格行列指示功能在录入大表格的时候可以避免行列录入错误,是个非常有用的功能。在某些插件里面俗称聚光灯功能。目前的VBA实现此功能的代码有很多,大概分三类:线段指示、单元格背景、条件格式。这几种方法代码简单,方便易用,效果很好。唯一的缺点是会影响单元格或者表格的一些数据,也会影响Undo和Redo的操作。
为了避免上面的缺陷,有人采用GDI绘图方式来实现单元格指示功能与工作表格的完全脱离,从根本上避免表格数据信息被破坏。下面我就简单介绍一下此类技术的实现原理。
Excel2010及以下版本的实现原理
单元格行列指示功能,在本论坛有GDI实现的代码,简单原理如下:
1、用spy++可以看到,Excel的表格窗口类名是“Excel7”,父窗口是“XLDESK”,再上面父窗口是“XLMAIN”。
2、通过SelectChange事件,获取激活单元格。
3、通过Windows API获取激活单元格的屏幕坐标和EXCEL7窗口的范围
4、根据上述坐标用GDI直接在EXCEL7窗口上绘图,就可以看到聚光灯效果了。
Excel2013以上版本的实现原理
可是,从Excel2013开始,微软改变了Excel7等窗口的绘图方式,导致GDI无法直接绘图,具体解决办法不详,哪位大神知道留个言。
为了一劳永逸的解决无法绘图的问题,我考虑采用HUD技术。
HUD是Head Up Display的缩写,中文意思是抬头指示。所谓HUD技术就是在正常画面上,叠加一个透明或者半透明效果的窗口,用来显示一些实时的数据。玩过飞行模拟之类游戏的,都会看到这种效果。很多电影的炫酷特效画面也经常能看到。
在Windows下实现HUD技术有很多成熟的例子。最简单的办法就是做一个透明无焦点的窗口即可,例子可以百度或者在开源项目中也能找到很多。
具体流程如下:
1、通过SelectChange事件,获取激活单元格。
2、通过Windows API获取激活单元格的屏幕坐标和EXCEL7窗口的范围
3、挂接自己的透明窗体,根据上述坐标用GDI直接在窗口上绘图,就可以看到聚光灯效果了。
4、注意处理一些窗口消息(例如WM_SIZE等),以确保在Excel窗口发生变化的时候能够实时更新绘图参数
Windows7和Windows10实现该功能的重大差别
1、Windows7操作系统的API和Windows8以上操作系统有些区别。特别是对透明窗体的一些关键API处理存在Bug,我不清楚是什么原因造成的,如果有哪位大神知道,在此留个言。
2、Excel在Windows7和Windows10下的消息也有很大不同,有些消息直接影响了代码流程,如果你想做这个功能的开发,切记一定要准备两个操作系统环境
3、监听XLMAIN和EXCEL7窗口基本可以满足功能需求,但要注意在不同系统下的消息差异,这很坑爹!
单元格行列指示目前实现的一些功能简介:
1、可自定义颜色的单元格焦点指示功能
2、用于行列对齐识别(采用GDI32实现,不影响工作表数据)
3、支持切换工作簿工作表冻结窗格滚动条鼠标滚轮拖拽单元格等各种情况
4、支持Excel2013、2016。彻底解决闪烁问题。
以上功能在我写的DNA Tools2.x版中已经得到完整验证。
总结:HUD技术的用途很广,学会了这个技术的应用,相信你对Winform编程会上升到一个新的台阶!
如果有谁对本人写的单元格行列指示功能源代码有兴趣的,可以QQ找我联系!