1. 程式人生 > >VB如何觸發焦點事件和失去焦點事件

VB如何觸發焦點事件和失去焦點事件

VB中有一個LostFocus事件和一個GotFocus事件,看名字似乎是噹噹前視窗失去焦點或得到焦點時觸發的事件。但在實際應用時卻發現當這個視窗和Windows中其他視窗進行切換時並沒有觸發這兩個事件。現在解析一下這兩個事件。 

---- Form_LostFocus、Form_GotFocus是指的是一個MDI主父窗體呼叫了多個子窗體,當這些子窗體之間切換時,就觸發這兩個事件;當一個窗體中的多個文字框,滑鼠點選另一個文字框時,也會觸發這兩個此事件,文字框在 Windows內部實際上也是一個視窗。 

---- Windows內部是通過訊息來觸發事件的,這兩個事件在Windows內部對應的訊息是WM_NCACTIVATE,當該訊息的wParam為0時表示是失去焦點,為非0時表示得到焦點。在模組中: 


Public Declare Function SetWindowLong Lib 
"user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, 
ByVal dwNewLong As Long) As Long 

Public Declare Function DefWindowProc Lib 
"user32" Alias "DefWindowProcA"_
(ByVal hwnd As Long, ByVal wMsg As Long,
ByVal wParam As Integer, ByVal_
lParam As Long) As Long 


Public Declare Function CallWindowProc Lib
"user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, 
ByVal Msg As Long, ByVal _
wParam As Long, ByVal lParam As Long) As Long 

Public Const WM_NCACTIVATE = &H86 
Public Const GWL_WNDPROC = (-4) 
Public OldWndProc& 

Public Function Hook&(ByVal hWnd1&) 

OldWndProc = SetWindowLong(hWnd1,
GWL_WNDPROC, AddressOf NewWndProc) 
Hook = OldWndProc 
End Function 

Public Sub UnHook(ByVal hWnd1&) 
SetWindowLong hWnd1, GWL_WNDPROC, OldWndProc 
End Sub 

Public Function NewWndProc&(ByVal hWnd1&, ByVal uMsg&,
ByVal wParam&, ByVal lParam&) 
If uMsg = WM_NCACTIVATE Then 
   If wParam = 0 Then ’失去焦點
      Form1.Caption = "失去焦點" 
       註釋:在這裡加入在失去焦點時想要執行的程式碼
   Else
              Form1.Caption = "得到焦點"  
        ’在這裡加入在得到焦點時想要執行的程式碼
   End If 
End If 
NewWndProc = CallWindowProc(OldWndProc, 
hWnd1, uMsg, wParam, lParam) 
End Function 

視窗中程式碼如下: 

Private Sub Form_Load() 
Hook Form1.hwnd 
End Sub 

Private Sub Form_QueryUnload(Cancel As Integer,
UnloadMode As Integer) 
UnHook Form1.hwnd 
End Sub 

---- 注意:在編寫“失去焦點”和“得到焦點”的程式碼時,不要使用VB本身自帶的函式,如: MsgBox()和Print()等,因為這裡不支援,要用MessageBox()、TextOut()等API函式來代替,否則VB會出現“非法保護性錯誤”而把VB連帶程式一起關掉。