Results 1 to 10 of 10

Thread: How send keystroke or command to a minimized window?

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Jul 2009
    Posts
    25

    How send keystroke or command to a minimized window?

    Is there a way to send a keystroke like ALT-F or CRTL-S to a specific
    running program which window doesn't have the focus? So not with sendkey
    that only send a keystroke through the keyboards buffer and could end up in
    an other application.

    So suppose I want to command the Notepad running minimized is the taskbar to "save as..."


    Actually, I'm looking for a way to command Adobe Reader to use it's build in "File / Save as text" while it's minimized or hidden. And I don't want or can install Acrobat-writer or any other software.

    Thanks!

  2. #2

    Thread Starter
    Junior Member
    Join Date
    Jul 2009
    Posts
    25

    Re: How send keystroke or command to a minimized window?

    I managed to open the ALT-F menu, but I can't seem to find a way now to select any of the commands like "S" for save...

    Code:
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Const WM_KEYDOWN As Long = &H100
    Private Const WM_KEYUP As Long = &H101
    Private Const WM_CHAR As Long = &H102
    Private Const WM_SYSKEYDOWN = &H104
    Private Const WM_SYSKEYUP = &H105
    Sub sTestPostMessage()
       Shell "notepad.exe", vbNormalFocus
       lHwnd = FindWindow("Notepad", vbNullString)
       lhWndEx = FindWindowEx(lHwnd, 0&, "EDIT", vbNullString)
       PostMessage lhWndEx, WM_SYSKEYDOWN, Asc("F"), &H20200001
       PostMessage lhWndEx, WM_CHAR , Asc("S"), &H20200001 '''THIS DOESN'T WORK ???
    End Sub

  3. #3
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,255

    Re: How send keystroke or command to a minimized window?

    I've used this for a couple programs and it worked even when they were minimized.

    Code:
    Option Explicit
    Private Const WM_COMMAND = &H111
    Private Const MIIM_TYPE = &H10
    Private Const MIIM_ID = 2
    Private Type MENUITEMINFO
        cbSize As Long
        fMask As Long
        fType As Long
        fState As Long
        wID As Long
        hSubMenu As Long
        hbmpChecked As Long
        hbmpUnchecked As Long
        dwItemData As Long
        dwTypeData As String
        cch As Long
    End Type
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function GetMenu Lib "user32" (ByVal Hwnd As Long) As Long
    Private Declare Function GetMenuItemInfo Lib "user32" Alias "GetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As Long, ByVal b As Long, lpMenuItemInfo As MENUITEMINFO) As Long
    Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal Hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    
    Private Sub Command1_Click()
    ' // Example (WinXP) - Open Notepad's Save As Dialog. //
    ' Launch notepad.exe, title bar caption should be: "Untitled - Notepad".
    
        ' find notepad and open "save as" dialog by menu commands.
        Dim Lng As Long
        Lng = FindWindow(vbNullString, "Untitled - Notepad")
        MenuClick Lng, 0, 3 ' first menu, 4th item (zero based).
    End Sub
    
    Private Sub MenuClick(Hwnd As Long, Menu As Long, Item As Long) '0 based, menu seperators count as an item.
        Dim hMenu As Long, hSubMenu As Long, L As Long
        Dim M As MENUITEMINFO
        If Hwnd Then
            hMenu = GetMenu(Hwnd)
            If hMenu Then
                hSubMenu = GetSubMenu(hMenu, Menu)
                If hSubMenu Then
                    M.fMask = MIIM_TYPE Or MIIM_ID
                    M.dwTypeData = Space$(128)
                    M.cbSize = Len(M)
                    M.cch = 128
                    L = GetMenuItemInfo(hSubMenu, Item, True, M)
                    L = SendMessage(Hwnd, WM_COMMAND, M.wID, ByVal 0)
                End If
            End If
        End If
    End Sub

  4. #4

    Thread Starter
    Junior Member
    Join Date
    Jul 2009
    Posts
    25

    Re: How send keystroke or command to a minimized window?

    Thanks!
    Is there also a way to know for shure that Item 3 = "Save" ?
    Can I read it, or select it with "Save" instead of 3 ?

  5. #5
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,255

    Re: How send keystroke or command to a minimized window?

    Might want to look at this thread

    FWIW, Found this old code in my code bank...
    Code:
    Option Explicit
    Private Const MF_BYCOMMAND = &H0&
    Private Const MF_BYPOSITION = &H400&
    Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long
    Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
    Private Declare Function GetMenuString Lib "user32" Alias "GetMenuStringA" (ByVal hMenu As Long, ByVal wIDItem As Long, ByVal lpString As String, ByVal nMaxCount As Long, ByVal wFlag As Long) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    
    Private Sub Form_Load()
        Dim hMenu(1 To 10) As Long
        Dim MenuItemsCount(1 To 10) As Long
        Dim i As Long, j As Long, k As Long
        Dim MyhWnd As Long
        
        MyhWnd = FindWindow("notepad", vbNullString)
    
        ' Level 1 Menu(Main Menu)
        hMenu(1) = GetMenu(MyhWnd)
        If hMenu(1) <> 0 Then
            MenuItemsCount(1) = GetMenuItemCount(hMenu(1))
            ' Level 1 loop
            For i = 0 To MenuItemsCount(1) - 1
                ' Print the menu text
                Debug.Print "Level 1:"; i; j; k; GetMenuText(hMenu(1), i)
                ' Level 2 Menu
                hMenu(2) = GetSubMenu(hMenu(1), i)
                If hMenu(2) <> 0 Then
                    MenuItemsCount(2) = GetMenuItemCount(hMenu(2))
                    ' Level 2 loop
                    For j = 0 To MenuItemsCount(2) - 1
                        ' Print the menu text
                        Debug.Print "Level 2:"; i; j; k; GetMenuText(hMenu(2), j)
                        ' Level 3 Menu
                        hMenu(3) = GetSubMenu(hMenu(2), j)
                        If hMenu(3) <> 0 Then
                            MenuItemsCount(3) = GetMenuItemCount(hMenu(3))
                            ' Level 3 loop
                            For k = 0 To MenuItemsCount(3) - 1
                                ' Print the menu text
                                Debug.Print "Level 3:"; i; j; k; GetMenuText(hMenu(3), k)
                            Next
                        End If
                    Next
                End If
            Next
        End If
    
    End Sub
    
    Private Function GetMenuText(ByVal hMenu As Long, ByVal wIDItem As Long) As String
        Dim c As Long
        Dim s As String
    
        ' Get the text size
        c = GetMenuString(hMenu, wIDItem, vbNullString, 0, MF_BYPOSITION)
        ' Allocate the string
        s = String(c + 1, 0)
        ' Get the text
        c = GetMenuString(hMenu, wIDItem, s, c + 1, MF_BYPOSITION)
        GetMenuText = s
    End Function

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Jul 2009
    Posts
    25

    Re: How send keystroke or command to a minimized window?

    Thanks!

  7. #7

    Thread Starter
    Junior Member
    Join Date
    Jul 2009
    Posts
    25

    Re: How send keystroke or command to a minimized window?

    There are still 3 problems in my vb code, for what I am trying to do:
    1) The "vbNormalNoFocus" doens't work. The AcrobarReader get's focust when started!
    2) The PostMessage of "File/SaveToText..." while AcrobatReader is minimized doesn't work. So how do I start is off-focus not disturbing while for instance typing a email....
    3) Can't seem to find a childwindow of the "save as" to be able to hit it with enter of ALT-S !

    Any idea how to do this?

    Code:
    Private Declare Function GetMenu Lib "user32" (ByVal hWnd As Long) As Long
    Private Declare Function GetMenuItemInfo Lib "user32" Alias "GetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As Long, ByVal b As Long, lpMenuItemInfo As MENUITEMINFO) As Long
    Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
    Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    Private Const WM_CHAR As Long = &H102
    Private Const WM_GETTEXTLENGTH = &HE
    Private Const GW_HWNDNEXT = 2
    Private Const GW_CHILD = 5
    Private Const WM_GETTEXT = &HD
    Private Const WM_SETTEXT = &HC
    Private Const WM_KEYDOWN As Long = &H100
    Private Const WM_KEYUP As Long = &H101
    Private Const WM_SYSKEYDOWN = &H104
    Private Const WM_SYSKEYUP = &H105
    Private Const VK_SHIFT = &H10
    Private Const VK_CONTROL = &H11
    Private Const WM_COMMAND = &H111
    Private Const MIIM_TYPE = &H10
    Private Const MIIM_ID = 2
    Private Type MENUITEMINFO
        cbSize As Long: fMask As Long: fType As Long: fState As Long
        wID As Long: hSubMenu As Long: hbmpChecked As Long: hbmpUnchecked As Long
        dwItemData As Long: dwTypeData As String: cch As Long
    End Type
    Private Sub sPDFtoTXT() '(vFile As String)
     vFile = "C:\temp\test.pdf"
       Dim hWnd As Long, hMenu As Long, hSubMenu As Long, l As Long, M As MENUITEMINFO
       vMenuNum = 0: vItemNum = 7 '''= "File", "Save as text..."  in AdobeReader8
       vFileName = Mid(vFile, InStrRev(vFile, "\") + 1, 99)
       hWnd = FindWindow("AcrobatSDIWindow", vFileName & " - adobe reader")
       If hWnd = 0 Then
          hAcrobat = Shell("C:\Program Files\Adobe\Reader 8.0\Reader\AcroRd32.exe /o /s /n""" & vFile & """", vbNormalNoFocus)
          hWnd = FindWindow("AcrobatSDIWindow", vFileName & " - adobe reader")
          If hWnd = 0 Then MsgBox "File not found!": Exit Sub
       End If
       hMenu = GetMenu(hWnd)
       If hMenu = 0 Then MsgBox "No commands foud!": Exit Sub
       hSubMenu = GetSubMenu(hMenu, vMenuNum)
       If hSubMenu Then
          M.fMask = MIIM_TYPE Or MIIM_ID
          M.dwTypeData = Space$(128)
          M.cbSize = Len(M)
          M.cch = 128
          l = GetMenuItemInfo(hSubMenu, vItemNum, False, M)
          l = PostMessage(hWnd, WM_COMMAND, M.wID, ByVal 0)
       End If
     MsgBox fWindowInfo(hWnd)
    End Sub
    Private Function fWindowInfo(hWnd, Optional vSubMarker As String)
       temp$ = Space(255): vClassName = Left(temp$, GetClassName(hWnd, temp$, 256))
       temp$ = Space(255): vWinName = Left(temp$, SendMessage(hWnd, WM_GETTEXT, 255, ByVal temp$))
    'vWinName = Space(SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0)): SendMessage hWnd, WM_GETTEXT, Len(vWinName)+1, ByVal vWinName
    'vWinName = Space(GetWindowTextLength(hWnd)): GetWindowText hWnd, vWinName, Len(vWinName)+1
       vText = vText & vSubMarker
       'vText = vText & hWnd & vbTab '''add handel
       'vText = vText & vClassName & vbTab
       vText = vText & "[" & vWinName & "]"
       vText = vText & vbCr
       hSubWin = GetWindow(hWnd, GW_CHILD)
       Do While hSubWin <> 0
           vText = vText & fWindowInfo(hSubWin, vSubMarker & "|")
           hSubWin = GetWindow(hSubWin, GW_HWNDNEXT)
       Loop
       fWindowInfo = vText
    End Function
    PS: I want to use AdobeReader8 to extract PDF-text and I can't install any other software on the machine this code should be working.
    Last edited by onidarbe; Nov 29th, 2009 at 12:44 PM.

  8. #8

    Thread Starter
    Junior Member
    Join Date
    Jul 2009
    Posts
    25

    Re: How send keystroke or command to a minimized window?

    1 step closer to a final solution to use AdobeReader8 to convert PDF to a TXT-file.
    1 more question: How do I open a PDF with AdobeReader in the background, not minimized but not focussed and without even a blink in focus?

  9. #9
    Super Moderator manavo11's Avatar
    Join Date
    Nov 2002
    Location
    Around the corner from si_the_geek
    Posts
    7,171

    Re: How send keystroke or command to a minimized window?

    Well, how are you launching it now? With Shell? ShellExecute?


    Has someone helped you? Then you can Rate their helpful post.

  10. #10

    Thread Starter
    Junior Member
    Join Date
    Jul 2009
    Posts
    25

    Re: How send keystroke or command to a minimized window?

    I tryed both. Works, only I get those Open/Save-dialogs popped-up !
    Code:
    Private Sub sPDFtoTXTbu() '(vFile As String)
    vFile = "C:\temp\test.pdf"
       Dim hwnd As Long, hMenu As Long, hSubMenu As Long, l As Long, M As MENUITEMINFO
       Set oFSO = CreateObject("Scripting.FileSystemObject")  '''to have disk-access
       If oFSO.FileExists("C:\temp\test.txt") Then oFSO.DeleteFile ("C:\temp\test.txt")
       vFileName = Mid(vFile, InStrRev(vFile, "\") + 1, 99)
       hwnd = FindWindow("AcrobatSDIWindow", "Adobe reader") '''=empty AdobeReader8 (hidden)
       If hwnd = 0 Then
          Shell "C:\Program Files\Adobe\Reader 8.0\Reader\AcroRd32.exe", SW_SHOWNORMAL
          hwnd = FindWindow("AcrobatSDIWindow", "Adobe reader") '''=empty AdobeReader8 (hidden)
          If hwnd = 0 Then MsgBox "Empty Adobe Reader not found!": Exit Sub
          'ShowWindow hwnd, SW_HIDE
          'Shell "C:\Program Files\Adobe\Reader 8.0\Reader\AcroRd32.exe /o /s /n""" & vFile & """", SW_SHOWMINNOACTIVE
          'ShellExecute 0, "open", vFile, vbNullString, vbNullString, SW_SHOWMINNOACTIVE
          'hwnd = FindWindow("AcrobatSDIWindow", vFileName & " - adobe reader")
       End If
       'SetWindowPos hwnd, 0, 0, 1000, 1000, 500, 0
       PostMessage hwnd, WM_COMMAND, 6001, 0 '''6001="Open" in AdobeReader8, because GetMenuItemID(GetSubMenu(GetMenu(hwnd), 0), iID) always changes!
       'ShowWindow hwnd, SW_HIDE
       i = 0: Do: Sleep 500: i = i + 1: hDialog = FindWindow("#32770", "Open"): Loop Until hDialog Or i > 4
       If hDialog = 0 Then MsgBox "Open-dialog from Adobe Reader, not working!": Exit Sub
       hText = FindWindowEx(hDialog, 0, "COMBOBOXEX32", "")
       hText = FindWindowEx(hText, 0, "COMBOBOX", "")
       hText = FindWindowEx(hText, 0, "EDIT", "")
       SendMessage hText, WM_SETTEXT, 1, ByVal "C:\temp\test.pdf"
       PostMessage FindWindowEx(hDialog, 0&, "BUTTON", "Open"), BM_CLICK, 0, 0
       'ShowWindow hwnd, SW_HIDE
       PostMessage hwnd, WM_COMMAND, 6338, 0 '''6338="Save as text" in AdobeReader8, because GetMenuItemID(GetSubMenu(GetMenu(hwnd), 0), iID) always changes!
       i = 0: Do: Sleep 500: i = i + 1: hDialog = FindWindow("#32770", "Save As"): Loop Until hDialog Or i > 4
       If hDialog = 0 Then MsgBox "Save As-dialog from Adobe Reader, not working!": Exit Sub
       hText = FindWindowEx(hDialog, 0, "COMBOBOXEX32", "")
       hText = FindWindowEx(hText, 0, "COMBOBOX", "")
       hText = FindWindowEx(hText, 0, "EDIT", "")
       SendMessage hText, WM_SETTEXT, 1, ByVal "C:\temp\test.txt"
       PostMessage FindWindowEx(hDialog, 0&, "BUTTON", "&Save"), BM_CLICK, 0&, 0
       PostMessage hwnd, WM_COMMAND, 6010, 0 '''6010="Close" in AdobeReader8, because GetMenuItemID(GetSubMenu(GetMenu(hwnd), 0), iID) always changes!
    End Sub
    It doesn't seem I can keep focus to any other running program. So now I'm thinking on sending a CTRL-A + CTRL-C to get is into the clipboard, although that probably want work minimized or hidden, maybe it would work shifted the window out of the screen-area. If I could find a way to just read the text out of some FindWindowEx-handle then I could save it hardcoded to a txt-file... I think I've found the window-handle but I can't even seem to find out how to even read the text in NOTEPAD !
    Code:
    Private Sub sReadTXTinPDF() '(vFile As String)
       notepad = FindWindow("notepad", vbNullString)
       editx = FindWindowEx(notepad, 0&, "edit", vbNullString)
       SendMessageByString editx, WM_SETTEXT, 0&, "The New Text"
       TextLen = SendMessage(editx, WM_GETTEXTLENGTH, 0, 0) + 1
       vString = String(TextLen, " ")
       SendMessageByString editx, WM_GETTEXT, TextLen - 1, vString  '''DOESN'T WORK !?????
       MsgBox (vString)
    Exit Sub
        
       vFile = "C:\temp\test.pdf"
       Dim hwnd As Long, hMenu As Long, hSubMenu As Long, l As Long, M As MENUITEMINFO
       Set oFSO = CreateObject("Scripting.FileSystemObject")  '''to have disk-access
       If oFSO.FileExists("C:\temp\test.txt") Then oFSO.DeleteFile ("C:\temp\test.txt")
       vFileName = Mid(vFile, InStrRev(vFile, "\") + 1, 99)
       hwnd = FindWindow("AcrobatSDIWindow", "Adobe reader") '''=empty AdobeReader8 (hidden)
       If hwnd = 0 Then
          Shell "C:\Program Files\Adobe\Reader 8.0\Reader\AcroRd32.exe /o /s /n""" & vFile & """", SW_SHOWNORMAL
          hwnd = FindWindow("AcrobatSDIWindow", vFileName & " - adobe reader")
          If hwnd = 0 Then MsgBox "Empty Adobe Reader not found!": Exit Sub
       End If
       'SetWindowPos hwnd, 0, 0, 1000, 1000, 500, 0
       hPDFdoc = FindWindowEx(hwnd, 0, "AVL_AVView", "AVToolBarHostView")
       hPDFdoc = FindWindowEx(hPDFdoc, 0, "AVL_AVView", "AVInternalDocumentView")
       hPDFdoc = FindWindowEx(hPDFdoc, 0, "AVL_AVView", "AVSplitterView")
       hPDFdoc = FindWindowEx(hPDFdoc, 0, "AVL_AVView", "AVDocumentWrapperView")
       hPDFdoc = FindWindowEx(hPDFdoc, 0, "AVL_AVView", "AVSplitterView")
       hPDFdoc = FindWindowEx(hPDFdoc, 0, "AVL_AVView", "AVSplitationPageView")
       hPDFdoc = FindWindowEx(hPDFdoc, 0, "AVL_AVView", "AVSplitterView")
       hPDFdoc = FindWindowEx(hPDFdoc, 0, "AVL_AVView", "AVScrolledPageView")
       hPDFdoc = FindWindowEx(hPDFdoc, 0, "AVL_AVView", "AVScrollView")
       hPDFdoc = FindWindowEx(hPDFdoc, 0, "AVL_AVView", "AVPageView")
    'i = SendMessage(hPDFdoc, WM_GETTEXTLENGTH, ByVal 0&, ByVal 0&)
    's = Space$(i + 1)
    'SendMessage hPDFdoc, WM_GETTEXT, ByVal i + 1, ByVal s
    End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width