19. 滑 鼠

Visual Basic提供了16種標準的滑鼠游標,並且讓你定義屬於自己的游標,本章的重點在介紹如何運用這些游標以及如何自行定義游標。

如何改變滑鼠游標?
 

在表單及許多可視控制項的屬性群中,其中有一個屬性MousePointer是用來定義滑鼠游標外觀的屬性。當游標在表單或控制項上移動時,游標就會變成MousePinter所定義的形狀。然而,這個屬性通常是在執行階段由程式碼設定的,因為根據程式所執行工作的不同,滑鼠游標也應該不同 (例如,在進行一個耗時的工作時,滑鼠游標通常會變成一個沙漏)在設計階段,MousePointer的屬性值都被設為vbDefault。

Visual Basic提供了一組十分方便好用的常數作為MousePointer屬性的設定值。使用這組常數時,請叫出「瀏覽物件」對話方塊,選擇「MousePointerConstants」,再利用「複製」及「貼上」功能將這些常數複製到程式碼視窗中即可。以下這張表列出了這組常數以及滑鼠游標形狀的描述。

常數 描述(游標形狀)
vbDefault 0 系統預設:由物件本身決定游標形狀
vbArrow 1 箭號
vbCrosshair 2 十字形
vbIbeam 3 I字形
vbIconPointer 4 圖像
vbSizePointer 5 調整尺寸游標:東西南北四向箭號
vbSizeNESW 6 調整尺寸游標:東北-西南雙向箭號
vbSizeNS 7 調整尺寸游標:南-北雙向箭號
vbSizeNWSE 8 調整尺寸游標:西北-東南雙向箭號
vbSizeWE 9 調整尺寸游標:東西雙向箭號
vbUpArrow 10 向上箭號
vbHourglass 11 沙漏
vbNoDrop 12 禁止置放符號
vbArrowQuestion 14 箭號及問號
vbSizeAll 15 指向四方
vbCustom 99 由MouseIcon屬性指定

在上表中,手指形狀的游標並沒有被定義,這是因為Visual Basic讓你可以建立自己的游標形狀,有關這部份我們到 第三十三章"公用程式" 再作討論。沙漏形狀常數是MousePointer屬性最常用到的常數,沙漏形狀的游標在告訴使用者系統正在進行處理。從圖19-1中你可以看到一個沙漏形狀的游標。請記得在工作結束時,要把游標形狀回復到原來的形狀。


 

 圖19-1 沙漏形狀的游標表示系統正在忙碌中

以下這段程式碼即是運用這種技巧。

frmMain.MousePointer = vbHourglass
ReturnValue = TimeConsumingFunction()
frmMain.MousePointer = vbDefault

參考資料:

請參閱 第三十三章"公用程式" 的MousePtr應用程式,這個程式讓你嘗試使用不同形狀的滑鼠游標。


如何建立自訂的滑鼠游標?
 

要建立自訂的滑鼠游標,首先你要把MousePointer屬性設定為vbCustom,然後指定圖像檔(ICO)檔或游標檔(CUR)的檔名給MouseIcon屬性,圖19-2所顯示的游標就是一個使用者自訂的游標。


 

 圖19-2 以圖像檔中的圖像作為滑鼠游標

注意:

目前MouseIcon屬性並不支援動畫游標。


如果在應用程式中要使用許多個不同的游標形狀,你可以在設計階段把多個圖像檔載入到ImageList控制項中(在Microsoft Windows Common Controls,MSCOMCTL.OCX裡),然後便可以方便快速地從ImageList的Picture屬性值中取得自訂的游標形狀,以下這段程式使用ImageList控制項來顯示不同的游標形狀。

Option Explicit

Private Sub Form_Click()
    Static intList As Integer
    intList = intList + 1
    If intList > 3 Then intList = 1
    MousePointer = vbCustom
    MouseIcon = ImageList1.ListImages(intList).Picture
End Sub

如何顯示動畫游標?
 

MouseIcon屬性並不支援動畫游標,不過,我們仍然能夠用Windows API函式來顯示動畫游標。

先用LoadCursorFromFile API函式載入任何一個Windows支援的游標,檔案載入後,要用Windows API函式SetClassLong函式來改變游標形狀,以下這段程式告訴你實際的做法:

Option Explicit

`Loads cursors and creates mouse pointer handle
Private Declare Function LoadCursorFromFile _
Lib "user32" Alias "LoadCursorFromFileA" ( _
    ByVal lpFileName As String _
) As Long

`Changes class information for a window
Private Declare Function SetClassLong _
Lib "user32" Alias "SetClassLongA" ( _
    ByVal hwnd As Long, _
    ByVal nIndex As Long, _
    ByVal dwNewLong As Long _
) As Long

`Index of mouse pointer in window class structure
Private Const GCL_HCURSOR = (-12)
Private hOldCursor As Long

Private Sub Form_Load()
    Dim hNewCursor As Long
    `Get handle to new animated mouse pointer
    hNewCursor = LoadCursorFromFile _
        ("C:\WINDOWS\CURSORS\DRUM.ANI")
    `Replace window's mouse pointer with new 
    `animated mouse pointer
    hOldCursor = SetClassLong(Form1.hwnd, GCL_HCURSOR, _
        hNewCursor)
End Sub

Private Sub Form_Unload(Cancel As Integer)
    `Restore original mouse pointer to prevent animated 
    `mouse pointer from being retained
    hOldCursor = SetClassLong(Form1.hwnd, GCL_HCURSOR, _
        hOldCursor)
End Sub

Form_Unload事件程序必須把游標回復為原來的樣子,如果不這麼做,那麼即使程式停止執行後,在設計階段中的游標仍然會是動畫游標。另外,請不要認為所有系統中的DRUM.ANI的路徑都和範例中的路徑一樣,你可以用Windows API函式GetWindowsDirectory來取得Windows的目錄名稱。

如何判斷游標的位置?
 

MouseMove、MouseUp以及MouseDown事件被驅動時會提供許多有用的資訊,其中的x值和y值可以告訴你滑鼠游標的位置。

以下這個範例告訴你如何利用游標的位置在表單上畫線。這個程式的基本概念是:當滑鼠左鍵被按下時,先記下線段的起點,當滑鼠左鍵鬆開後,再記下線段的終點。我們在MouseDown事件把中滑鼠游標的位置存放在模組層次的變數X1和Y1裡,以便讓Form_MouseUp事件程序可以使用到這兩個值,做為線段的起點。

Option Explicit

Private X1, Y1

Private Sub Form_MouseDown( _
    Button As Integer, _
    Shift As Integer, _
    X As Single, _
    Y As Single _
)
    X1 = X
    Y1 = Y
End Sub

Private Sub Form_MouseUp( _
    Button As Integer, _
    Shift As Integer, _
    X As Single, _
    Y As Single _
)
    Line (X1, Y1)-(X, Y)
End Sub

圖19-3顯示的是本範例執行的情形。


 

 圖19-3 利用MouseUp和MouseDown事件畫出線段

參考資料:

 第三十三章"公用程式" 的MousePtr應用程式對游標位置有進一步的討論。