DrawFocusRect
VB聲明
Declare Function DrawFocusRect Lib "user32" Alias "DrawFocusRect" (ByVal hdc As Long, lpRect As RECT) As Long
說明
畫一個焦點矩形。這個矩形是在標誌焦點的樣式中通過異或運算完成的(焦點通常用一個點線表示)。如用同樣的參數再次調用這個函數,就表示刪除焦點矩形
傳回值
Long,非零表示成功,零表示失敗。會設定GetLastError
參數表
參數 類型及說明
hdc Long,裝置情境的控制代碼
lpRect RECT,要在邏輯座標中描繪的矩形
這是一個可以直接畫出虛線框的函數,非常有用,收錄!
一、游標的指示
當游標移動到要拖動或縮放的控制項上時,應顯示相應的動作箭頭。定義一個枚舉的變數來標識對應的狀態。
Enum EnumMousePointPosition
MouseSizeNone = 0 '無
MouseSizeRight = 1 '展開右邊框
MouseSizeLeft = 2 '展開左邊框
MouseSizeBottom = 3 '展開下邊框
MouseSizeTop = 4 '展開上邊框
MouseSizeTopLeft = 5 '展開左上方
MouseSizeTopRight = 6 '展開右上方
MouseSizeBottomLeft = 7 '展開左下角
MouseSizeBottomRight = 8 '展開右下角
MouseDrag = 9 '滑鼠拖動
End Enum
Dim m_MousePointPosition As EnumMousePointPosition
在MouseMove事件中讀取進入控制項的游標位置,用下面函數判斷游標的狀態。
m_MousePointPosition = MousePointPosition(sender.Size, e)
按對應的狀態顯示光線標形狀
Select Case m_MousePointPosition
Case EnumMousePointPosition.MouseSizeNone
Me.Cursor = Cursors.Arrow
'箭頭
Case EnumMousePointPosition.MouseDrag
Me.Cursor = Cursors.SizeAll
'四方向
Case EnumMousePointPosition.MouseSizeBottom
Me.Cursor = Cursors.SizeNS
'南北
Case EnumMousePointPosition.MouseSizeTop
Me.Cursor = Cursors.SizeNS
'南北
Case EnumMousePointPosition.MouseSizeLeft
Me.Cursor = Cursors.SizeWE
'東西
Case EnumMousePointPosition.MouseSizeRight
Me.Cursor = Cursors.SizeWE
'東西
Case EnumMousePointPosition.MouseSizeBottomLeft
Me.Cursor = Cursors.SizeNESW
'東北到南西
Case EnumMousePointPosition.MouseSizeBottomRight
Me.Cursor = Cursors.SizeNWSE
'東南到西北
Case EnumMousePointPosition.MouseSizeTopLeft
Me.Cursor = Cursors.SizeNWSE
'東南到西北
Case EnumMousePointPosition.MouseSizeTopRight
Me.Cursor = Cursors.SizeNESW
'東北到南西
End Select
如果游標離開控制項,MouseMove事件將不響應,因此用需用MouseLeave事件來接力完成游標狀態的標識和顯示。
Private Sub MyMouseLeave(ByVal sender As Object, ByVal e As System.EventArgs)
m_MousePointPosition = EnumMousePointPosition.MouseSizeNone
Me.Cursor = Cursors.Arrow
End Sub
二、拖動
拖動的原理是行動控制項的Location到當前游標的位置,並保持控制項的高度和寬度不變。如果記錄起始游標點為p,當前游標點為e,那麼x方向的移動距離是e.X - p.X,x方向的移動距離是e.Y - p.Y。
在滑鼠按下時,即是拖動的開始,在MouseDown事件中,記錄游標開始拖動點
p = New Point(e.X, e.Y)
在MouseMove事件,檢測是否持續按著滑鼠左鍵,如果是則更新控制項的起點位置
If e.Button = MouseButtons.Left Then
sender.Location = New Point(sender.Left + e.X - p.X, sender.Top + e.Y - p.Y)
End If
三、縮放
縮放的原理和拖動類似,如果縮放底邊,就是根據游標的移動改變控制項的高度,而不改變控制項的起點位置。
同樣,如果縮放底邊,在滑鼠按下時,即是縮放的開始,在MouseDown事件中,記錄游標開始拖動點
p = New Point(e.X, e.Y)
在MouseMove事件,檢測是否持續按著滑鼠左鍵,如果是則更新控制項的高度
If e.Button = MouseButtons.Left Then
sender.Size = New Size(sender.Width, sender.Height + e.Y - p1.Y)
p1 = New Point(e.X, e.Y)
'記錄游標拖動的當前點
End If
這裡和拖動有些區別,就是高度的變化會導致游標位置數值的變化,因此需重新用p1定位游標起始點的位置。所有涉及控制項底邊和右邊的縮放都要這樣處理,而左邊和頂邊則不用。
其它所有各方向的拖動都可以類推。
四、委派
所有的操作,一共總結為三個函數,MyMouseDown,MyMouseMove,MyMouseLeave。
動態建立控制項後,需委派相應的事件到這三個函數。如果建立一個按鈕,
Dim Button As New Button
Controls.Add(Button)
AddHandler Button.MouseDown, AddressOf MyMouseDown
AddHandler Button.MouseMove, AddressOf MyMouseMove
AddHandler Button.MouseLeave, AddressOf MyMouseLeave
五、源碼
建立一個表單,放置一個按鈕,點擊該按鈕建立動態建立一個可以拖動和縮放的按鈕。全部源碼如下:
Public Class Form1
Inherits System.Windows.Forms.Form
Enum EnumMousePointPosition
MouseSizeNone = 0 '無
MouseSizeRight = 1 '展開右邊框
MouseSizeLeft = 2 '展開左邊框
MouseSizeBottom = 3 '展開下邊框
MouseSizeTop = 4 '展開上邊框
MouseSizeTopLeft = 5 '展開左上方
MouseSizeTopRight = 6 '展開右上方
MouseSizeBottomLeft = 7 '展開左下角
MouseSizeBottomRight = 8 '展開右下角
MouseDrag = 9 '滑鼠拖動
End Enum
Dim m_MousePointPosition As EnumMousePointPosition
Dim p, p1 As Point
Private Sub MyMouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
p = New Point(e.X, e.Y)
'記錄游標開始拖動點
p1 = New Point(e.X, e.Y)
End Sub
Private Sub MyMouseLeave(ByVal sender As Object, ByVal e As System.EventArgs)
m_MousePointPosition = EnumMousePointPosition.MouseSizeNone
Me.Cursor = Cursors.Arrow
End Sub
Private Sub MyMouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = MouseButtons.Left Then
Select Case m_MousePointPosition
Case EnumMousePointPosition.MouseDrag
sender.Location = New Point(sender.Left + e.X - p.X, sender.Top + e.Y - p.Y)
Case EnumMousePointPosition.MouseSizeBottom
sender.Size = New Size(sender.Width, sender.Height + e.Y - p1.Y)
p1 = New Point(e.X, e.Y)
'記錄游標拖動的當前點
Case EnumMousePointPosition.MouseSizeBottomRight
sender.Size = New Size(sender.Width + e.X - p1.X, sender.Height + e.Y - p1.Y)
p1 = New Point(e.X, e.Y)
Case EnumMousePointPosition.MouseSizeRight
sender.Size = New Size(sender.Width + e.X - p1.X, sender.Height)
p1 = New Point(e.X, e.Y)
Case EnumMousePointPosition.MouseSizeTop
sender.Location = New Point(sender.Left, sender.Top + (e.Y - p.Y))
sender.Size = New Size(sender.Width, sender.Height - (e.Y - p.Y))
Case EnumMousePointPosition.MouseSizeLeft
sender.Location = New Point(sender.Left + e.X - p.X, sender.Top)
sender.Size = New Size(sender.Width - (e.X - p.X), sender.Height)
Case EnumMousePointPosition.MouseSizeBottomLeft
sender.Location = New Point(sender.Left + e.X - p.X, sender.Top)
sender.Size = New Size(sender.Width - (e.X - p.X), sender.Height + e.Y - p1.Y)
p1 = New Point(e.X, e.Y)
Case EnumMousePointPosition.MouseSizeTopRight
sender.Location = New Point(sender.Left, sender.Top + (e.Y - p.Y))
sender.Size = New Size(sender.Width + (e.X - p1.X), sender.Height - (e.Y - p.Y))
p1 = New Point(e.X, e.Y)
Case EnumMousePointPosition.MouseSizeTopLeft
sender.Location = New Point(sender.Left + e.X - p.X, sender.Top + (e.Y - p.Y))
sender.Size = New Size(sender.Width - (e.X - p.X), sender.Height - (e.Y - p.Y))
End Select
Else
m_MousePointPosition = MousePointPosition(sender.Size, e)
'判斷游標的位置狀態
Select Case m_MousePointPosition