在開發一個Sql文字編輯器時很意外的在游標顯示問題上卡了一下。其解決的過程和之前發布的問題解決篇中的內容很吻合,是對比法解決問題的一個非常好的例子。所以下來分享一下。
背景:
1.由於產品需要,公司決定自行開發一個文本剪輯器,以滿足功能的要求。
2.我們是在讀懂一個開源的編輯器的基礎上,完全自行開發的。
3.之前在GDI+方面的經驗非常少,僅限於基本的圖形繪製
問題:
在顯示編輯器中的游標時,需要在某些場合自行繪製游標。我發現游標的定位有問題,總是偏離正確位置兩個像素左右的位移。也就是說游標在當前行的位置,往上多位移了兩個像素左右的位置。這是通過觀察顯示器的輸出得到的結論。當然差這一點距離,不是說就不行,只是與其它編輯器比較會覺得很不舒服。所以我還是打算解決這個問題。
下面介紹一下解決步驟和過程。第一步是嘗試調整顯示光線標的位置。既然游標位置偏高,那麼顯示光線標時把位置調低不就可以了麼。不幸的是實踐發現,顯示位置調低以後,游標圖形的上面是不高了,但是下面卻偏低了。無論如何調整都不能兩全。通過比較開源的代碼也沒有發現問題。然後上網找例子,但是若干例子嘗試以後,也沒有解決問題。由於畫游標只是一個簡單繪製直線的操作,所以真的不清楚還會出什麼問題。於是到這裡就陷入困境了。
考慮一下過後,開始考察自行繪製的游標和用Win32 API點亮的游標之間的差異。我發現點亮的游標顯示是正常的,而點亮的游標的位置和自行繪製貫標的位置是相同的。這說明位置是正確的,問題出在別的地方。好,到這裡這在困境中多少理出了一條新線索。於是想到一個方法,點亮的游標位置和繪製的游標位置使用不同的座標,在繪製游標時將座標往下移兩個像素。這個方法是可行的,但是顯然不太完美,至少開原始碼中沒有這樣。嘗試後發現位置貌似對了,但是繪製的游標和點亮的游標在形狀上存在一點點差異。由於整個游標的高度也就是10個像素左右,所以這一點點差異從比例上講還是不小的,使用者會有明顯的察覺。所以問題還是沒有完全解決。
到這裡基本上覺得很頭疼了。由於之前沒有接觸過游標的繪製,所以還一度開始懷疑是不是在某些不知道的地方出現了問題。在多次google和比較開原始碼之後還是沒有發現導致問題的原因。但是可以肯定一點是我寫下的代碼本身出問題的可能也很低。因為都是非常簡單的代碼。於是把注意力放寬,關注整個繪製流程,也就是OnDraw方法中的全部代碼。通過反覆和仔細的比較,發現了一個可疑的地方。那就是我在繪製文本時繪製方法的參數指定使用高品質,反鋸齒的效果,而在開源碼中是沒有這樣做的。一個事實說清楚的,如果使用反鋸齒高品質的參數來繪製直線的話,那麼直線是會有一點虛化部分,用於光滑鋸齒。那麼這個會不會就是導致問題的原因呢?
在嘗試修改之前來回答這個問題的話,我一定說不會。因為反鋸齒的效果只會線上條不是垂直和水平的情況下出現,這個經驗我在用VC的時候是有的。而我現在繪製的游標就是一個10幾像素高的垂直直線。但是眼下的情況不同,因為這麼一個簡單的繪製直線的小問題,在反覆多次檢查都沒有能查出問題的所在,所以當下這個線索是值得去確認一下。另一個理由是,開原始碼沒有使用反鋸齒,這是通過比較發現的差異,讓這個線索變得很可疑。實踐證明確實就是這個原因導致。修改代碼,在繪製游標時不使用反鋸齒效果,於是問題就解決了。