2011-08-13 53 views
2

在Userform上,通過切換其可見性來關閉/打開幀。它閃爍不定次數然後停止,但在閃爍之間它檢查用戶活動。如果在窗體的任何地方或任何包含的控件上點擊了鼠標,則閃爍立即停止。將代碼放到循環中以便在任何鼠標點擊後退出循環

這是我的blinker看起來像。

For i = 1 To numberOfBlinks 
    <blink twice> 
    DoEvents 
    If <click detected> Then Exit Sub 
    Next i 

一切工作正常,除了<click detected>部分。我如何從循環內部做到這一點?

+0

這聽起來像那些視力測試,其中的一個他們會要求您在出現特定數字時單擊鼠標:p – aevanko

+0

這是一個很好的問題。也許一個API函數設置觸發器什麼的。其實,期待一個很好的答案。順便說一句,您對第一個答案的評論也可能出現在您的問題中,我認爲要澄清這些問題。 – Oneide

回答

3

您是否嘗試將mouseclick事件的全局布爾變量更改爲true(默認爲false)?

然後嘗試檢查這個全局布爾變量在<click detected>中是否爲真。

+0

鼠標點擊可能在數百個控件中的任何一個上。我猜我必須使用類模塊來檢測點擊,但有沒有更簡單的方法?如果沒有,有人可以建議一個代碼片段來做到這一點嗎? – Roy

+0

您在Excel用戶窗體中確實擁有數百個控件? – ChandlerPelhams

+0

是的,我喜歡。大型的容器框架包含一張地圖,而百多個兒童控件則是地圖上的特徵。 – Roy

0

這似乎工作正常,但它看起來像很多代碼只是爲了檢測到鼠標點擊。例如,我認爲應該可以創建一個包含所有表單控件的類,這樣我就可以一次檢測到它們中的任何一個,而不必單獨檢查每種控件。我無法做到這一點,我希望有人能夠改善這一點。

只是爲了重申它做了什麼:在一個用戶窗體上,一個名爲mapFrame的大框架可以包含任意數量的其他框架和標籤,並且所有包含框架的框架可以包含任意數量的其他框架和標籤,但是與嵌套走。我想開始一個循環(在這種情況下,循環閃爍一個控制關閉和打開,但它可能是任何其他循環),並等待用戶點擊任何包含的幀或標籤來發出循環退出信號。我也想獲取被點擊的控件的名稱。

我採用了therealmarv的建議,並使用click來設置在循環內部進行測試的公共布爾值。

在一個新的類模塊:

Option Explicit 

Public WithEvents classLabels As msForms.Label 

Private Sub classLabels_Click() 
    clickedControlName = "" '<== Public String 
    With classLabels 
    If .Parent.Name = "mapFrame" Or _ 
     .Parent.Parent.Name = "mapFrame" Then 
     isClickDetected = True '<== Public Boolean 
     clickedControlName = .Name 
    End If 
    End With 
End Sub 

在另一個新的類模塊:

Option Explicit 

Public WithEvents classFrames As msForms.Frame 

Private Sub classFrames_Click() 
    clickedControlName = "" '<== Public String 
    With classFrames 
    If .Name = "mapFrame" Or _ 
     .Parent.Name = "mapFrame" Or _ 
     .Parent.Parent.Name = "mapFrame" Then 
     isClickDetected = True '<== Public Boolean 
     clickedControlName = .Name 
    End If 
    End With 
End Sub 

在窗體模塊:

Option Explicit 

Dim frames() As New clsFrames 
Dim labels() As New clsLabels 

Private Sub createFrameListeners() 
    Dim ctl As msForms.Control 
    Dim frameCount as Long 
    For Each ctl In Me.Controls 
    '  Debug.Print TypeName(ctl): Stop 
     If TypeName(ctl) = "Frame" Then 
     frameCount = frameCount + 1 
     ReDim Preserve frames(1 To frameCount) 
     'Create the Frame Listener objects 
     Set frames(frameCount).classFrames = ctl 
     End If 
    Next ctl 
End Sub 

Private Sub createLabelListeners() 
Dim ctl As msForms.Control 
Dim LabelCount as Long 
    For Each ctl In Me.Controls 
    '  Debug.Print TypeName(ctl): Stop 
    If TypeName(ctl) = "Label" Then 
     LabelCount = LabelCount + 1 
     ReDim Preserve labels(1 To LabelCount) 
     'Create the Label Listener objects 
     Set labels(LabelCount).classLabels = ctl 
    End If 
    Next ctl 
End Sub 

Function blinkThisControl(ctrl As Control, ByVal blinkCount As Long) 
    isClickDetected = False 
    Dim i As Integer 
    For i = 1 To blinkCount 

     ' <blink ctrl twice> 

     DoEvents 
     If isClickDetected Then Exit Function 
     'name of clicked control will be in clickedControlName 
    Next i 
End Function 

Private Sub userform_initialize() 
Call createFrameListeners 
Call createLabelListeners 

' do other stuff 


End Sub