當鼠標在控制點上進行拖拽操作就應當可以動態的修改對象的大小,以前我是如此實現的
◆在鼠標按鍵按下事件處理(HandleMouseDown)中,若鼠標光標在某個控制點上則設置一個鼠標按鍵按下標記變量,並記下鼠標光標位置,然後退出事件處理
◆在鼠標移動事件中(HandleMouseMove),若設置了鼠標按鍵按下標記變量,則根據當前鼠標光標位置和上一次鼠標光標的位置之差就是鼠標光標移動的距離,該距離的水平分量和垂直分量就是對象寬度和高度的改變量,此時可以使用庫函數System.Windows.Forms.ControlPaint.DrawReversibleFrame在界面上繪制一個虛線框,當鼠標移動時不斷的調用該庫函數,這樣實現了所謂的“橡皮筋”操作
◆在鼠標按鍵松開事件(HandleMouseDown)處理中,根據鼠標光標的當前位置和以前記下的鼠標按鍵按下時的鼠標光標位置計算兩者之差,這樣就是整個鼠標拖拽操作中鼠標光標移動的距離,程序就可以依據該距離來改變對象的大小
經過一些編程實踐,發現該操作比較麻煩,需要編寫不少代碼,而且代碼分散在3個事件處理過程中,多了一些全局變量,很難寫出一個通用例程到處調用,經過分析,將這種處理模式改掉了。其實一般的程序正在進行鼠標拖拽操作時,用戶是不可能同時進行其他操作(不如邊鼠標拖拽邊打字),而且進行”橡皮筋“操作時程序用戶界面無需重新繪制,這樣可以認為進行鼠標拖拽時應用程序應用程序只處理鼠標移動消息和鼠標松開消息而不進行任何其他操作,為了編程簡單,甚至連重繪界面的操作也不處理了,因此可以編一個通用例程來處理整個的鼠標拖拽來實現“橡皮筋”操作,該函數處理過程為
◆在鼠標按鍵按下事件處理(HandleMouseDown)中就調用該例程
◆進入例程中,首先記下鼠標光標的當前位置,然後進入一個死循環
◆該死循環首先調用Win32API函數 WaitMessage等待Windows消息,若沒有任何Windows消息則退出該循環
◆調用Win32API函數PeekMessage來獲得當前Windows消息
◆若當前消息為鼠標按鍵松開消息則退出循環
◆若當前消息為鼠標移動消息則則獲得當前鼠標光標位置,根據開始脫拽的鼠標光標位置來繪制橡皮筋矩形
◆調用Win32API函數GetMessage將當前Windows消息給“吃”掉,然後進入下一次循環
◆例程退出該循環後就將當前鼠標光標位置和拖拽操作前的鼠標光標位置之差,也就是鼠標光標在整個拖拽操作中移動的距離作為返回值返回給主調函數(HandleMouseDown)
◆主調函數接受返回的鼠標光標移動的距離,然後根據該距離來進行其他的處理,在這裡就是修改對象的大小
在此插上一段,其實.Net框架還是比較適合Win32的API編程,System.Windows.Form.Control的Handle屬性就是窗體的句柄,可以被其他Win32API作為參數調用,CreateParams屬性實際上就是CreateWindowEx的參數,重載它就可以設置控件創建時的樣式;WndProc就是控件處理所有的Windows消息的默認過程,也可以重載它自己來處理底層的Windows消息。System.Windows.Forms.Application的靜態函數AddMessageFilter和RemoveMessageFilter就可以很方便的為整個應用程序添加或刪除"鉤子"程序。C#語言可以使用System.Runtime.InteropServices.DllImport來導入聲明DLL文件中的API函數。
光標的控制
光標就是文本編輯器在獲得輸入焦點時在當前插入點閃爍顯示的一個小方塊,當文本編輯器沒有獲得輸入焦點時就不會顯示光標。Windows操作系統已經提供了一套處理光標的API函數,包括創建光標CreateCaret,設置光標位置SetCaretPos,顯示光標ShowCaret和隱藏光標HideCaret。使用API創建和顯示光標後,操作系統會自動的讓光標閃爍。文本編輯器要提供處理光標的例程供其他程序模塊調用。文本編輯器首先根據當前插入點的位置計算光標在文檔視圖區域中的位置,還需要根據文檔處理插入模式還是修改模式計算光標的大小。若光標所在位置在用戶界面上沒有顯示出來則還需要滾動文本編輯器已保證光標所在區域處於可視區域。然後調用API來創建和顯示光標。文本編輯器還重載OnGotFocus過程來顯示光標,重載OnLostFocus過程隱藏光標。注意重載這兩個過程時需要在最後必須調用base.OnGotFocus和base.OnLostFocus,若不這樣則文本編輯器嵌入在網頁中運行會發生無法獲得輸入焦點的錯誤。光標控制還涉及到輸入法的控制,我們中國人使用文本編輯器會使用到各種中文輸入法。Windows操作系統也提供了一套API來控制輸入法。在本文本編輯器中重載OnKeyPress方法來獲得用戶輸入的字符,此時的字符可以是鍵盤直接輸入的ASCI字符,也可以是使用某種輸入法輸入的漢字。這些操作系統都已經實現了,為什麼還要控制輸入法。原因是使用默認處理時輸入法的浮動窗口會顯示在屏幕中間而不會隨著插入點的位置而移動。一般的中文輸入法的用戶界面為一個浮動窗口,各種建議輸入的中文字符顯示在這個浮動窗口中供人選擇。想想看,當插入點在屏幕的某個邊角中,而輸入法的浮動窗口在屏幕中央,這樣輸入中文比較累。但若輸入的浮動窗體隨著插入點的移動而移動,浮動窗體和插入點緊密的靠在一起,這樣輸入中文就不是很累了。Win32API函數ImmSetCompositionWindow能對指定的窗體控制輸入法浮動窗體的顯示位置,當插入點改變時調用該API函數就能讓輸入法浮動窗體隨著插入點跑了。