开发者

Put code inside a loop to exit the loop after any mouse click

On a Userform, I'm blinking a frame Off/On by toggling its visiblity. It blinks a variable number of times and then stops, but in between blinks it checks for user activity. If there has been a mouse click anywhere on the form or on any of the contained controls then the blinking stops immediately.

This is what my blinker looks like.

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

Everything works fine except for the <click detected> part. How do I do that from inside the 开发者_如何学Goloop?


Did you tried to change a global boolean variable on the mouseclick event to true (default false)?

Then try to check if this global boolean variable is true in <click detected>.


This seems to work ok, but it looks like a lot of code just to detect a mouse click. For instance, I thought it should be possible to create a Class that contains all the Form Controls, so I could detect a click on any of them in one go, without having to check on each kind of control separately. I couldn't make that work and I'm hoping somebody can improve on this.

Just to restate what this does: On a Userform, a large frame named mapFrame holds any number of other frames and labels, and all those contained frames can hold any number of other frames and labels, but that's as deep as the nesting goes. I want to start a loop, (in this case the loop blinks a control off and on, but it could be any other loop) and wait for the user to click on any of the contained Frames or Labels to signal an exit from the loop. I also want to get the name of the control that was clicked.

I took the suggestion by therealmarv and used the click to set a public Boolean which gets tested inside the loop.

In a new Class Module:

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

In another new Class Module:

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

In a Form Module:

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜