-
Nov 22nd, 2009, 05:12 PM
#1
Thread Starter
Junior Member
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!
-
Nov 25th, 2009, 11:16 AM
#2
Thread Starter
Junior Member
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
-
Nov 25th, 2009, 01:12 PM
#3
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
-
Nov 25th, 2009, 04:38 PM
#4
Thread Starter
Junior Member
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 ?
-
Nov 29th, 2009, 09:28 AM
#5
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
-
Nov 29th, 2009, 09:32 AM
#6
Thread Starter
Junior Member
Re: How send keystroke or command to a minimized window?
-
Nov 29th, 2009, 12:13 PM
#7
Thread Starter
Junior Member
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.
-
Dec 1st, 2009, 04:30 PM
#8
Thread Starter
Junior Member
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?
-
Dec 3rd, 2009, 05:21 PM
#9
-
Dec 4th, 2009, 05:53 PM
#10
Thread Starter
Junior Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|