Make application sleep

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

    #1

    Make application sleep

    I open a file for input. Each line is handled individually. Every time
    a line has been handled I wish to wait for ½ second before reading the
    next. Am I doing it right or wrong ? (I think it's wrong):


    Dim thSleep As New Thread(AddressO f AppSleep)

    Sub AppSleep()
    Do
    Thread.Sleep(50 0)
    Loop
    End Sub

    Private Sub Button1_Click(B yVal sender As System.Object, ByVal e As
    System.EventArg s) Handles Button1.Click

    Dim sr As StreamReader = New StreamReader("d :\test.txt")
    Dim s As String = ""

    Do While sr.Peek() >= 0
    s = sr.ReadLine()
    Console.WriteLi ne(s)

    If s.Substring(0, 1) = "{" Then
    s = s.Substring(1, s.Length - 2)
    Dim myArray() As String = Split(s, ",", ,
    CompareMethod.T ext)

    ClickPosition()
    AppSleep()

    Else
    TextInput = s
    WriteText()
    AppSleep()
    End If

    Loop

    sr.Close()
    sr.Dispose()

    End Sub

    The essense is that for each line either a mouse click og textline i
    send to another application. For each click/text I wish for the
    application to "absorb" it.

    Regards /Snedker
  • Stephany Young

    #2
    Re: Make application sleep

    Ummmmmmmm ... It's very wrong.

    The first time you call AppSleep, your UI thread will go to sleep and never
    wake up again because of the Do ... Loop.



    "Morten Snedker" <morten_spammen ot_ATdbconsult. dkwrote in message
    news:7arri2dqvf 1gtljjumsvbngpd n5tb0f8pm@4ax.c om...
    >I open a file for input. Each line is handled individually. Every time
    a line has been handled I wish to wait for ½ second before reading the
    next. Am I doing it right or wrong ? (I think it's wrong):
    >
    >
    Dim thSleep As New Thread(AddressO f AppSleep)
    >
    Sub AppSleep()
    Do
    Thread.Sleep(50 0)
    Loop
    End Sub
    >
    Private Sub Button1_Click(B yVal sender As System.Object, ByVal e As
    System.EventArg s) Handles Button1.Click
    >
    Dim sr As StreamReader = New StreamReader("d :\test.txt")
    Dim s As String = ""
    >
    Do While sr.Peek() >= 0
    s = sr.ReadLine()
    Console.WriteLi ne(s)
    >
    If s.Substring(0, 1) = "{" Then
    s = s.Substring(1, s.Length - 2)
    Dim myArray() As String = Split(s, ",", ,
    CompareMethod.T ext)
    >
    ClickPosition()
    AppSleep()
    >
    Else
    TextInput = s
    WriteText()
    AppSleep()
    End If
    >
    Loop
    >
    sr.Close()
    sr.Dispose()
    >
    End Sub
    >
    The essense is that for each line either a mouse click og textline i
    send to another application. For each click/text I wish for the
    application to "absorb" it.
    >
    Regards /Snedker

    Comment

    • HKSHK

      #3
      Re: Make application sleep

      Dear Mr. Snedker,

      As I see it your sub AppSleep is an eternal loop, because you didn't set
      any condition on how to end it. So it will sleep again and again and
      again and ...

      So, make AppSleep look like this:

      Sub AppSleep()
      Thread.Sleep(50 0)
      End Sub

      Apart from that, there is the problem that the sending application
      (sender) does not know if the string was processed or not. Depending on
      the situation (maybe Windows is swapping or very busy) 500 ms might not
      be enough. If you send the next string already, the processing order
      might be that the second string is processed first. This might be a
      problem if the order of the strings is important.

      Perhaps another method might be better (but it would only work if you
      have access to the sources of both applications):

      Implement a status message into both programs. This could e.g. be done
      by creating a status file (or a named pipe).

      The receiver creates a status file (and if you like returns a status
      message e.g. OK or error message). The sender then checks if the file
      exists.

      a) If the file exists and you implemented the OK/error message it opens
      it and checks if the transaction was OK or an error occurred. If OK,
      then the sender deletes the file and sends the next string otherwise
      handle the error.

      OR

      b) If the file exists the sender deletes the file and sends the next string.

      Best Regards,

      HKSHK


      Morten Snedker wrote:
      I open a file for input. Each line is handled individually. Every time
      a line has been handled I wish to wait for ½ second before reading the
      next. Am I doing it right or wrong ? (I think it's wrong):
      >
      >
      Dim thSleep As New Thread(AddressO f AppSleep)
      >
      Sub AppSleep()
      Do
      Thread.Sleep(50 0)
      Loop
      End Sub
      >
      Private Sub Button1_Click(B yVal sender As System.Object, ByVal e As
      System.EventArg s) Handles Button1.Click
      >
      Dim sr As StreamReader = New StreamReader("d :\test.txt")
      Dim s As String = ""
      >
      Do While sr.Peek() >= 0
      s = sr.ReadLine()
      Console.WriteLi ne(s)
      >
      If s.Substring(0, 1) = "{" Then
      s = s.Substring(1, s.Length - 2)
      Dim myArray() As String = Split(s, ",", ,
      CompareMethod.T ext)
      >
      ClickPosition()
      AppSleep()
      >
      Else
      TextInput = s
      WriteText()
      AppSleep()
      End If
      >
      Loop
      >
      sr.Close()
      sr.Dispose()
      >
      End Sub
      >
      The essense is that for each line either a mouse click og textline i
      send to another application. For each click/text I wish for the
      application to "absorb" it.
      >
      Regards /Snedker

      Comment

      • teslar91@hotmail.com

        #4
        Re: Make application sleep

        As the others said, and:

        If you're using PostMessage as we recently discussed in your
        ClickPosition() , you might want to use SendMessage instead - it waits
        until the app processes the message before returning. Might help
        reduce/eliminate the need for Sleep and speed things up.

        Comment

        • Morten Snedker

          #5
          Re: Make application sleep

          On 12 Oct 2006 03:11:54 -0700, teslar91@hotmai l.com wrote:


          Thanks to all of you guys for your help and efforts. I've given
          SendMessage a go, but it still won't do (entirely).

          My test.txt contains:
          {1221,12}
          {50,980}
          {70,867}

          The idea is to move to each position and perform a click. In my case
          the first position should minimize any foremost underlying
          application.

          Second click hits the Win-XP Start-button.

          The third click should click somewhat above the the now unfolded list
          above the the Start-button and hit Notepad.

          In all three cases the mouse moves to the proper position.

          Though, the first click doesn't minimize the underlying application
          (that could be any maximized app).

          The second click performs well and unfolds the Start-button.

          The thirc click doesn't open the Notepad (even at the right position).

          Here is my full code:

          '--code begin
          Imports System.Windows. Forms
          Imports System.Threadin g
          Imports System.IO
          Public Class Form1

          Public TextInput As String = ""
          Public PosX As Integer, PosY As Integer

          Dim thSleep As New Thread(AddressO f ReadFile)

          #Region "Get window-name, Declares"
          Dim myVal1 As Integer
          Dim myVal2 As Integer

          Dim intHandle As IntPtr = FindWindow("[Class Name Here]",
          vbNullString)
          Dim intHandle2 As IntPtr = FindWindow(vbNu llString, "Lommeregne r")

          Private Declare Function GetForegroundWi ndow _
          Lib "user32" () As IntPtr
          Private Declare Function SetForegroundWi ndow _
          Lib "user32" (ByVal hWnd As IntPtr) As Boolean
          Private Declare Function GetWindowThread ProcessId _
          Lib "user32" (ByVal hWnd As IntPtr, _
          ByVal lpdwProcessId As IntPtr) As Integer
          Private Declare Function AttachThreadInp ut _
          Lib "user32" (ByVal idAttach As Integer, _
          ByVal idAttachTo As Integer, ByVal fAttach As Boolean _
          ) As Boolean
          Private Declare Function FindWindow _
          Lib "user32" Alias "FindWindow A" (ByVal lpClassName As String,
          _
          ByVal lpWindowName As String) As IntPtr
          #End Region

          Declare Auto Function WindowFromPoint Lib "user32" (ByVal xPoint
          As Integer, ByVal yPoint As Integer) As IntPtr
          Declare Function SendMessage Lib "user32" Alias "SendMessag eA" _
          (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal
          wParam As Integer, ByVal lParam As Integer) As Integer

          Private Sub Button1_Click(B yVal sender As System.Object, ByVal e
          As System.EventArg s) Handles Button1.Click
          Me.WindowState = FormWindowState .Minimized
          ReadFile()
          End Sub
          Sub ReadFile()

          Dim sr As StreamReader = New StreamReader("d :\test.txt")
          Dim s As String = ""

          Do While sr.Peek() >= 0
          s = sr.ReadLine()
          Console.WriteLi ne(s)

          If s.Substring(0, 1) = "{" Then
          s = s.Substring(1, s.Length - 2)
          Dim myArray() As String = Split(s, ",", ,
          CompareMethod.T ext)
          PosX = myArray(0)
          PosY = myArray(1)

          ClickPosition()
          Thread.Sleep(50 0)
          Else
          'TextInput = s
          'WriteText()
          'Thread.Sleep(5 00)
          End If
          Loop

          sr.Close()
          sr.Dispose()

          End Sub
          Sub ClickPosition()
          Dim wnd As IntPtr
          Dim pt As Point

          pt.X = PosX
          pt.Y = PosY
          Windows.Forms.C ursor.Position = pt

          Const WM_ACTIVATEAPP = &H1C
          Const WM_LBUTTONUP = &H202 '//LButton up
          Const WM_LBUTTONDOWN = &H201 '//LButton down

          wnd = WindowFromPoint (PosX, PosY)
          Call SendMessage(wnd , WM_ACTIVATEAPP, 0, 0)
          Call SendMessage(wnd , WM_LBUTTONDOWN, 0, 0)
          Call SendMessage(wnd , WM_LBUTTONUP, 0, 0)
          End Sub

          Sub WriteText()
          SendKeys.SendWa it(TextInput)
          End Sub

          End Class
          '--code end

          Regards /Snedker

          Comment

          • Chris Dunaway

            #6
            Re: Make application sleep

            Morten Snedker wrote:
            The third click should click somewhat above the the now unfolded list
            above the the Start-button and hit Notepad.
            What if the position of Notepad in the start menu changes? What if the
            machine the program is running on does not have Notepad in the start
            menu?

            What are you trying to accomplish? Just starting Notepad (or some
            other app?) Why not use the Process class to start notepad directly?

            Comment

            • NickP

              #7
              Re: Make application sleep

              Hi Morten,

              This won't really help with your app but I can see a few strange things
              going on there..

              When you call a method to operate on a variable it's best to send that
              variable to the method as a parameter, i.e.

              Sub WriteText(Byval iTextInput As String)
              SendKeys.SendWa it(iTextInput)
              End Sub

              That way SendKeys will always send each value. If the value of
              TextInput were to change after calling the method it would not act as
              expected.

              Same goes for your click method, I would create a parameter for the
              position to click, but this would be relative to the screen coordinates.
              You have to bare in mind that if you are obtaining the handle to a window
              and sending the click message to it then X, and Y will be relative to it's
              current location, so it might not even be clicking inside of it.

              BTW, what are you trying to achieve? Scripting clicking a few buttons I
              presume to remove something annoying from the screen? ;-)

              Nick.

              "Morten Snedker" <morten_spammen ot_ATdbconsult. dkwrote in message
              news:dkbsi218ov 4g0hotsfj1i3os3 fpv9lgosa@4ax.c om...
              On 12 Oct 2006 03:11:54 -0700, teslar91@hotmai l.com wrote:
              >
              >
              Thanks to all of you guys for your help and efforts. I've given
              SendMessage a go, but it still won't do (entirely).
              >
              My test.txt contains:
              {1221,12}
              {50,980}
              {70,867}
              >
              The idea is to move to each position and perform a click. In my case
              the first position should minimize any foremost underlying
              application.
              >
              Second click hits the Win-XP Start-button.
              >
              The third click should click somewhat above the the now unfolded list
              above the the Start-button and hit Notepad.
              >
              In all three cases the mouse moves to the proper position.
              >
              Though, the first click doesn't minimize the underlying application
              (that could be any maximized app).
              >
              The second click performs well and unfolds the Start-button.
              >
              The thirc click doesn't open the Notepad (even at the right position).
              >
              Here is my full code:
              >
              '--code begin
              Imports System.Windows. Forms
              Imports System.Threadin g
              Imports System.IO
              Public Class Form1
              >
              Public TextInput As String = ""
              Public PosX As Integer, PosY As Integer
              >
              Dim thSleep As New Thread(AddressO f ReadFile)
              >
              #Region "Get window-name, Declares"
              Dim myVal1 As Integer
              Dim myVal2 As Integer
              >
              Dim intHandle As IntPtr = FindWindow("[Class Name Here]",
              vbNullString)
              Dim intHandle2 As IntPtr = FindWindow(vbNu llString, "Lommeregne r")
              >
              Private Declare Function GetForegroundWi ndow _
              Lib "user32" () As IntPtr
              Private Declare Function SetForegroundWi ndow _
              Lib "user32" (ByVal hWnd As IntPtr) As Boolean
              Private Declare Function GetWindowThread ProcessId _
              Lib "user32" (ByVal hWnd As IntPtr, _
              ByVal lpdwProcessId As IntPtr) As Integer
              Private Declare Function AttachThreadInp ut _
              Lib "user32" (ByVal idAttach As Integer, _
              ByVal idAttachTo As Integer, ByVal fAttach As Boolean _
              ) As Boolean
              Private Declare Function FindWindow _
              Lib "user32" Alias "FindWindow A" (ByVal lpClassName As String,
              _
              ByVal lpWindowName As String) As IntPtr
              #End Region
              >
              Declare Auto Function WindowFromPoint Lib "user32" (ByVal xPoint
              As Integer, ByVal yPoint As Integer) As IntPtr
              Declare Function SendMessage Lib "user32" Alias "SendMessag eA" _
              (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal
              wParam As Integer, ByVal lParam As Integer) As Integer
              >
              Private Sub Button1_Click(B yVal sender As System.Object, ByVal e
              As System.EventArg s) Handles Button1.Click
              Me.WindowState = FormWindowState .Minimized
              ReadFile()
              End Sub
              Sub ReadFile()
              >
              Dim sr As StreamReader = New StreamReader("d :\test.txt")
              Dim s As String = ""
              >
              Do While sr.Peek() >= 0
              s = sr.ReadLine()
              Console.WriteLi ne(s)
              >
              If s.Substring(0, 1) = "{" Then
              s = s.Substring(1, s.Length - 2)
              Dim myArray() As String = Split(s, ",", ,
              CompareMethod.T ext)
              PosX = myArray(0)
              PosY = myArray(1)
              >
              ClickPosition()
              Thread.Sleep(50 0)
              Else
              'TextInput = s
              'WriteText()
              'Thread.Sleep(5 00)
              End If
              Loop
              >
              sr.Close()
              sr.Dispose()
              >
              End Sub
              Sub ClickPosition()
              Dim wnd As IntPtr
              Dim pt As Point
              >
              pt.X = PosX
              pt.Y = PosY
              Windows.Forms.C ursor.Position = pt
              >
              Const WM_ACTIVATEAPP = &H1C
              Const WM_LBUTTONUP = &H202 '//LButton up
              Const WM_LBUTTONDOWN = &H201 '//LButton down
              >
              wnd = WindowFromPoint (PosX, PosY)
              Call SendMessage(wnd , WM_ACTIVATEAPP, 0, 0)
              Call SendMessage(wnd , WM_LBUTTONDOWN, 0, 0)
              Call SendMessage(wnd , WM_LBUTTONUP, 0, 0)
              End Sub
              >
              Sub WriteText()
              SendKeys.SendWa it(TextInput)
              End Sub
              >
              End Class
              '--code end
              >
              Regards /Snedker

              Comment

              • Morten Snedker

                #8
                Re: Make application sleep

                On 12 Oct 2006 06:27:09 -0700, "Chris Dunaway" <dunawayc@gmail .com>
                wrote:
                >What if the position of Notepad in the start menu changes? What if the
                >machine the program is running on does not have Notepad in the start
                >menu?
                Not an issue - the described situation is just for test. Just to see
                it work.
                >What are you trying to accomplish? Just starting Notepad (or some
                >other app?) Why not use the Process class to start notepad directly?
                Notepad is just an example. The end-purpose is to make flexible
                navigation in any given program.

                The kickstart is my collegue who has a special application to make
                complicated calculations. That takes several clicks and input of data.
                Then it calculates for 5-6 minutes. That he sometimes does a hundred
                times - and it's a kiling job.

                So we wish for this application to take care of itself.

                Regards /Snedker

                Comment

                • Morten Snedker

                  #9
                  Re: Make application sleep

                  On Thu, 12 Oct 2006 14:48:07 +0100, "NickP" <a@a.comwrote :
                  >Hi Morten,
                  >
                  This won't really help with your app but I can see a few strange things
                  >going on there..
                  >
                  When you call a method to operate on a variable it's best to send that
                  >variable to the method as a parameter, i.e.
                  >
                  Sub WriteText(Byval iTextInput As String)
                  SendKeys.SendWa it(iTextInput)
                  End Sub
                  Initially that's what I had. Just found it more convenient to have
                  just one variable...but I agree.
                  Same goes for your click method, I would create a parameter for the
                  >position to click, but this would be relative to the screen coordinates.
                  >You have to bare in mind that if you are obtaining the handle to a window
                  >and sending the click message to it then X, and Y will be relative to it's
                  >current location, so it might not even be clicking inside of it.
                  Aha. That indeed may be where I'm going wrong. But if I send a
                  doubleclick to an Excel-shortcut on the desktop, still Excel doesn't
                  open...?

                  Thanks for input.

                  Regards /Snedker

                  Comment

                  • teslar91@hotmail.com

                    #10
                    Re: Make application sleep

                    Sigh.

                    In your thread "How to find my information", you inquired into a means
                    of simulating a mouse click *without* moving the mouse, which I
                    provided with a warning that not all controls respond uniformly. You
                    said you'd follow up in that thread if you had problems.

                    Instead, you started a new thread, "Trouble with mouse click", where
                    you posted code where you're *moving* the mouse, then using the
                    technique I provided for simulating a click *without moving* the mouse,
                    thus combining the disadvantages of both. There I advised you use the
                    more conventional, reliable method of simulating clicks if you were
                    going to move the mouse anyway, and provided code.

                    When you started this thread I wasn't sure if you'd seen my previous
                    response, but now that you've posted ClickPosition code, it appears
                    that you did not; if you had, it would be working already.

                    Seriously. One problem, one thread, makes things so much easier. :)

                    This will work just fine on your minimize button, start menu, shortcut,
                    and whatever else you throw at it:

                    Const MOUSEEVENTF_LEF TDOWN = &H2
                    Const MOUSEEVENTF_LEF TUP = &H4
                    Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Int32, ByVal dX
                    As Int32, ByVal dy As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo
                    As Int32)

                    Sub ClickPosition()
                    Dim wnd As IntPtr
                    Dim pt As Point

                    pt.X = PosX
                    pt.Y = PosY
                    Windows.Forms.C ursor.Position = pt

                    mouse_event(MOU SEEVENTF_LEFTDO WN + MOUSEEVENTF_LEF TUP, 0, 0, 0, 0)
                    End Sub

                    Want a double-click? Just issue that mouse_event twice, back to back,
                    no delay necessary.

                    Comment

                    • HKSHK

                      #11
                      Re: Make application sleep

                      Dear Mr. Snedker,
                      The idea is to move to each position and perform a click. In my case
                      the first position should minimize any foremost underlying
                      application.
                      If you want to minimize windows, then maybe you would like to use this
                      method (which minimizes ALL visible windows, taken from


                      Private Const WM_COMMAND As Int32 = &H111
                      Private Const MIN_ALL As Int32 = 419
                      Private Const MIN_ALL_UNDO As Int32 = 416

                      Private Declare Function FindWindow Lib "USER32" Alias "FindWindow A"
                      (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32

                      Private Declare Function SendMessage Lib "USER32" Alias "SendMessag eA"
                      (ByVal hWnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32,
                      lParam As Any) As Int32

                      '--------------------------


                      Dim TrayHandle as Int32, r As Int32

                      'Minimize all windows
                      TrayHandle = FindWindow("She ll_TrayWnd", Chr(0))
                      r = SendMessage(Tra yHandle, WM_COMMAND, MIN_ALL, 0&)



                      'Restore all windows
                      r = SendMessage(Tra yHandle, WM_COMMAND, MIN_ALL_UNDO, 0&)

                      Best Regards,

                      HKSHK

                      Comment

                      • Morten Snedker

                        #12
                        Re: Make application sleep

                        On 12 Oct 2006 07:27:38 -0700, teslar91@hotmai l.com wrote:
                        >Sigh.
                        >
                        >In your thread "How to find my information", you inquired into a means
                        >of simulating a mouse click *without* moving the mouse, which I
                        >provided with a warning that not all controls respond uniformly. You
                        >said you'd follow up in that thread if you had problems.
                        >
                        >Instead, you started a new thread, "Trouble with mouse click", where
                        >you posted code where you're *moving* the mouse, then using the
                        >technique I provided for simulating a click *without moving* the mouse,
                        >thus combining the disadvantages of both. There I advised you use the
                        >more conventional, reliable method of simulating clicks if you were
                        >going to move the mouse anyway, and provided code.
                        >
                        >When you started this thread I wasn't sure if you'd seen my previous
                        >response, but now that you've posted ClickPosition code, it appears
                        >that you did not; if you had, it would be working already.
                        >
                        >Seriously. One problem, one thread, makes things so much easier. :)
                        I apologize for my poor newsgroup behaviour. I _will_ improve in the
                        future! :-)
                        >This will work just fine on your minimize button, start menu, shortcut,
                        >and whatever else you throw at it:
                        >
                        >Const MOUSEEVENTF_LEF TDOWN = &H2
                        >Const MOUSEEVENTF_LEF TUP = &H4
                        >Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Int32, ByVal dX
                        >As Int32, ByVal dy As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo
                        >As Int32)
                        >
                        >Sub ClickPosition()
                        Dim wnd As IntPtr
                        Dim pt As Point
                        >
                        pt.X = PosX
                        pt.Y = PosY
                        Windows.Forms.C ursor.Position = pt
                        >
                        mouse_event(MOU SEEVENTF_LEFTDO WN + MOUSEEVENTF_LEF TUP, 0, 0, 0, 0)
                        >End Sub
                        >
                        >Want a double-click? Just issue that mouse_event twice, back to back,
                        >no delay necessary.
                        That all did the trick.

                        Although the solution seems simple I find reaching it difficult. Then
                        again, I haven't spend as much time with .Net as I'd like to, so I
                        guess it'll some bleeding knees before riding the bike.

                        Thank you for helping me out. =B-)


                        Regards /Snedker

                        Comment

                        • teslar91@hotmail.com

                          #13
                          Re: Make application sleep

                          Morten Snedker wrote:
                          Thank you for helping me out. =B-)
                          Sure thing. Your colleague is gonna looove you. :)

                          Comment

                          Working...