locked
Form with periodically focus, Visual Basic 2008 RRS feed

  • Question

  • Hi,

    I periodically copy a web page with (Visual Basic 2008):

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

    Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)

    Private Const VK_CONTROL As Integer = &H11
    Private Const VK_C As Integer = &H43
    Private Const VK_A As Integer = &H41
    Private Const KEYEVENTF_KEYUP As Integer = &H2

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

    'activate Form, focus on the Form

    Me.Activate()

    'copy screen

    'Press Control

    keybd_event(VK_CONTROL, 0, 0, 0)
    ' Press A.
    keybd_event(VK_A, 1, 0, 0)
    ' Control-C.
    ' Press Control.
     keybd_event(VK_CONTROL, 0, 0, 0)
     ' Press C.
     keybd_event(VK_C, 1, 0, 0)
    ' Release Control.
    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0)

    If I work on another window, it's annoying to see the focus change.
    Is there a way to avoid this and keep the focus on the other work window?

    Thank you

    Friday, December 22, 2017 4:07 PM

Answers

  •   As i said before,  if you gave some better details,  we may well be able to suggest a better way to accomplish the end goal.  Maybe by using a WebBrowser control on your form,  or using a way to get the text directly from the website without copy/paste or a webbrowser even being involved.

      Just so you are aware,  it is never going to be reliable doing it by shifting the focused windows around and using a copy/paste method while trying to work in other windows.  If you are working in a window and just happen to click on something or press a key at the same time the code gets executed,  you are going to shift focus to the wrong window and the copy/paste is not going to copy what you want or is going to paste it somewhere you don't want it. There are many, many things that can go wrong with doing it this way.

     

     With that said,  this is a simple example that uses the GetForegroundWindow and SetForegroundWindow api functions to get the handle of the window that has focus,  sets focus to Firefox and copies all the text from the current page,  sets the previously focused window back to the foreground,  and processes the text from the clipboard.

    Imports System.Runtime.InteropServices
    
    Public Class Form1
        <DllImport("user32.dll")> Public Shared Function GetForegroundWindow() As IntPtr
        End Function
    
        <DllImport("user32.dll")> Public Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Timer1.Interval = 15000 'aprox. 15 second interval
            Timer1.Enabled = Not Timer1.Enabled
        End Sub
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            Dim hWnd As IntPtr = GetForegroundWindow() 'get the current foreground window handle
            Dim FirefoxProcess As Process = Process.GetProcessesByName("Firefox").FirstOrDefault
            If FirefoxProcess IsNot Nothing Then
                SetForegroundWindow(FirefoxProcess.MainWindowHandle) 'set Firefox as the foreground window
                Threading.Thread.Sleep(500) 'never know how long it will take fore firefox to be brought to the foreground and activated
                SendKeys.SendWait("^{a}") 'selects all the text
                Threading.Thread.Sleep(100) 'might need to wait, it could take a few hundred milliseconds to select all the text if there is a lot
                SendKeys.SendWait("^{c}") 'copies the selected text
                SetForegroundWindow(hWnd) 'set the privious window back to the foreground
                RichTextBox1.Paste() 'paste the clipboard text into a richtextbox
                FirefoxProcess.Dispose() 'dispose the process class
            Else
                Timer1.Stop()
                MessageBox.Show("Firefox is not running.")
            End If
        End Sub
    End Class


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Saturday, December 23, 2017 12:27 PM
    • Marked as answer by InizioVB6 Saturday, December 23, 2017 3:15 PM
    • Unmarked as answer by InizioVB6 Saturday, December 23, 2017 3:17 PM
    • Marked as answer by InizioVB6 Saturday, December 23, 2017 3:17 PM
    Saturday, December 23, 2017 12:26 PM

All replies

  • Is there a way to avoid this and keep the focus on the other work window?

    Thank you

     No,  not doing it with a Copy/Paste method using the keybd_event api function.  That requires the window being Pasted into,  to be focused.

    For us to give a good suggestion on how to do it,  we need more info on exactly how you want it to work and what window it is you are working with when you say it changes the focus.

     Are you working in your internet web browser like Firefox or Internet Explorer,  and copying things that you want to be pasted into your VB.Net application automatically without it having to be focused?


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Friday, December 22, 2017 11:04 PM
    Friday, December 22, 2017 9:28 PM
  • If you have a WebBrowser control, then try this:

       Dim s = WebBrowser1.DocumentText

    The s variable will contain the content of the page in HTML format. If required, it can be copied to Clipboard using the Clipboard class.

    Friday, December 22, 2017 9:38 PM
  • Thanks for the quick reply.
    Viorel_:
    Yes, I copy and save the browser's Web page on disk, from the screen, because in this way there are no tags and control characters (only spaces and the characters of the alphabet + vbCrLf).
    IronRazerz:
    Any (any) other active window I'm using, loses focus and I'm forced to continuously press the mouse to continue (after the program that copies the screen has read the Web page).
    Is it possible to make the handle of the active window, on which I work, known to the screen reading program, and then to restore the focus to the window on which I work, at the end of the screen reading?

    Thank you

    Saturday, December 23, 2017 9:49 AM
  •   As i said before,  if you gave some better details,  we may well be able to suggest a better way to accomplish the end goal.  Maybe by using a WebBrowser control on your form,  or using a way to get the text directly from the website without copy/paste or a webbrowser even being involved.

      Just so you are aware,  it is never going to be reliable doing it by shifting the focused windows around and using a copy/paste method while trying to work in other windows.  If you are working in a window and just happen to click on something or press a key at the same time the code gets executed,  you are going to shift focus to the wrong window and the copy/paste is not going to copy what you want or is going to paste it somewhere you don't want it. There are many, many things that can go wrong with doing it this way.

     

     With that said,  this is a simple example that uses the GetForegroundWindow and SetForegroundWindow api functions to get the handle of the window that has focus,  sets focus to Firefox and copies all the text from the current page,  sets the previously focused window back to the foreground,  and processes the text from the clipboard.

    Imports System.Runtime.InteropServices
    
    Public Class Form1
        <DllImport("user32.dll")> Public Shared Function GetForegroundWindow() As IntPtr
        End Function
    
        <DllImport("user32.dll")> Public Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Timer1.Interval = 15000 'aprox. 15 second interval
            Timer1.Enabled = Not Timer1.Enabled
        End Sub
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            Dim hWnd As IntPtr = GetForegroundWindow() 'get the current foreground window handle
            Dim FirefoxProcess As Process = Process.GetProcessesByName("Firefox").FirstOrDefault
            If FirefoxProcess IsNot Nothing Then
                SetForegroundWindow(FirefoxProcess.MainWindowHandle) 'set Firefox as the foreground window
                Threading.Thread.Sleep(500) 'never know how long it will take fore firefox to be brought to the foreground and activated
                SendKeys.SendWait("^{a}") 'selects all the text
                Threading.Thread.Sleep(100) 'might need to wait, it could take a few hundred milliseconds to select all the text if there is a lot
                SendKeys.SendWait("^{c}") 'copies the selected text
                SetForegroundWindow(hWnd) 'set the privious window back to the foreground
                RichTextBox1.Paste() 'paste the clipboard text into a richtextbox
                FirefoxProcess.Dispose() 'dispose the process class
            Else
                Timer1.Stop()
                MessageBox.Show("Firefox is not running.")
            End If
        End Sub
    End Class


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Saturday, December 23, 2017 12:27 PM
    • Marked as answer by InizioVB6 Saturday, December 23, 2017 3:15 PM
    • Unmarked as answer by InizioVB6 Saturday, December 23, 2017 3:17 PM
    • Marked as answer by InizioVB6 Saturday, December 23, 2017 3:17 PM
    Saturday, December 23, 2017 12:26 PM
  • I will follow your advice and acquire the web page with .DocumentText.
    I quote the code that VB 2008 has transferred from VB6, and which I use for the acquisition.

        Private Sub LeggeDatiSchermo()
            'testo completo in HTML: DatiRx = brwWebBrowser.DocumentText
            'testo completo senza tag ma con i valori dei Titoli senza separatore
            'DatiRx = brwWebBrowser.Document.ActiveElement.OuterText
            '=> utilizzare il CtrlA-CtrlC per acquisire lo schermo e i separatori spazio
    
            'scrive su file i dati presenti nella pagina Web
            'utilizzo del ClipBoard per mantenere e scambiare i dati:
            'archivio compatto e senza fronzoli con i dati CHIARI E SEPARATI da spazi!
    
            'attiva periodicamente il Form (riceve il focus): 
            'deve essere visibile e non ridotto a icona
            'salta e esegue
            Me.Activate()
    
            ' Clear the clipboard.
            My.Computer.Clipboard.Clear()
            System.Windows.Forms.Application.DoEvents()
    
            ' Grab all of the text in the WebBrowser control.
            ' Control-A.
            ' Press Control.
            keybd_event(VK_CONTROL, 0, 0, 0)
            System.Windows.Forms.Application.DoEvents()
            ' Press A.
            keybd_event(VK_A, 1, 0, 0)
            System.Windows.Forms.Application.DoEvents()
    
            ' Control-C.
            ' Press Control.
            keybd_event(VK_CONTROL, 0, 0, 0)
            System.Windows.Forms.Application.DoEvents()
            ' Press C.
            keybd_event(VK_C, 1, 0, 0)
            System.Windows.Forms.Application.DoEvents()
    
            ' Release Control.
            keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0)
            System.Windows.Forms.Application.DoEvents()
    
            'Get the text from the clipboard.
            DatiRx = My.Computer.Clipboard.GetText
            ' Clear the clipboard.
            My.Computer.Clipboard.Clear()
    
            'scrive su file la pagina a video
            My.Computer.FileSystem.WriteAllText(FilePathName, DatiRx, append:=False)
            System.Windows.Forms.Application.DoEvents()
    
            'acquisisce e registra i dati Web
            EstraeNomiDati()
        End Sub
    
        Private Sub Timer1_Tick(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Timer1.Tick
            'rilegge i dati dal sito 
            LeggeDatiSchermo()
        End Sub

    Many thanks

    Saturday, December 23, 2017 3:25 PM