Move a window with a title that matches a pattern in C#

[example]

The example Set another application’s size and position in C# uses the FindWindow API function to find a window with a given title. Unfortunately FindWindow only finds the window if the title is an exact match. If you only know part of the title or if there are extra spaces or other characters in the title, FindWindow won’t find it.

This example enumerates the desktop windows and looks for one with a title that matches a regular expression. The following code shows how the FindWindowTitleMatch method starts the process.

// The target window's pattern to match
// and the found handle and title.
private static string MatchPattern;
private static IntPtr MatchedHandle;
private static string MatchedTitle;

// Return a list of the desktop windows' handles and titles.
public static void FindWindowTitleMatch(
   string pattern, out IntPtr handle, out string title)
{
    MatchPattern = pattern;
    MatchedHandle = IntPtr.Zero;
    MatchedTitle = "";

    EnumDesktopWindows(IntPtr.Zero, FilterCallback, IntPtr.Zero);

    handle = MatchedHandle;
    title = MatchedTitle;
}

The FindWindowTitleMatch method saves the pattern that it should match in the MatchPattern variable. It also initializes the MatchedHandle and MatchedTitle values to defaults that it will return if it cannot find a matching window.

The method then calls the EnumDesktopWindows method passing it the FilterCallback method as the method that the API function should call for each of the windows that it enumerates.

After EnumDesktopWindows finishes, the program copies the values contained in the MatchedHandle and MatchedTitle variables into the method’s return variables.

The following code shows the FilterCallback method that is called by the EnumDesktopWindows API function.

// Select the first window that matches the target pattern.
private static bool FilterCallback(IntPtr hWnd, int lParam)
{
    // Get the window's title.
    StringBuilder sb_title = new StringBuilder(1024);
    int length = GetWindowText(hWnd, sb_title, sb_title.Capacity);
    string title = sb_title.ToString();

    // If the window is visible and has a title, see if it matches.
    if (IsWindowVisible(hWnd) &&
        string.IsNullOrEmpty(title) == false)
    {
        if (title.Matches(MatchPattern))
        {
            MatchedHandle = hWnd;
            MatchedTitle = title;
            // Return false to indicate that we
            // don't need to continue enumerating windows.
            return false;
        }
    }

    // Return true to indicate that we
    // should continue enumerating windows.
    return true;
}

The method uses the GetWindowText API function to get the current window’s title. If the window is visible and the title is not blank, the method uses the Matches string extension to determine whether the title matches the target pattern. (For information about the Matches string extension, see Make a string extension to determine whether a string matches a regular expression in C#.)

If the title matches, the method saves its handle and title in the MatchedHandle and MatchedTitle variables and returns false to tell EnumDesktopWindows that it doesn’t need to continue enumerating windows. If the title doesn’t match, the method returns true to tell EnumDesktopWindows that it hasn’t found a match yet and that it should continue enumerating other windows.

After it finds a matching window, the main program uses the SetWindowPlacement method to restore the window so it’s not minimized or maximized. It then uses the SetWindowPosition method to move the window to the desired position.

As in the example Set another application’s size and position in C#, be careful where you move windows. If you move a window off of the screen, you’ll need to use this program or something similar to get it back.

Download the example program to see additional details.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in API, miscellany, regular expressions, system and tagged , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *