2

I am working on a WinUI 3 demo using C++.

enter image description here

I want to get a Main or Native Window Handler to open a Picker within a Page.

The code block which I am using works fine on Window but it does not work on Page.

auto windowNative{ this->try_as<::IWindowNative>()};
winrt::check_bool(windowNative);
HWND hWnd{ 0 };
windowNative->get_WindowHandle(&hWnd);

Help me to get MainWindow Handler in Page1.xaml.cpp

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
Gaurang Dave
  • 3,956
  • 2
  • 15
  • 34
  • Only Window implements IWindowNative, you need to pass the window somehow or consider there's only one (depends on your application) https://stackoverflow.com/questions/74273875/retrive-window-handle-in-class-library-winui3 – Simon Mourier Feb 13 '23 at 13:37
  • @SimonMourier I have only one window on my app and rest are pages. Can you show how to do it using c++ ? – Gaurang Dave Feb 13 '23 at 13:44
  • The C# code is actually pure interop so it's easy to translate back, for example https://stackoverflow.com/questions/1888863/how-to-get-main-window-handle-from-process-id/1888944#1888944 – Simon Mourier Feb 13 '23 at 14:02
  • @SimonMourier It did not work. Can you share some code snippet or an example? I am C# developer, not c++. It will be good if you can share an easy to understand example or code block. – Gaurang Dave Feb 13 '23 at 17:47

1 Answers1

1

Only Window implements IWindowNative, so you need to pass the window reference around, or if you're sure there's only one Window in your process, you can use a code like this:

HWND GetProcessFirstWindowHandle(DWORD pid = 0)
{
    struct ProcessWindow { DWORD pid;  HWND hWnd; } pw = {};
    pw.pid = pid ? pid : GetCurrentProcessId();
    EnumWindows([](auto hWnd, auto lParam)
        {
            DWORD pid;
            GetWindowThreadProcessId(hWnd, &pid);
            if (pid != ((ProcessWindow*)lParam)->pid)
                return TRUE;

            ((ProcessWindow*)lParam)->hWnd = hWnd;
            return FALSE;
        }, (LPARAM)&pw);
    return pw.hWnd;
}

And for example, call it simply like this:

void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
{
    auto hwnd = GetProcessFirstWindowHandle();
}

You can also add some check on class name, like what's done in this answer (it's C# but the code is already using interop to access native Windows APIs) : Retrive Window Handle in Class Library WinUI3

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • Hi Simon. Can you help me further with opening a file picker? I am still facing this issue - https://github.com/microsoft/microsoft-ui-xaml/issues/2716 . Its a couple of years old bug and discussion but its not working for me either. – Gaurang Dave Feb 14 '23 at 04:49
  • I raised another question - https://stackoverflow.com/questions/75443728/fileopenpicker-returns-memory-error-in-winui3-using-c – Gaurang Dave Feb 14 '23 at 05:14