locked
How do I start my application without window focus? RRS feed

  • Question

  • I can't find anything about a Visual Basic application that doesn't open with focus

    I've written an application that takes the current clipboard text and changes all letters to lower case, then the first letter of every word to upper case (the first letter after a space), this is for when I download a file that I want to look neat (such as an mp3 audio file). It's output is then placed in the clipboard to be used as the filename (or text).

    I've set a shortcut key (Ctrl+Alt+X) to open the application by placing a shortcut in Accessories so it runs instantly whenever I hit the shortcut combination.

    However the application steals focus when it runs, so as soon as it ends I lose focus altogether, and I then have to Alt+Tab and find where I was when I used the shortcut!

    There are 2 possibilities for my application, the latter is what I really want, but the former is OK for me:

    1. I use Ctrl+C to copy, The application runs and then switches to the original focus (focus before using my shortcut combination), I can then Ctrl+V to paste.

    2. The application runs WITHOUT stealing focus altogether, this way I can have the application copy the selected text for me, and replace it aswel

     

    For "1." I have attempted using the SendKeys Alt+Tab but it doesn't always goto the right application (eg. If I have notepad and firefox open, it doesn't matter where I run the shortcut, it will switch to notepad automatically, even if notepad is the bottom of the whole Alt+Tab Stack)

    Any help would be much appreciated. Is there any way to let my application open totally out of focus, bear in mind I am NOT using an external application to open it, the application is being opened by the Explorer process.

    Tuesday, December 14, 2010 7:14 PM

Answers

  •  

    Why dont you go with a clipboard listener instead of trying to start an application.

    The clipboard listener can run in the notify area and the user can right click on it to get a menu to start and stop the listener to title case your text

    This will never take the focus from any application

    Here an example of code (You will have to specify an icon that is on your disk to run the application)

    Just paste this on an empty form and run

     

     

    Public Class Form1
    
      Private ClipboardMenu As Windows.Forms.ContextMenu
      Friend WithEvents menuItemStart As Windows.Forms.MenuItem
      Friend WithEvents menuItemStop As Windows.Forms.MenuItem
      Friend WithEvents menuItemEnd As Windows.Forms.MenuItem
      Friend WithEvents ClipboardNotifyIcon As Windows.Forms.NotifyIcon
      Private Working As Boolean = False
    
      Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        Me.WindowState = FormWindowState.Minimized
        Me.ShowInTaskbar = False
        If AddClipboardFormatListener(Me.Handle) Then Working = True
        ClipboardMenu = New Windows.Forms.ContextMenu
        menuItemStart = New Windows.Forms.MenuItem
        menuItemStop = New Windows.Forms.MenuItem
        menuItemEnd = New Windows.Forms.MenuItem
        ClipboardMenu.MenuItems.AddRange(New Windows.Forms.MenuItem() {menuItemStart, menuItemStop, menuItemEnd})
        menuItemStart.Index = 0
        menuItemStart.Text = "&Start"
        menuItemStop.Index = 1
        menuItemStop.Text = "S&top"
        menuItemEnd.Index = 2
        menuItemEnd.Text = "E&xit"
        ClipboardNotifyIcon = New Windows.Forms.NotifyIcon()
        ClipboardNotifyIcon.Icon = New Icon("c:\Users\Luc\Desktop\FileScan\FileScan\FS.ico")
        ClipboardNotifyIcon.ContextMenu = Me.ClipboardMenu
        ClipboardNotifyIcon.Text = "Clipboard Hook"
        ClipboardNotifyIcon.Visible = True
      End Sub
    
      Protected Overrides Sub WndProc(ByRef m As Windows.Forms.Message)
        If m.Msg = WM_CLIPBOARDUPDATE AndAlso Working Then
          m.Result = IntPtr.Zero
          Dim oClip = My.Computer.Clipboard.GetDataObject
          If oClip.GetDataPresent(DataFormats.Text) Then
            If RemoveClipboardFormatListener(Me.Handle) Then
              Dim TextInfo As Globalization.TextInfo = New Globalization.CultureInfo("en-US", False).TextInfo
              My.Computer.Clipboard.SetText(TextInfo.ToTitleCase(TextInfo.ToLower(My.Computer.Clipboard.GetText())))
              AddClipboardFormatListener(Me.Handle)
            Else
              Me.Close()
              ClipboardNotifyIcon.Dispose()
            End If
          End If
        Else
          MyBase.WndProc(m)
        End If
      End Sub
    
      Private Sub menuItemEnd_Click(ByVal sender As Object, ByVal e As EventArgs) Handles menuItemEnd.Click
        Me.Close()
        ClipboardNotifyIcon.Dispose()
      End Sub
    
      Private Sub menuItemStart_Click(ByVal sender As Object, ByVal e As EventArgs) Handles menuItemStart.Click
        If AddClipboardFormatListener(Me.Handle) Then Working = True
      End Sub
    
      Private Sub menuItemStop_Click(ByVal sender As Object, ByVal e As EventArgs) Handles menuItemStop.Click
        Working = False
        If Not RemoveClipboardFormatListener(Me.Handle) Then
          Me.Close()
          ClipboardNotifyIcon.Dispose()
        End If
      End Sub
    
      Private Const WM_CLIPBOARDUPDATE As Integer = &H31D
      Declare Function AddClipboardFormatListener Lib "User32.dll" (ByVal hWnd As IntPtr) As Boolean
      Declare Function RemoveClipboardFormatListener Lib "User32.dll" (ByVal hWnd As IntPtr) As Boolean
    
    End Class

     

    • Proposed as answer by Jarrey Monday, December 20, 2010 9:43 AM
    • Marked as answer by Martin_Xie Thursday, December 23, 2010 10:55 AM
    Thursday, December 16, 2010 1:21 AM
  • Nimso,

    I'm sorry to hear that that did not work, but I learned something.  I originally tested that code on XP Pro 32 bit and it worked but when I tried it on my Vista Home Premium 32 bit, it failed.

    So it is evidently version specific.  To make it work with Vista, I had to change

    ShowWindow(myWindowHandle, ShowWindowEnum.SW_Hide)

    to

    ShowWindow(myWindowHandle, ShowWindowEnum.SW_Minimize)

    Hopefully, this modification will allow it to work on your Win 7 installation.

    • Marked as answer by Martin_Xie Thursday, December 23, 2010 10:55 AM
    Thursday, December 16, 2010 1:49 AM
  • As expected the problem persist and seems to be due to the way windows runs Keyboard Shortcuts as opposed to the standard way of opening an application...

     

    Opening my application from double clicking it's actual shortcut does the application functions properly and sends focus straight back to the Explorer folder that I was at... using the keyboard shortcut to the very same shortcut doesn't!

     

    It seems I'm better making a launcher for all my apps that runs as a background process, that way I have a single extra background process that can run each of my applications with proper focus control!

    Thanks for the attempt though, but have you tried doing a simple test on the notepad shortcut,

    Set a shortcut key for it, now open the shortcut normally and close Notepad after it runs, focus jumps back to where you were,

    now try running Notepad from the keyboard shortcut, when you close Notepad you've also lost focus,

    You see what I mean, I think it's just the Windows handles it!

     

    EDIT:

    It seems I've managed to emulate switching back focus by using SendKeys.SendWait("%{TAB}")
    (Sends an Alt Tab)

    This is obviously not the best way, as it shows the Alt-Tab window in the center of the screen, however it manages to keep my selected text selected and rids me of the need to actually CLICK on my window!

    • Marked as answer by Martin_Xie Thursday, December 23, 2010 10:55 AM
    Thursday, December 16, 2010 10:23 PM

All replies

  • does running it as a console app work?
    Tuesday, December 14, 2010 9:44 PM
  • Do you need a form in this application? If you dont opem a form, your application wont take the focus
    Tuesday, December 14, 2010 10:37 PM
  • I'm not using a Form.

    It's a console application (visual Studio 2010)

    As soon as it runs (from the shortcut combination)

    I quickly see the cmd window open to run the app, it then closes instantly after doing it's functions, and the focus is totally lost!
    Tuesday, December 14, 2010 11:18 PM
  • Does it need to be a console application ??

    If you use a Form application that start from "Sub Main" and you never call "Application.Run", the application will not get the focus

    Wednesday, December 15, 2010 12:15 AM
  • I hope that works... I'll try it out, but I did make the application as a Window Form,
    But I placed the same code in the Main Sub, it didn't do anything at all!

     

    Thanks for the suggestion

     

    EDIT:

     

    I have attempted this suggestion, it now never actually SHOWS the window, but still Loses focus.

    It's as if windows jumps to the new application then doesn't bother jumping back when it closes (I used "Me.Close" to end it)

    The application does work properly but loses focus, just doesn't show it's window!

    Wednesday, December 15, 2010 12:29 AM
  • This is the code you need

    Module module1
      Sub main()
        Dim a As String = My.Computer.Clipboard.GetText
        'Do whatever you need with your text here
        My.Computer.Clipboard.SetText(a)
      End Sub
    End Module
    
    Make sure your application is setup to start in Sub Main
    Wednesday, December 15, 2010 12:47 AM
  • That made no difference, I'm already getting and setting the clipboard using Clipboard.GetText / Clipboard.SetText

    That's not a problem at all... I've already got the script in the Main Sub also...

    I have however realised one thing:

    When the application is run normally (by double clicking, or using the Return key on the selected icon) it doesn't affect focus, however when run through the keyboard shortcut (which is a standard keyboard shortcut, Shortcut.lnk > Properties > Shortcut Key) It DOES steal focus?

     

    EDIT:

    Wow, it seems to be a silly situation with Windows!
    When I open from the icon, then close it Focus goes back to explorer
    If I dod the same using my keyboard shortcut then close notepad, focus is just lost!

    I think the taskbar getting selected?

    Wednesday, December 15, 2010 12:57 AM
  • Hi Nimso,

    Give this a try.  I think it has the behavior you are looking for.  Also, I think you original program may have worked if you set your shortcut to startup minimized, but I'm not 100% sure about that.

    Module Module1
      Sub Main()
       Dim myWindowHandle As IntPtr
       myWindowHandle = System.Diagnostics.Process.GetCurrentProcess.MainWindowHandle
       ShowWindow(myWindowHandle, ShowWindowEnum.SW_Hide)
       Dim s As String = My.Computer.Clipboard.GetText
       Dim ti As System.Globalization.TextInfo = _
         New System.Globalization.CultureInfo("en-US", False).TextInfo
       s = ti.ToTitleCase(s)
       My.Computer.Clipboard.SetText(s)
      End Sub
    
      Enum ShowWindowEnum As Int32
       ''' <summary>Hides the window and activates another window.</summary>
       SW_Hide = 0
       ''' <summary>Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.</summary>
       SW_ShowNormal = 1
       ''' <summary>Activates the window and displays it as a minimized window</summary>
       SW_ShowMinimized = 2
       ''' <summary>Activates the window and displays it as a maximized window.</summary>
       SW_Maximize = 3
       ''' <summary>Displays a window in its most recent size and position. This value is similar to SW_SHOWNORMAL, except that the window is not activated.</summary>
       SW_ShowNoActivate = 4
       ''' <summary>Activates the window and displays it in its current size and position.</summary>
       SW_Show = 5
       ''' <summary>Minimizes the specified window and activates the next top-level window in the Z order.</summary>
       SW_Minimize = 6
       ''' <summary>Displays the window as a minimized window. This value is similar to SW_SHOWMINIMIZED, except the window is not activated.</summary>
       SW_ShowMinNoActive = 7
       ''' <summary>Displays the window in its current size and position. This value is similar to SW_SHOW, except that the window is not activated.</summary>
       SW_ShowNotActivated = 8
       ''' <summary>Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window.</summary>
       SW_Restore = 9
       ''' <summary>Sets the show state based on the SW_ value specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application.</summary>
       SW_ShowDefault = 10
       ''' <summary>Minimizes a window, even if the thread that owns the window is not responding. This flag should only be used when minimizing windows from a different thread.</summary>
       SW_ForceMinimize = 11
      End Enum
    
      <System.Runtime.InteropServices.DllImport("User32.dll")> _
      Public Function ShowWindow( _
       <System.Runtime.InteropServices.In()> ByVal hWnd As IntPtr, _
       <System.Runtime.InteropServices.In()> ByVal nCmdShow As ShowWindowEnum) As Boolean
      End Function
    
    End Module
    
    

    Wednesday, December 15, 2010 3:37 AM
  • No difference, I see what that code attempts to do but even when the application is run minimised (from the shortcut properties) it just loses focus when it runs...

     

    I am coming to believe that it is impossible, I believe the keyboard shortcut causes focus loss BEFORE the application runs which would have to be a GLITCH in Windows!!!

     

    I'm running Windows 7 Home Premium Edition on a 64-bit processor.

     

    For now I'll just have to stick to having to click back into my last application whenever I run my text modification app!

    Wednesday, December 15, 2010 9:25 PM
  •  

    Why dont you go with a clipboard listener instead of trying to start an application.

    The clipboard listener can run in the notify area and the user can right click on it to get a menu to start and stop the listener to title case your text

    This will never take the focus from any application

    Here an example of code (You will have to specify an icon that is on your disk to run the application)

    Just paste this on an empty form and run

     

     

    Public Class Form1
    
      Private ClipboardMenu As Windows.Forms.ContextMenu
      Friend WithEvents menuItemStart As Windows.Forms.MenuItem
      Friend WithEvents menuItemStop As Windows.Forms.MenuItem
      Friend WithEvents menuItemEnd As Windows.Forms.MenuItem
      Friend WithEvents ClipboardNotifyIcon As Windows.Forms.NotifyIcon
      Private Working As Boolean = False
    
      Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        Me.WindowState = FormWindowState.Minimized
        Me.ShowInTaskbar = False
        If AddClipboardFormatListener(Me.Handle) Then Working = True
        ClipboardMenu = New Windows.Forms.ContextMenu
        menuItemStart = New Windows.Forms.MenuItem
        menuItemStop = New Windows.Forms.MenuItem
        menuItemEnd = New Windows.Forms.MenuItem
        ClipboardMenu.MenuItems.AddRange(New Windows.Forms.MenuItem() {menuItemStart, menuItemStop, menuItemEnd})
        menuItemStart.Index = 0
        menuItemStart.Text = "&Start"
        menuItemStop.Index = 1
        menuItemStop.Text = "S&top"
        menuItemEnd.Index = 2
        menuItemEnd.Text = "E&xit"
        ClipboardNotifyIcon = New Windows.Forms.NotifyIcon()
        ClipboardNotifyIcon.Icon = New Icon("c:\Users\Luc\Desktop\FileScan\FileScan\FS.ico")
        ClipboardNotifyIcon.ContextMenu = Me.ClipboardMenu
        ClipboardNotifyIcon.Text = "Clipboard Hook"
        ClipboardNotifyIcon.Visible = True
      End Sub
    
      Protected Overrides Sub WndProc(ByRef m As Windows.Forms.Message)
        If m.Msg = WM_CLIPBOARDUPDATE AndAlso Working Then
          m.Result = IntPtr.Zero
          Dim oClip = My.Computer.Clipboard.GetDataObject
          If oClip.GetDataPresent(DataFormats.Text) Then
            If RemoveClipboardFormatListener(Me.Handle) Then
              Dim TextInfo As Globalization.TextInfo = New Globalization.CultureInfo("en-US", False).TextInfo
              My.Computer.Clipboard.SetText(TextInfo.ToTitleCase(TextInfo.ToLower(My.Computer.Clipboard.GetText())))
              AddClipboardFormatListener(Me.Handle)
            Else
              Me.Close()
              ClipboardNotifyIcon.Dispose()
            End If
          End If
        Else
          MyBase.WndProc(m)
        End If
      End Sub
    
      Private Sub menuItemEnd_Click(ByVal sender As Object, ByVal e As EventArgs) Handles menuItemEnd.Click
        Me.Close()
        ClipboardNotifyIcon.Dispose()
      End Sub
    
      Private Sub menuItemStart_Click(ByVal sender As Object, ByVal e As EventArgs) Handles menuItemStart.Click
        If AddClipboardFormatListener(Me.Handle) Then Working = True
      End Sub
    
      Private Sub menuItemStop_Click(ByVal sender As Object, ByVal e As EventArgs) Handles menuItemStop.Click
        Working = False
        If Not RemoveClipboardFormatListener(Me.Handle) Then
          Me.Close()
          ClipboardNotifyIcon.Dispose()
        End If
      End Sub
    
      Private Const WM_CLIPBOARDUPDATE As Integer = &H31D
      Declare Function AddClipboardFormatListener Lib "User32.dll" (ByVal hWnd As IntPtr) As Boolean
      Declare Function RemoveClipboardFormatListener Lib "User32.dll" (ByVal hWnd As IntPtr) As Boolean
    
    End Class

     

    • Proposed as answer by Jarrey Monday, December 20, 2010 9:43 AM
    • Marked as answer by Martin_Xie Thursday, December 23, 2010 10:55 AM
    Thursday, December 16, 2010 1:21 AM
  • Thanks, that was sort of my backup plan, to build an application to run in the background and use it to shortcut key instead of windows... But I just didn't want another application in the background.

    Having a application that opens when you need it and you don't actually see it is almost like windows having the ability integrated in the shell!

    However I'm going to develop an application that runs in the background to bring all my shortcut apps together,

    I've got another one that is based on this one, it changes the letters to characters in ASCII that look a bit like letters:

    L!ke thiš, dºešn't it lººk ¢ººl

     

    For my social networking!

    So that code that you just posted is pretty much the perfect thing to start with!!!

     

    Thank you!

    Thursday, December 16, 2010 1:31 AM
  • Nimso,

    I'm sorry to hear that that did not work, but I learned something.  I originally tested that code on XP Pro 32 bit and it worked but when I tried it on my Vista Home Premium 32 bit, it failed.

    So it is evidently version specific.  To make it work with Vista, I had to change

    ShowWindow(myWindowHandle, ShowWindowEnum.SW_Hide)

    to

    ShowWindow(myWindowHandle, ShowWindowEnum.SW_Minimize)

    Hopefully, this modification will allow it to work on your Win 7 installation.

    • Marked as answer by Martin_Xie Thursday, December 23, 2010 10:55 AM
    Thursday, December 16, 2010 1:49 AM
  • As expected the problem persist and seems to be due to the way windows runs Keyboard Shortcuts as opposed to the standard way of opening an application...

     

    Opening my application from double clicking it's actual shortcut does the application functions properly and sends focus straight back to the Explorer folder that I was at... using the keyboard shortcut to the very same shortcut doesn't!

     

    It seems I'm better making a launcher for all my apps that runs as a background process, that way I have a single extra background process that can run each of my applications with proper focus control!

    Thanks for the attempt though, but have you tried doing a simple test on the notepad shortcut,

    Set a shortcut key for it, now open the shortcut normally and close Notepad after it runs, focus jumps back to where you were,

    now try running Notepad from the keyboard shortcut, when you close Notepad you've also lost focus,

    You see what I mean, I think it's just the Windows handles it!

     

    EDIT:

    It seems I've managed to emulate switching back focus by using SendKeys.SendWait("%{TAB}")
    (Sends an Alt Tab)

    This is obviously not the best way, as it shows the Alt-Tab window in the center of the screen, however it manages to keep my selected text selected and rids me of the need to actually CLICK on my window!

    • Marked as answer by Martin_Xie Thursday, December 23, 2010 10:55 AM
    Thursday, December 16, 2010 10:23 PM