2009-11-16 80 views
0

我有一個窗體,就像一個下拉菜單,它顯示非模態。我在表單上附加了一個鼠標鉤,以確定鼠標何時被點擊,以便我知道關閉它 - 通過設置Visible = False。因爲我想HookProc來處理最後一次點擊,我不能處置Hook或我的下拉列表,直到我確定我的事件處理程序已返回到HookProc。確定鼠標鉤何時處理了最後一條消息

這是一個有點難以解釋,但我希望下面的代碼使其更清晰一點: -

//Loop to display the dropdown. 
Dim dd as New DropDown 
dd.Visible = True 
Do While dd.Visible 
    Application.DoEvents() 
    NativeMethods.MsgWaitForMultipleObjectsEx(0, IntPtr.Zero, 250, &HFF, 4) 
Loop 
// I want to dispose dd now, but how can I be sure that e.Handled (See below) 
// has been returned to HookProc? 

//A handler within dropdown to determine what to do with the mouse click. 
Private Sub DropDown_MouseHookClick(ByVal sender As Object, ByVal e As MouseClickEventArgs) 
    If IWantToCloseTheDropDown Then 
     e.Handled = True 
     MyHook.UnHook 
     Me.Visible = False 
    End If 
    // All done, e.Handled is returned to HookProc. 
    // But which happens first? Will e.Handled arrive at HookProc first, or will 
    // the form display loop, above, notice that Visible is now False? 
End Sub 

//The main part of the hooking class. 
Public Function MouseHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer 
    Dim MyMouseHookStruct As MouseHookStruct = DirectCast(Marshal.PtrToStructure(lParam, GetType(MouseHookStruct)), MouseHookStruct) 
    If nCode < 0 Then 
     Return CallNextHookEx(hHook, nCode, wParam, lParam) 
    Else 
     Dim handle As Integer = MyMouseHookStruct.hwnd 
     Dim c As Control = Control.FromHandle(New IntPtr(handle)) 
     If MouseUpOrDown Then 
      Dim e As MouseHookClickEventArgs 
      OnMouseClick(e) 
      If e.Handled Then 
       Return 1 
      EndIf 
     End If 
     Return CallNextHookEx(hHook, nCode, wParam, lParam) 
    End If 
End Function 

回答

0

爲什麼不直接處理的焦點事件? Form_LostFocus會告訴你他們何時關注另一個控件/表單。此時你可以隱藏你的表格。

鼠標鉤看起來像矯枉過正,用於檢測表單是否有焦點。

+0

我用鼠標鉤子,因爲有兩種方式下拉可剩下。一個是通過點擊它(在這種情況下,我希望它關閉)。另一種情況是,如果物業網格(它所在的並且我有限的控制權)打開另一個表單 - 即類型編輯器(TypeEditor)。在這種情況下,我不想關閉我的下拉菜單。 – Jules 2009-11-24 08:52:43

+0

您可能能夠處理PropertyGrid上的PropertyValueChanged事件,並在該特定值發生更改(使用TypeEditor的那個值)更改時重新打開下拉菜單。如果事件觸發,則對話框關閉,您可以再次打開下拉菜單。 – 2009-12-01 18:33:18

0

您繞過.NET的機制來處理窗口事件

你不應該需要什麼本地處理的WinForms。另外,整個代碼回收垃圾,所以你不應該再擔心刪除的鉤

你可能想看看form.deactivate事件