Currently the "Perform a Window Function" actions allow the user to change the "show" state of a given window or process based on its title information or process name, respectively. However there is not a way to
obtain the show state of a given window. Below you will find a profile and associated C# inline function code for doing just that. The use cases may be narrow, but I figured I'd share it anyway.
Please note:
- In its current state this profile will not be able to search for hidden windows. An example of this is making the command search for "VoiceAttack" when VoiceAttack is minimized to the system tray. This is because the window handle (which is needed to make the inline function work) for a hidden window is more difficult to obtain than for a non-hidden window. There are ways around this, but I choose not to include this functionality at this time for the sake of simplicity.
- The profile is set up so that if there are multiple windows that have titles that match your search term only the last match (whatever is programmatically encountered last by the inline function) will be outputted to the event log. Though I've included some code lines (commented out) in the inline function that would output every result to the log. I figured folks would have a reasonably specific search term and then would want to pass that information back to VoiceAttack for further actions. Obviously feel free to change it however you see fit.
Cheers!
VoiceAttack Command Code:// Define window title text you want to search for
Set Text [TitleSearchText] to 'Notepad'
// Define type of text search you want to perform (case sensitive or insensitive)
Set Boolean [TitleSearchSensitivity] to True
// C# inline function for obtaining window state for all windows containing title text matching TitleSearchText
Inline C# Function: Get window state for all windows matching search term, wait until execution finishes
// Output result of window title search and window state (if available)
// If the inline function finds multiple matches only the final match will be outputted here
Write '[Blue] Window Title = {TXT:FullWindowTitle} ; Window State = {TXT:WindowShowState}' to log
Inline Function Code:Referenced Assemblies = System.dll;System.Drawing.dll;using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
public class VAInline
{
public void main()
{
string searchTerm = VA.GetText("TitleSearchText"); // Retrieve window title text to search for from VoiceAttack text variable
bool CaseSensitiveSearch = (bool)VA.GetBoolean("TitleSearchSensitivity"); // Retrieve desired search case sensitivity from VoiceAttack boolean variable
string windowState = ""; // Initialize string variable for storing window state information
string FullWindowTitle = ""; // Initialize string variable for storing complete window title
foreach (Process pList in Process.GetProcesses()) // Loop through all active processes
{
// Check if searchTerm is found in window title
bool WindowSearchResult; // Initialize boolean variable for storing result of the window title search
if (CaseSensitiveSearch == true) // Check if case sensitive search was requested
WindowSearchResult = pList.MainWindowTitle.Contains(searchTerm); // Case-sensitive searchTerm comparison
else
WindowSearchResult = pList.MainWindowTitle.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0; // Case-insensitive searchTerm comparison
if (WindowSearchResult) // Check if the searchTerm was found within a window's title text
{
WINDOWPLACEMENT placement = new WINDOWPLACEMENT(); // Create new WINDOWPLACEMENT instance
StringBuilder title = new StringBuilder(256); // Create new StringBuilder instance
GetWindowPlacement(pList.MainWindowHandle, ref placement); // Get the WINDOWPLACEMENT data using the inputted window handle
GetWindowText(pList.MainWindowHandle, title, 256); // Get the window title using the inputted window handle
FullWindowTitle = title.ToString(); // Store full title of found window
switch (placement.showCmd) // switch statement for processing different window "show" states
{
case 1: // Window placement code "1"
windowState = "Normal";
break; // Terminate switch statement
case 2: // Window placement code "2"
windowState = "Minimized";
break; // Terminate switch statement
case 3: // Window placement code "3"
windowState = "Maximized";
break; // Terminate switch statement
}
VA.SetText("FullWindowTitle", FullWindowTitle); // Store full window title text in VoiceAttack variable
VA.SetText("WindowShowState", windowState); // Store window show state in VoiceAttack variable
//VA.WriteToLog("Window Title = " + FullWindowTitle + " ; Window State = " + windowState, "green"); // Output info to VoiceAttack event log
}
}
if (windowState == "") // Check if windowState still is blank
{
FullWindowTitle = "Not Found"; // Store search result in VoiceAttack variable
windowState = "N/A"; // Store search result in VoiceAttack variable
VA.SetText("FullWindowTitle", FullWindowTitle); // Store full window title text in VoiceAttack variable
VA.SetText("WindowShowState", windowState); // Store window show state in VoiceAttack variable
//VA.WriteToLog("Window Title = " + FullWindowTitle + " ; Window State = " + windowState, "red"); // Output info to VoiceAttack event log
}
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
private struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
public System.Drawing.Point ptMinPosition;
public System.Drawing.Point ptMaxPosition;
public System.Drawing.Rectangle rcNormalPosition;
}
}
// References:
// https://stackoverflow.com/questions/1003073/how-to-check-whether-another-app-is-minimized-or-not
// https://stackoverflow.com/questions/13547639/return-window-handle-by-its-name-title
// https://stackoverflow.com/questions/444798/case-insensitive-containsstring
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms632611(v=vs.85).aspx