原始出處: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找我聯系!
