![]() |
KnowBrainer Speech Recognition | ![]() |
Topic Title: Is there a way to get the name of the current window or application in an advanced script? Topic Summary: Created On: 03/07/2022 05:27 PM Status: Post and Reply |
|
![]() |
![]() |
- wristofdoom | - 03/07/2022 05:27 PM |
![]() |
![]() |
- Edgar | - 03/08/2022 10:03 AM |
![]() |
![]() |
- R. Wilke | - 03/08/2022 02:21 PM |
![]() |
![]() |
- wristofdoom | - 03/08/2022 05:46 PM |
![]() |
![]() |
- Matt_Chambers | - 03/08/2022 07:33 PM |
![]() |
![]() |
- R. Wilke | - 03/08/2022 08:39 PM |
![]() |
![]() |
- Alan Cantor | - 03/08/2022 07:46 PM |
![]() |
![]() |
- Matt_Chambers | - 03/09/2022 08:14 AM |
![]() |
![]() |
- Edgar | - 03/08/2022 08:21 PM |
![]() |
![]() |
- Edgar | - 03/09/2022 08:56 AM |
![]() |
|
I find myself re-creating similar "application-specific" commands over and over in different applications that have slightly different hotkeys.
What I would like to do is set a global command that will check what the current application is, and then send the correct hotkey accordingly.
currentApp = { some magical code that will fetch the name of the current application } If currentApp = "Chrome.exe" then Sendkeys "^+8" ' this is Google docs ElseIf currentApp = "Obsidian.exe" then Sendkeys "%-" ElseIf ...
So is there some way to get the name of the application or the window into a variable?
Or am I stuck re-creating the same command over and over again every time I start using a new app?
------------------------- Dragon Professional Individual v15.6. Windows 10. Knowbrainer 2017. |
|
|
|
![]() |
|
The short answer is yes, but there are a couple of complications. You can get the name of the current window and, if it is not a child window, it's usually possible to determine the application from that name. However, if the application has multiple windows open, it might not be possible to determine the application from the name of the window. Dragon®/KnowBrainer scripting allows you access to most, if not all, of the low level function calls for manipulating Windows®. You have to prepare each individual script to recognize these function calls and each function call must be individually specified. The easiest way to do this is to set up an "include" file. ____example with uses:____ '#Uses "C:\Program Files (x86)\KnowBrainer\KnowBrainer Professional 2017\WindowsAPI.txt" Sub Main ' your code goes here End Sub ____end of example____
____example without uses:____ Declare Function GetForegroundWindow Lib "user32" Alias "GetForegroundWindow" () As Long Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Sub Main Dim title As String
title = ActiveWindowTitle ' You now have the title of the foreground when the ' You need to figure out how to parse the application from the title ' if the application is Notepad the title might look like: ' untitled - Notepad ' your code goes here, in pseudocode and might look something like... If InStr(title, "Notepad") <> 0 Then ' Do whatever you want to do if the application is notepad End If End Sub
Function ActiveWindowTitle() As String ' based on a script from the KnowBrainer Forum by Fmen Dim titleLength As Integer Dim title As String Dim foregroundWindow As Long
foregroundWindow = GetForegroundWindow() titleLength = GetWindowText (foregroundWindow, title, 512) title = Left(title, titleLength) title = Trim (title) ActiveWindowTitle = title End Function ____end of example____
I have a text file "WindowsAPI.txt" in which I keep every Windows® API which I use (you may place it anywhere just make sure that your #uses statement reflects the accurate location), for the not-faint-of-heart, I will included here... ____WindowsAPI.txt:____ ' WindowsAPI.txt ' efm5 30 November 2016 'references these Windows API functions: 'FindWindow (ByVal lpClassName As String, ByVal lpWindowName As String) As Long 'GetCursorPos (lpPoint As POINT) As Long 'GetForegroundWindow () As Long 'GetMonitorInfo (ByVal hMonitor As Long, lpMonitorInformation As MONITORINFO) As Long 'GetSystemMetrics (ByVal n As Long) As Long 'GetTickCount () As Long 'GetWindowPlacement (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long 'GetWindowRect (ByVal hwnd As Long, lpRect As LOCATIONSIZE) As Long 'GetWindowText (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long 'keybd_event Lib "user32.dll" (ByVal vKey As Long, bScan As Long, ByVal Flag As Long, ByVal exInfo As Long) As Long 'MonitorFromRect (lpRect As RECTANGLE, dwFlags As Long) As Long 'MoveWindow (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long 'SetActiveWindow (ByVal hwnd As Long) As Long 'SetForegroundWindow (ByVal hwnd As Long) As Long 'SetWindowPos (ByVal hwnd As Long, ByVal hwndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long 'ShowWindow (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long 'SystemParametersInfo (ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long) As Long
'mouse_event (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal dwData As Long, ByVal dwExtraInfo As Long)
' defines these custom functions: 'ActivateWindow (ByVal windowClass As String, ByVal windowTitle As String, ByVal timeout As Long) As Boolean (ByVal windowClass As String, ByVal windowTitle As String, ByVal timeout As Long) As Boolean 'ActivateWindow is currently unused and commented out 'SecondaryMonitorRectangle (lpPrimaryMonitorRectangle As RECTANGLE) As RECTANGLE 'ActiveWindowTitle() As String 'WaitForDialog() 'WaitForWindow (WindowTitle As String, WaitTime As Integer) As Integer
Type RECTANGLE Left As Long Top As Long Right As Long Bottom As Long End Type
Type LOCATIONSIZE Left As Long Top As Long Width As Long Height As Long End Type
Type POINT x As Long y As Long End Type
type WINDOWPLACEMENT length As Long flags As Long showCmd As Long ptMinPosition As POINT ptMaxPosition As POINT rcNormalPosition As RECTANGLE End Type
Type MONITORINFO cbSize As Long rcMonitor As RECTANGLE rcWork As RECTANGLE dwFlags As Long End Type
' WINDOWPLACEMENT pound defines for showCmd: Enum WindowPlacements SW_HIDE = 0 SW_SHOWNORMAL = 1 SW_SHOWMINIMIZED = 2 SW_MAXIMIZE = 3 'SW_SHOWMAXIMIZED = 3' I wonder if this is a mistake in the documentation SW_SHOWNOACTIVATE = 4 SW_SHOW = 5 SW_MINIMIZE = 6 SW_SHOWMINNOACTIVE = 7 SW_SHOWNA = 8 SW_RESTORE = 9 End Enum Dim WindowPlacement As WindowPlacements
' pound defines for Set Window Position: Enum SetWindowPositions SWP_SHOWWINDOW = 64 ' there are quite a few more but I won't worry about them until I need them ' https://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx End Enum Dim WindowPositions As SetWindowPositions
' pound defines for System Parameters Info : Enum SystemParametersInfos SPI_GETWORKAREA = 48 ' there are quite a few more but I won't worry about them until I need them ' https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947(v=vs.85).aspx End Enum Dim SystemParameters As SystemParametersInfos
' pound defines for Monitor From Rectangle/Window: Enum MonitorFromRectangles MONITOR_DEFAULTTONULL = 0 MONITOR_DEFAULTTOPRIMARY = 1 MONITOR_DEFAULTTONEAREST = 2 End Enum Dim MonitorFroms As MonitorFromRectangles
' Constants for mouse_event Const MOUSEEVENTF_LEFTDOWN = &H2 Const MOUSEEVENTF_LEFTUP = &H4 Const MOUSEEVENTF_MIDDLEDOWN = &H20 Const MOUSEEVENTF_MIDDLEUP = &H40 Const MOUSEEVENTF_RIGHTDOWN = &H8 Const MOUSEEVENTF_RIGHTUP = &H10
' declare virtual key constant for the left Windows key, control key, shift key, alt key & space key 'https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes Const VK_LWIN = &h5B Const VK_CTRL = &h11 Const VK_SHIFT = &h10 Const VK_ALT = &h12 Const VK_SPACE = &h20 Const VK_LMENU = &hA4 Const VK_LALT = &hA4' alias Const VK_RMENU = &hA5 Const VK_RALT = &hA5' alias Const VK_LSHIFT = &hA0 Const VK_RSHIFT = &hA1 Const VK_SNAPSHOT = &h2C Const VK_PRINT_SCREEN = &h2C' alias
' declare Win32 API functions Declare Function keybd_event Lib "user32.dll" (ByVal vKey As Long, bScan As Long, ByVal Flag As Long, ByVal exInfo As Long) As Long
Declare Function GetCursorPos Lib "user32" Alias "GetCursorPos" (lpPoint As POINT) As Long
Declare Function GetTickCount Lib "kernel32" () As Long
Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As Long, lpRect As LOCATIONSIZE) As Long
Declare Function GetForegroundWindow Lib "user32" Alias "GetForegroundWindow" () As Long
Declare Function MoveWindow Lib "user32.dll" Alias "MoveWindow" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Declare Function SetWindowPos Lib "user32.dll" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hwndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long) As Long
Declare Function GetMonitorInfo Lib "user32" Alias "GetMonitorInfo" (ByVal hMonitor As Long, lpMonitorInformation As MONITORINFO) As Long
Declare Function MonitorFromRect Lib "user32" Alias "MonitorFromRect" (lpRect As RECTANGLE, dwFlags As Long) As Long
Declare Function GetWindowPlacement Lib "user32" Alias "GetWindowPlacement" (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long
Declare Function SetForegroundWindow Lib "user32" Alias "SetForegroundWindow" (ByVal hwnd As Long) As Long
Declare Function ShowWindow Lib "user32.dll" Alias "ShowWindow" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Declare Function FindWindow Lib "user32" Alias "FindWindow" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function SetActiveWindow Lib "user32" Alias "SetActiveWindow" (ByVal hwnd As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Declare Function GetSystemMetrics Lib "user32" Alias "GetSystemMetrics" (ByVal n As Long) As Long
Declare Function mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal dwData As Long, ByVal dwExtraInfo As Long)
' Custom functions:
' the ActivateWindow command is unused as of 21 February 2018 'Declare Function ActivateWindow Lib "user32" Alias "ActiveWindow" (ByVal windowClass As String, ByVal windowTitle As String, ByVal timeout As Long) As Boolean
'Function ActivateWindow (ByVal windowClass As String, ByVal windowTitle As String, ByVal timeout As Long) As Boolean 'Dim returnValue As Boolean 'returnValue = false 'Dim windowHandle As Long 'windowHandle = FindWindow (windowClass, windowTitle) 'if windowHandle = 0 Then '' warn the user then bail out 'MsgBox "could not find a window with the title: " + windowTitle 'Exit All 'End If 'ShowWindow(windowHandle, 5)' 5 = SW_SHOW - see above WindowPlacements 'windowHandle = SetForegroundWindow(windowHandle)' may not activate a window unless it is foreground 'if windowHandle = 0 Then '' warn the user then bail out 'MsgBox "could not make a window with the title: " + windowTitle + " the Foreground window" 'Exit All 'End If 'For increment = 0 To timeout 'Dim activeWindowHandle As Long 'activeWindowHandle = SetActiveWindow(windowHandle) 'If activeWindowHandle = 0 Then 'Wait 1 'Else 'returnValue = true 'Exit For 'End If 'Next increment 'ActivateWindow = returnValue 'End Function
Function SecondaryMonitorRectangle (lpPrimaryMonitorRectangle As RECTANGLE) As RECTANGLE Dim secondaryRectangle As RECTANGLE Dim monitorInformation As MONITORINFO Dim monitorHandle As Long ' given a grid like the Mouse Grid: ' 1 2 3 ' 4 5 6 ' 7 8 9 ' and that the primary monitor is 5 and the secondary monitor is 4 secondaryRectangle.Left = lpPrimaryMonitorRectangle.Left - 1 secondaryRectangle.Top = lpPrimaryMonitorRectangle.Top secondaryRectangle.Right = lpPrimaryMonitorRectangle.Left - 1 secondaryRectangle.Bottom = lpPrimaryMonitorRectangle.Top ' if the secondary monitor were 6 ' secondaryRectangle.Left = lpPrimaryMonitorRectangle.Right + 1 ' etc. monitorHandle = MonitorFromRect secondaryRectangle, MONITOR_DEFAULTTONEAREST GetMonitorInfo monitorHandle, monitorInformation SecondaryMonitorRectangle = monitorInformation.rcWork End Function
Function ActiveWindowTitle() As String ' based on a script from the KnowBrainer Forum by Fmen Dim titleLength As Integer Dim title As String Dim foregroundWindow As Long foregroundWindow = GetForegroundWindow() titleLength = GetWindowText (foregroundWindow, title, 512) title = Left(title, titleLength) title = Trim (title) ActiveWindowTitle = title End Function
Function WaitForDialog() ' based on a script from the KnowBrainer Forum by monkey8 (Lindsay) Dim handle As Long handle = GetForegroundWindow 'gets the window handle of the current window Do While GetForegroundwindow = handle Wait 0.2 'the wait command frees up the CPU to do other work, must be present 'when the word document loads foreground window handle will change and the loop will exit Loop End Function
Function WaitForWindow (WindowTitle As String, WaitTime As Integer) As Integer ' based on a script from the KnowBrainer Forum by PG LTU Dim count As Integer
count = 1 Do Until InStr (GetWindowTitle, WindowTitle) > 0 DoEvents Wait 1 If count = WaitTime Then WaitForWindow = 0 Exit Function End If count = count + 1 Loop WaitForWindow = 1 End Function ____end of WindowsAPI.txt____ ------------------------- -Edgar |
|
|
|
![]() |
|
Edgar, this really looks like being a great post, if anyone could even read it. :-) -------------------------
|
|
|
|
![]() |
|
Very cool, would love to take a look at this. But the formatting… ------------------------- Dragon Professional Individual v15.6. Windows 10. Knowbrainer 2017. |
|
|
|
![]() |
|
If William Faulkner had been a programmer, his posts would have looked like this one of Edgar's! :-)
|
|
|
|
![]() |
|
Quite right, Matt. Both authors have a preference for the interior monologue. However, to me it looks even more inspired by James Joyce. -------------------------
|
|
|
|
![]() |
|
I have done this via Macro Express. It's relatively easy to scope Macro Express scripts to only be recognized in specified applications or windows. Make the Macro Express script triggered by, for example, F12. And then make a Dragon command that sends F12.
The Macro Express script looks something like this: Variable Set String %TopmostProgram% to topmost program name Switch( %TopmostProgram% ) Case: WINWORD.EXE // Do something End Case Case: OUTLOOK.EXE // Do something End Case Case: POWERPNT.EXE // Do something End Case Case: EXCEL.EXE // Do something End Case Case: FIREFOX.EXE // Do something End Case Case: ACRORD32.EXE // Do something End Case Default Case Text Box Display: Script does not yet handle "%TopmostProgram%" Macro Stop End Case End Switch |
|
|
|
![]() |
|
I think it would be similarly easy in AutoHotkey, although I haven't done it. |
|
|
|
![]() |
|
Everything looked fine until I clicked the Send button - will resend it tomorrow, sorry.
------------------------- -Edgar |
|
|
|
![]() |
|
I fixed up the missing line breaks in the original post.
------------------------- -Edgar |
|
|
FuseTalk Standard Edition v4.0 - © 1999-2022 FuseTalk™ Inc. All rights reserved.