2

In my code I have a message class that I would like to 'Find' from another process.

class MyWindow : public CWnd
{
public:
  MyWindow::MyWindow(LPCTSTR pszClassName)
  {
    auto wcn = ::AfxRegisterWndClass(NULL);
    auto created = this->CreateEx(0, wcn, pszClassName, 0, 0, 0, 0, 0, HWND_MESSAGE, 0);
  }
};

Then somewhere in my main app.

...
auto pszClassName = _T("MyWindowClass");
auto wnd = new MyWindow(pszClassName);

auto p = FindWindow(pszClassName, nullptr); // = nullptr

// or using FindWindowExW( ... )
p = FindWindowExW(nullptr, nullptr, pszClassName, nullptr);// = nullptr
p = FindWindowExW(HWND_MESSAGE, nullptr, pszClassName, nullptr);// = nullptr

So, regardless what I do, I never seem to 'Find' the created window.

How can I create a window that can be 'Found' using FindWindow[Ex]

Simon Goodman
  • 1,174
  • 1
  • 8
  • 35
  • 2
    When you create your window, you use `pszClassName` not as class name, but window name. The class name is in `wcn`, which you would have to pass to `FindWindow`. – Karsten Koop Jun 24 '16 at 08:56
  • So basically I really need to create my own ```WNDCLASS``` and call ```RegisterClass( ...)``` – Simon Goodman Jun 24 '16 at 09:04
  • You could either call `RegisterClass` with your `pszClassName`, or use the returned value of `AfxRegisterWndClass` for `FindWindow`, which might be better as `AfxRegisterWndClass` probably makes sure the name is unique. – Karsten Koop Jun 24 '16 at 09:06
  • Maybe UIPI is restricting you? https://blogs.msdn.microsoft.com/vishalsi/2006/11/30/what-is-user-interface-privilege-isolation-uipi-on-vista/ – Daniel Jun 24 '16 at 09:44

1 Answers1

2

I'm using a VS2013 console app. I've modified your code slightly to create a normal window and a message-only window and find both their handles by class name.

Output:

Normal window=00000000003A06FE Message-only window=00000000001F06CA
FindWindow=00000000003A06FE
FindWindowEx=00000000003A06FE
FindWindowEx(HWND_MESSAGE,...)=00000000001F06CA

Code:

typedef std::basic_string<TCHAR> tstring;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

class MyWindow //: public CWnd
{
public:
    tstring className;
    HWND hwnd;
    HWND hwndMsgOnly;
    HWND find1;
    HWND find2;
    HWND find3;

    MyWindow::MyWindow(LPCTSTR pszClassName)
    {
        className = pszClassName;

        //auto wcn = ::AfxRegisterWndClass(NULL);
        //auto created = this->CreateEx(0, wcn, pszClassName, 0, 0, 0, 0, 0, HWND_MESSAGE, 0);

        // For a console app, `hInstance` is the instance of the program
        HINSTANCE hInstance = GetModuleHandle(0);

        WNDCLASSEX windowClass;
        windowClass.lpszClassName = pszClassName;
        windowClass.cbClsExtra = NULL;
        windowClass.cbWndExtra = NULL;
        windowClass.cbSize = sizeof(WNDCLASSEX);
        windowClass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(150, 0, 0));
        windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
        windowClass.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION));
        windowClass.hIconSm = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 16, 16, NULL);
        windowClass.hInstance = hInstance;
        windowClass.lpfnWndProc = WindowProc;
        windowClass.lpszMenuName = NULL;
        windowClass.style = CS_VREDRAW | CS_HREDRAW;
        RegisterClassEx(&windowClass);
        hwnd = CreateWindowEx(NULL, pszClassName, _T("Basic Window"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 500, 500, NULL, NULL, hInstance, NULL);
        hwndMsgOnly = CreateWindowEx(NULL, pszClassName, _T("Dummy name"), 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
    }
};

void window_test(MyWindow & wnd)
{
    LPCTSTR pszClassName = wnd.className.c_str();
    wnd.find1 = FindWindow(pszClassName, nullptr); // = nullptr for OP version; okay for this version

    // or using FindWindowExW( ... )
    /**
        HWND hwndParent is a handle to the parent window whose child windows are to be searched.
        If hwndParent is NULL, the function uses the desktop window as the parent window.The function searches among windows that are child windows of the desktop.
        If hwndParent is HWND_MESSAGE, the function searches all message-only windows.
    **/
    HWND hWndParent = nullptr;
    wnd.find2 = FindWindowExW(hWndParent, nullptr, pszClassName, nullptr);// = nullptr for OP version; okay for this version
    hWndParent = HWND_MESSAGE;
    wnd.find3 = FindWindowExW(hWndParent, nullptr, pszClassName, nullptr);// = nullptr for OP version; finds the message-only window in this version
}

void main()
{
    MyWindow wnd(_T("test_window"));
    cout << "Normal window=" << wnd.hwnd << " Message-only window=" << wnd.hwndMsgOnly << endl;
    window_test(wnd);
    cout << "FindWindow=" << wnd.find1 << endl;
    cout << "FindWindowEx=" << wnd.find2 << endl;
    cout << "FindWindowEx(HWND_MESSAGE,...)=" << wnd.find3 << endl;
}
John D
  • 1,627
  • 1
  • 11
  • 10