有時,我們需要用VB快速開發一個試驗資料繪圖處理程序,將繪圖控制項內的滑鼠遊標改變成與AutoCAD軟體中使用的大十字遊標的形式,將可以比普通的箭頭遊標達到更好的效果。那我們要如何實現這樣的大十字遊標呢?
----首先,我們明確一下要達到的效果,假若我們在一個Picture控件中繪圖,那麼,當鼠標移動到這個控件上時,滑鼠遊標立即改變為大十字形狀,遊標中的橫線從控件的左邊界到右邊界,垂直線從控制的上邊界到下邊界,即大十字光標將繪圖控制分割為四個像限。當滑鼠移動到控制外時,遊標則又恢復成原來的形式。
----要實現這樣的遊標,得我們自己透過畫線的方式實現。如滑鼠在繪圖控制項內,先在滑鼠的目前位置畫上遊標的橫線和垂直線;當滑鼠位置移動,先擦除原先的遊標橫線和垂直線,然後再在新的位置畫遊標的橫線和垂直線,那麼我們就要回應繪圖控制項的MouseMove事件。當然,繪圖控制項內無論有什麼內容,我們擦除遊標線和重畫遊標線時都不能破壞原先的內容,因此我們要將繪圖控制的DrawMode設定為vbXorPen(異或方式),繪製遊標的橫線和豎線時,用異或的方式將橫線和豎線的像素點顏色設為遊標的顏色和原先的像素點色彩的異或值,再用異或的方式在同樣的位置繪製一遍豎線和橫線,橫線和豎線上的像素點再一次和遊標顏色進行異或操作,就擦除了遊標的橫線和垂直線,且又恢復了繪圖控制內原先的內容。
----我們還得確保滑鼠移動到繪圖控制項內時,普通的滑鼠遊標消失,只有繪製的大十字遊標出現,因此也應該設定繪圖控制項的MousePointer屬性為vbCuntom,即使用者自訂。繪圖控制項的MousePointer屬性設定為vbCustom後,其MouseIcon屬性中應裝入對應的使用者自訂圖形,因為我們希望繪圖控制項內只有我們所繪製的遊標,而沒有其它的遊標,故應裝入一個空的(透明的)遊標圖形。可以任找一個遊標文件,透過任何一個資源編輯器進行編輯,用透明的方式填充整個遊標圖形,保存成我們所需的NoIcon.cur即可。
----透過以上的關鍵設定和操作,我們就可以實現大十字遊標了。利用異或方式進行繪圖,我們還可以實現一般繪圖軟體中常有的「橡皮筋」效果,即用滑鼠定義一個點後,動態拖曳滑鼠來定義另一個點,動態拖曳滑鼠過程中,所要繪的圖形也動態對應變化。
----以下我們透過一個範例來完整實作繪圖控制項中的大十字遊標,也示範如何實作以「橡皮筋」效果來畫出矩形:
----在VB中新建一個標準EXE工程,在Form1中加入一個Picture控件,其Name設為PicDraw,可以裝入一個圖象文件,PicDraw的大小和其中的圖像大小基本上覆蓋大部分的Form1即可。實作程式碼如下所示。此程式在VB5.0中運行通過。
OptionExplicit
PRivateOld_XAsSingle
PrivateOld_YAsSingle
PrivateisMouseDownAsBoolean
PrivateBox_X0AsSingle
PrivateBox_Y0AsSingle
PrivateBox_X1AsSingle
PrivateBox_Y1AsSingle
PrivatePenColorAsLong
PrivateCrossColorAsLong
PrivateSubForm_Load()
CrossColor=QBColor(8)
PenColor=QBColor(15)
picDraw.DrawMode=vbXorPen
picDraw.MouseIcon=LoadPicture
(App.Path&"/no.cur")
picDraw.MousePointer=vbCustom
isMouseDown=False
Box_X0=Box_X1=Box_Y0=Box_Y1=0
EndSub
PrivateSubpicDraw_MouseDown
(ButtonAsInteger,
ShiftAsInteger,XAsSingle,YAsSingle)
IfisMouseDown=TrueThen
'先前已經用滑鼠定義了一個點
Box_X1=X
Box_Y1=Y
isMouseDown=False
picDraw.DrawMode=vbCopyPen
picDraw.Line(Box_X0,Box_Y0)-
(Box_X1,Box_Y1),
PenColor,B
picDraw.DrawMode=vbXorPen
'畫一個遊標
picDraw.Line(0,Y)-(picDraw.ScaleWidth,Y),
CrossColor
picDraw.Line(X,0)-(X,picDraw.ScaleHeight),
CrossColor
Old_X=X
Old_Y=Y
Else
'定義了一個矩形的第一個頂點,則擦除遊標
picDraw.Line(0,Y)-(picDraw.ScaleWidth,Y),
CrossColor
picDraw.Line(X,0)-(X,picDraw.ScaleHeight),
CrossColor
Box_X0=X
Box_Y0=Y
isMouseDown=True
EndIf
EndSub
PrivateSubpicDraw_MouseMove(ButtonAsInteger,
ShiftAsInteger,XAsSingle,YAsSingle)
IfisMouseDown=TrueThen
'拖曳滑鼠來定義矩形的另一個頂點,
此時擦除前一個矩形,繪製新的矩形
picDraw.Line(Box_X0,Box_Y0)-(Old_X,Old_Y),
PenColor,B
picDraw.Line(Box_X0,Box_Y0)-(X,Y),PenColor,B
Else
'消除舊遊標線
picDraw.Line(0,Old_Y)-(picDraw.ScaleWidth,Old_Y),
CrossColor
picDraw.Line(Old_X,0)-(Old_X,picDraw.ScaleHeight),
CrossColor
'畫出新的遊標線
picDraw.Line(0,Y)-(picDraw.ScaleWidth,Y),
CrossColor
picDraw.Line(X,0)-(X,picDraw.ScaleHeight),
CrossColor
EndIf
Old_X=X
Old_Y=Y
EndSub->