|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Make application sleepa 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(AddressOf AppSleep) Sub AppSleep() Do Thread.Sleep(500) Loop End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 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.WriteLine(s) If s.Substring(0, 1) = "{" Then s = s.Substring(1, s.Length - 2) Dim myArray() As String = Split(s, ",", , CompareMethod.Text) 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 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. Show quoteHide quote "Morten Snedker" <morten_spammenot_ATdbconsult.dk> wrote in message news:7arri2dqvf1gtljjumsvbngpdn5tb0f8pm@4ax.com... >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(AddressOf AppSleep) > > Sub AppSleep() > Do > Thread.Sleep(500) > Loop > End Sub > > Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As > System.EventArgs) 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.WriteLine(s) > > If s.Substring(0, 1) = "{" Then > s = s.Substring(1, s.Length - 2) > Dim myArray() As String = Split(s, ",", , > CompareMethod.Text) > > 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 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(500) 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: Show quoteHide quote > 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(AddressOf AppSleep) > > Sub AppSleep() > Do > Thread.Sleep(500) > Loop > End Sub > > Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As > System.EventArgs) 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.WriteLine(s) > > If s.Substring(0, 1) = "{" Then > s = s.Substring(1, s.Length - 2) > Dim myArray() As String = Split(s, ",", , > CompareMethod.Text) > > 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 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. On 12 Oct 2006 03:11:54 -0700, tesla***@hotmail.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.Threading Imports System.IO Public Class Form1 Public TextInput As String = "" Public PosX As Integer, PosY As Integer Dim thSleep As New Thread(AddressOf 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(vbNullString, "Lommeregner") Private Declare Function GetForegroundWindow _ Lib "user32" () As IntPtr Private Declare Function SetForegroundWindow _ Lib "user32" (ByVal hWnd As IntPtr) As Boolean Private Declare Function GetWindowThreadProcessId _ Lib "user32" (ByVal hWnd As IntPtr, _ ByVal lpdwProcessId As IntPtr) As Integer Private Declare Function AttachThreadInput _ Lib "user32" (ByVal idAttach As Integer, _ ByVal idAttachTo As Integer, ByVal fAttach As Boolean _ ) As Boolean Private Declare Function FindWindow _ Lib "user32" Alias "FindWindowA" (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 "SendMessageA" _ (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 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.WriteLine(s) If s.Substring(0, 1) = "{" Then s = s.Substring(1, s.Length - 2) Dim myArray() As String = Split(s, ",", , CompareMethod.Text) PosX = myArray(0) PosY = myArray(1) ClickPosition() Thread.Sleep(500) Else 'TextInput = s 'WriteText() 'Thread.Sleep(500) 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.Cursor.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.SendWait(TextInput) End Sub End Class '--code end Regards /Snedker Morten Snedker wrote:
> The third click should click somewhat above the the now unfolded list What if the position of Notepad in the start menu changes? What if the> above the the Start-button and hit Notepad. 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? On 12 Oct 2006 06:27:09 -0700, "Chris Dunaway" <dunaw***@gmail.com> Not an issue - the described situation is just for test. Just to seewrote: >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? it work. >What are you trying to accomplish? Just starting Notepad (or some Notepad is just an example. The end-purpose is to make flexible>other app?) Why not use the Process class to start notepad directly? 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 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.SendWait(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. Show quoteHide quote "Morten Snedker" <morten_spammenot_ATdbconsult.dk> wrote in message news:dkbsi218ov4g0hotsfj1i3os3fpv9lgosa@4ax.com... > On 12 Oct 2006 03:11:54 -0700, tesla***@hotmail.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.Threading > Imports System.IO > Public Class Form1 > > Public TextInput As String = "" > Public PosX As Integer, PosY As Integer > > Dim thSleep As New Thread(AddressOf 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(vbNullString, "Lommeregner") > > Private Declare Function GetForegroundWindow _ > Lib "user32" () As IntPtr > Private Declare Function SetForegroundWindow _ > Lib "user32" (ByVal hWnd As IntPtr) As Boolean > Private Declare Function GetWindowThreadProcessId _ > Lib "user32" (ByVal hWnd As IntPtr, _ > ByVal lpdwProcessId As IntPtr) As Integer > Private Declare Function AttachThreadInput _ > Lib "user32" (ByVal idAttach As Integer, _ > ByVal idAttachTo As Integer, ByVal fAttach As Boolean _ > ) As Boolean > Private Declare Function FindWindow _ > Lib "user32" Alias "FindWindowA" (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 "SendMessageA" _ > (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal > wParam As Integer, ByVal lParam As Integer) As Integer > > Private Sub Button1_Click(ByVal sender As System.Object, ByVal e > As System.EventArgs) 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.WriteLine(s) > > If s.Substring(0, 1) = "{" Then > s = s.Substring(1, s.Length - 2) > Dim myArray() As String = Split(s, ",", , > CompareMethod.Text) > PosX = myArray(0) > PosY = myArray(1) > > ClickPosition() > Thread.Sleep(500) > Else > 'TextInput = s > 'WriteText() > 'Thread.Sleep(500) > 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.Cursor.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.SendWait(TextInput) > End Sub > > End Class > '--code end > > Regards /Snedker On Thu, 12 Oct 2006 14:48:07 +0100, "NickP" <a@a.com> wrote: Initially that's what I had. Just found it more convenient to have>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.SendWait(iTextInput) > End Sub just one variable...but I agree. > Same goes for your click method, I would create a parameter for the Aha. That indeed may be where I'm going wrong. But if I send a>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. doubleclick to an Excel-shortcut on the desktop, still Excel doesn't open...? Thanks for input. Regards /Snedker 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_LEFTDOWN = &H2 Const MOUSEEVENTF_LEFTUP = &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.Cursor.Position = pt mouse_event(MOUSEEVENTF_LEFTDOWN + MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) End Sub Want a double-click? Just issue that mouse_event twice, back to back, no delay necessary. On 12 Oct 2006 07:27:38 -0700, tesla***@hotmail.com wrote:
Show quoteHide quote >Sigh. I apologize for my poor newsgroup behaviour. I _will_ improve in the> >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. :) future! :-) Show quoteHide quote >This will work just fine on your minimize button, start menu, shortcut, That all did the trick. >and whatever else you throw at it: > >Const MOUSEEVENTF_LEFTDOWN = &H2 >Const MOUSEEVENTF_LEFTUP = &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.Cursor.Position = pt > > mouse_event(MOUSEEVENTF_LEFTDOWN + MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) >End Sub > >Want a double-click? Just issue that mouse_event twice, back to back, >no delay necessary. 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 Morten Snedker wrote:
> Thank you for helping me out. =B-) Sure thing. Your colleague is gonna looove you. :)Dear Mr. Snedker,
> The idea is to move to each position and perform a click. In my case If you want to minimize windows, then maybe you would like to use this> the first position should minimize any foremost underlying > application. method (which minimizes ALL visible windows, taken from http://groups.google.com/group/microsoft.public.vb.winapi/tree/browse_frm/thread/5c87c565a02eb525/26f09645b8f1219e?rnum=1&q=vb+minimize+windows&_done=%2Fgroup%2Fmicrosoft.public.vb.winapi%2Fbrowse_frm%2Fthread%2F5c87c565a02eb525%2F4cbafa5ecf39b93a%3Flnk%3Dst%26q%3Dvb+minimize+windows%26rnum%3D3%26#doc_050a39c3d24b89a3): 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 "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32 Private Declare Function SendMessage Lib "USER32" Alias "SendMessageA" (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("Shell_TrayWnd", Chr(0)) r = SendMessage(TrayHandle, WM_COMMAND, MIN_ALL, 0&) 'Restore all windows r = SendMessage(TrayHandle, WM_COMMAND, MIN_ALL_UNDO, 0&) Best Regards, HKSHK
Check for .NET Installed
file transfer help? What .NET classes are SLOW vs. API? anyway to unload the dll mp3 synchronised lyrics Programmatically Find All Registry Entries Bitmap to JPEG with compression settings ToolStripMenuItem Possible bug in VS2005 Design View when using an ASP:Panel to show/hide groups of <tr>'s Check for .NET Installed |
|||||||||||||||||||||||