1

I am using FindWindow in an mfc application.

HWND hWnd = ::FindWindow(NULL, _T("foobar v5"));

I would like to use FindWindow with wildcards so that I can match just foobar.

Thanks

dangerousdave
  • 6,331
  • 8
  • 45
  • 62

2 Answers2

6

You will have to create your own implementation which should be based on EnumWindows, GetWindowText and GetWindowTextLength which then must allow the wildcards.

#include <Windows.h>
#include <iostream>
#include <string>
#include <vector>

struct FindWindowData {
    FindWindowData( TCHAR const * windowTitle )
        : WindowTitle( windowTitle )
        , ResultHandle( 0 )
    {}

    std::basic_string<TCHAR> WindowTitle;
    HWND ResultHandle;
};

BOOL CALLBACK FindWindowImpl( HWND hWnd, LPARAM lParam ) {
    FindWindowData * p = reinterpret_cast<FindWindowData*>( LongToPtr( lParam ) );
    if( !p ) {
        // Finish enumerating we received an invalid parameter
        return FALSE;
    }

    int length = GetWindowTextLength( hWnd ) + 1;
    if( length > 0 ) {
        std::vector<TCHAR> buffer( std::size_t( length ), 0 );      
        if( GetWindowText( hWnd, &buffer[0], length ) ) {
                    // Comparing the string - If you want to add some features you can do it here
            if( _tcsnicmp( &buffer[0], p->WindowTitle.c_str(), min( buffer.size(), p->WindowTitle.size() )  ) == 0 ) {
                p->ResultHandle = hWnd;
                // Finish enumerating we found what we need
                return FALSE;
            }
        }
    }
    // Continue enumerating
    return TRUE;
}

// Returns the window handle when found if it returns 0 GetLastError() will return more information
HWND FindWindowStart( TCHAR const * windowTitle ) {

    if( !windowTitle ) {
        SetLastError( ERROR_INVALID_PARAMETER );
        return 0;
    }

    FindWindowData data( windowTitle );
    if( !EnumWindows( FindWindowImpl, PtrToLong(&data) ) && data.ResultHandle != 0 ) {
        SetLastError( ERROR_SUCCESS );
        return data.ResultHandle;
    }

    // Return ERROR_FILE_NOT_FOUND in GetLastError
    SetLastError( ERROR_FILE_NOT_FOUND );
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::cout << "HWND: " << FindWindowStart(TEXT("foobar ") );
    std::cout << "  GetLastError() = " << GetLastError() << std::endl;
    return 0;
}
Vinzenz
  • 2,749
  • 17
  • 23
  • Thanks for the reply Vinzenz, do you have any examples? or know where i could find some? – dangerousdave Oct 13 '10 at 10:35
  • I have just updated the post how you can find a window which starts with the name you wanted. You can extend the example if you want – Vinzenz Oct 13 '10 at 11:08
  • And in what form are wildcards given? – nanofarad Dec 30 '12 at 00:01
  • Well as written there, there are no wildcards used for the example I posted. It just finds the first window which matches the requirement. In this case the requirement was to match the beginning of the title. If you want to apply regex on it, it's possible as well, I have commented the code where it is possible – Vinzenz Dec 31 '12 at 14:35
1

Unfortunately, FindWindow() does not support wildcards.

Did you try matching the window class name instead of its title? You can use a tool like Spy++ to find out the class name of the foobar main window.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479