Close form if no user action including mouse move over form.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Rob

    Close form if no user action including mouse move over form.

    This is a curious problem. It seems like it should be quite easy. Of course
    a timer is used to determine when form should be closed, but how do you
    consistently reset the timer when the mouse is moved over the form.

    Normally I would use the MouseMove event to know when the mouse moves over
    the form and use that to reset the timer. However, this fails on a form that
    has a large number of controls of the form. The Form.MouseMove event will
    not fire when the pointer is over a control on the form! Therefore in the
    past I built recursive routine to go through the control collections of form
    controls and recurse when a container is discovered in the controls
    collection. Then for each control found an handler is set for MouseMove to a
    method that resets the timer and keeps the form open.

    This works but it doesn't seem very graceful. I was wondering if there is
    more graceful way to do the same job.

    Any help on this is appreciated.

    Rob
  • tommaso.gastaldi@uniroma1.it

    #2
    Re: Close form if no user action including mouse move over form.

    Hi Rob,

    see if this can be a way:

    Private WithEvents t As New Timer
    Private OldMousePos As Point

    Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
    System.EventArg s) Handles MyBase.Load
    t.Interval = 100
    t.Start()
    End Sub

    Private Sub t_Tick(ByVal sender As Object, ByVal e As
    System.EventArg s) Handles t.Tick
    If Not Me.Cursor.Posit ion.Equals(OldM ousePos) Then
    Me.GlobalMouseM ove(Me, EventArgs.Empty )
    Me.OldMousePos = Me.Cursor.Posit ion
    End Sub

    'Here do your reset
    Sub GlobalMouseMove (ByVal sender As Object, ByVal EventArgs As
    EventArgs)
    Me.Text = Cursor.Position .X.ToString & "," & _
    Cursor.Position .Y.ToString
    End Sub


    Not sure it's really graceful.

    -tom


    Rob ha scritto:
    [color=blue]
    > This is a curious problem. It seems like it should be quite easy. Of course
    > a timer is used to determine when form should be closed, but how do you
    > consistently reset the timer when the mouse is moved over the form.
    >
    > Normally I would use the MouseMove event to know when the mouse moves over
    > the form and use that to reset the timer. However, this fails on a form that
    > has a large number of controls of the form. The Form.MouseMove event will
    > not fire when the pointer is over a control on the form! Therefore in the
    > past I built recursive routine to go through the control collections of form
    > controls and recurse when a container is discovered in the controls
    > collection. Then for each control found an handler is set for MouseMove to a
    > method that resets the timer and keeps the form open.
    >
    > This works but it doesn't seem very graceful. I was wondering if there is
    > more graceful way to do the same job.
    >
    > Any help on this is appreciated.
    >
    > Rob[/color]

    Comment

    • gene kelley

      #3
      Re: Close form if no user action including mouse move over form.

      On Mon, 5 Jun 2006 10:52:01 -0700, Rob <Rob@discussion s.microsoft.com >
      wrote:
      [color=blue]
      >This is a curious problem. It seems like it should be quite easy. Of course
      >a timer is used to determine when form should be closed, but how do you
      >consistently reset the timer when the mouse is moved over the form.
      >
      >Normally I would use the MouseMove event to know when the mouse moves over
      >the form and use that to reset the timer. However, this fails on a form that
      >has a large number of controls of the form. The Form.MouseMove event will
      >not fire when the pointer is over a control on the form! Therefore in the
      >past I built recursive routine to go through the control collections of form
      >controls and recurse when a container is discovered in the controls
      >collection. Then for each control found an handler is set for MouseMove to a
      >method that resets the timer and keeps the form open.
      >
      >This works but it doesn't seem very graceful. I was wondering if there is
      >more graceful way to do the same job.
      >
      >Any help on this is appreciated.
      >
      >Rob[/color]


      (VB2005)

      It's not clear if you are talking about a particular form in your app
      or the app itself. If the app, then you can use the Application.Idl e
      method which will fire when either a long process is complete or the
      mouse is not moving - which ever occurs last. Scope of mouse move
      detection in this method is application wide without regard to any
      particular form or controls.

      Gene



      Comment

      • Cor Ligthert [MVP]

        #4
        Re: Close form if no user action including mouse move over form.

        Yea,

        Great (it is in my idea not complete, but the idea)
        I was thinking about the hover event, but that would eat much processing.
        Your sample does that not.
        The only time it could go wrong is if the x and y would be the same; A
        chance of 1 in a billion probably.

        Cor

        <tommaso.gastal di@uniroma1.it> schreef in bericht
        news:1149545352 .654411.280120@ c74g2000cwc.goo glegroups.com.. .[color=blue]
        > Hi Rob,
        >
        > see if this can be a way:
        >
        > Private WithEvents t As New Timer
        > Private OldMousePos As Point
        >
        > Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
        > System.EventArg s) Handles MyBase.Load
        > t.Interval = 100
        > t.Start()
        > End Sub
        >
        > Private Sub t_Tick(ByVal sender As Object, ByVal e As
        > System.EventArg s) Handles t.Tick
        > If Not Me.Cursor.Posit ion.Equals(OldM ousePos) Then
        > Me.GlobalMouseM ove(Me, EventArgs.Empty )
        > Me.OldMousePos = Me.Cursor.Posit ion
        > End Sub
        >
        > 'Here do your reset
        > Sub GlobalMouseMove (ByVal sender As Object, ByVal EventArgs As
        > EventArgs)
        > Me.Text = Cursor.Position .X.ToString & "," & _
        > Cursor.Position .Y.ToString
        > End Sub
        >
        >
        > Not sure it's really graceful.
        >
        > -tom
        >
        >
        > Rob ha scritto:
        >[color=green]
        >> This is a curious problem. It seems like it should be quite easy. Of
        >> course
        >> a timer is used to determine when form should be closed, but how do you
        >> consistently reset the timer when the mouse is moved over the form.
        >>
        >> Normally I would use the MouseMove event to know when the mouse moves
        >> over
        >> the form and use that to reset the timer. However, this fails on a form
        >> that
        >> has a large number of controls of the form. The Form.MouseMove event
        >> will
        >> not fire when the pointer is over a control on the form! Therefore in
        >> the
        >> past I built recursive routine to go through the control collections of
        >> form
        >> controls and recurse when a container is discovered in the controls
        >> collection. Then for each control found an handler is set for MouseMove
        >> to a
        >> method that resets the timer and keeps the form open.
        >>
        >> This works but it doesn't seem very graceful. I was wondering if there
        >> is
        >> more graceful way to do the same job.
        >>
        >> Any help on this is appreciated.
        >>
        >> Rob[/color]
        >[/color]


        Comment

        • tommaso.gastaldi@uniroma1.it

          #5
          Re: Close form if no user action including mouse move over form.


          Good idea Gene,

          .... but ... tried it and I must be missing something because does not
          seem to work as we expect (?).

          Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
          System.EventArg s) Handles MyBase.Load
          AddHandler Application.Idl e, AddressOf TimeReset
          End Sub

          Sub TimeReset(ByVal sender As Object, ByVal e As System.EventArg s)
          MsgBox("Reset now")
          End Sub

          Cor, to move the mouse returning exactly to the same start position
          within 1/100th of a second would take an enormous speed and incredible
          precision :) Anyway your observation make me think about a situation
          where the PC is a placed on a noisy place of work where there could be
          "vibrations " which make move the mouse slightly. In such a case the
          application is essentially idle, but since the vibrations make the
          mouse move, it does not appear so. I would be interesting to study an
          algorithm which redefines what "idle" means for noisy places ! :)





          gene kelley ha scritto:
          [color=blue]
          > On Mon, 5 Jun 2006 10:52:01 -0700, Rob <Rob@discussion s.microsoft.com >
          > wrote:
          >[color=green]
          > >This is a curious problem. It seems like it should be quite easy. Of course
          > >a timer is used to determine when form should be closed, but how do you
          > >consistently reset the timer when the mouse is moved over the form.
          > >
          > >Normally I would use the MouseMove event to know when the mouse moves over
          > >the form and use that to reset the timer. However, this fails on a form that
          > >has a large number of controls of the form. The Form.MouseMove event will
          > >not fire when the pointer is over a control on the form! Therefore in the
          > >past I built recursive routine to go through the control collections of form
          > >controls and recurse when a container is discovered in the controls
          > >collection. Then for each control found an handler is set for MouseMove to a
          > >method that resets the timer and keeps the form open.
          > >
          > >This works but it doesn't seem very graceful. I was wondering if there is
          > >more graceful way to do the same job.
          > >
          > >Any help on this is appreciated.
          > >
          > >Rob[/color]
          >
          >
          > (VB2005)
          >
          > It's not clear if you are talking about a particular form in your app
          > or the app itself. If the app, then you can use the Application.Idl e
          > method which will fire when either a long process is complete or the
          > mouse is not moving - which ever occurs last. Scope of mouse move
          > detection in this method is application wide without regard to any
          > particular form or controls.
          >
          > Gene[/color]

          Comment

          • gene kelley

            #6
            Re: Close form if no user action including mouse move over form.

            On 6 Jun 2006 03:19:10 -0700, tommaso.gastald i@uniroma1.it wrote:
            [color=blue]
            >
            >Good idea Gene,
            >
            >... but ... tried it and I must be missing something because does not
            >seem to work as we expect (?).
            >
            > Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
            >System.EventAr gs) Handles MyBase.Load
            > AddHandler Application.Idl e, AddressOf TimeReset
            > End Sub
            >
            > Sub TimeReset(ByVal sender As Object, ByVal e As System.EventArg s)
            > MsgBox("Reset now")
            > End Sub
            >
            >[/color]

            The above code in a simple app would result in a perpetual message box
            and no way to exit the app.

            This simple example works here using a timer component. If you simply
            run the example, the message box displays after 5 seconds. If you run
            the example and move the mouse before 5 seconds has elapsed, the timer
            restarts.

            Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
            System.EventArg s) Handles MyBase.Load
            AddHandler Application.Idl e, AddressOf TimeReset
            Me.Timer1.Inter val = 5000

            End Sub


            Sub TimeReset(ByVal sender As Object, ByVal e As System.EventArg s)
            'Start/'Restart the timer
            Me.Timer1.Enabl ed = False
            Me.Timer1.Enabl ed = True

            End Sub

            Private Sub Timer1_Tick(ByV al sender As Object, ByVal e As
            System.EventArg s) Handles Timer1.Tick
            Me.Timer1.Enabl ed = False
            MessageBox.Show ("App has been idle for 5 seconds. App
            closing.")
            Me.Close()
            End Sub


            Gene

            Comment

            • tommaso.gastaldi@uniroma1.it

              #7
              Re: Close form if no user action including mouse move over form.

              Thank you Gene. Now I understand how the idle event works. Good to know
              it. Thanks!

              -tommaso

              gene kelley ha scritto:
              [color=blue]
              > On 6 Jun 2006 03:19:10 -0700, tommaso.gastald i@uniroma1.it wrote:
              >[color=green]
              > >
              > >Good idea Gene,
              > >
              > >... but ... tried it and I must be missing something because does not
              > >seem to work as we expect (?).
              > >
              > > Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
              > >System.EventAr gs) Handles MyBase.Load
              > > AddHandler Application.Idl e, AddressOf TimeReset
              > > End Sub
              > >
              > > Sub TimeReset(ByVal sender As Object, ByVal e As System.EventArg s)
              > > MsgBox("Reset now")
              > > End Sub
              > >
              > >[/color]
              >
              > The above code in a simple app would result in a perpetual message box
              > and no way to exit the app.
              >
              > This simple example works here using a timer component. If you simply
              > run the example, the message box displays after 5 seconds. If you run
              > the example and move the mouse before 5 seconds has elapsed, the timer
              > restarts.
              >
              > Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
              > System.EventArg s) Handles MyBase.Load
              > AddHandler Application.Idl e, AddressOf TimeReset
              > Me.Timer1.Inter val = 5000
              >
              > End Sub
              >
              >
              > Sub TimeReset(ByVal sender As Object, ByVal e As System.EventArg s)
              > 'Start/'Restart the timer
              > Me.Timer1.Enabl ed = False
              > Me.Timer1.Enabl ed = True
              >
              > End Sub
              >
              > Private Sub Timer1_Tick(ByV al sender As Object, ByVal e As
              > System.EventArg s) Handles Timer1.Tick
              > Me.Timer1.Enabl ed = False
              > MessageBox.Show ("App has been idle for 5 seconds. App
              > closing.")
              > Me.Close()
              > End Sub
              >
              >
              > Gene[/color]

              Comment

              Working...