Skip to content

Instantly share code, notes, and snippets.

@JaiganeshKumaran
Last active October 30, 2022 10:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JaiganeshKumaran/1a46d5536aceb3cd3b95c1fbb72179c8 to your computer and use it in GitHub Desktop.
Save JaiganeshKumaran/1a46d5536aceb3cd3b95c1fbb72179c8 to your computer and use it in GitHub Desktop.
Showcases how to get the handle (HWND) of an UWP app window
__interface __declspec(uuid("b74ea3bc-43c1-521f-9c75-e5c15054d78c")) IApplicationWindow_HwndInterop : IInspectable
{
// <summary>
// Gets the window handle of this AppWindow instance as a bit-blitted WindowId.
// </summary>
// <remarks>To get the actual ID, use [CoreAppWindowPreview::GetIdFromWindow](https://docs.microsoft.com/en-us/uwp/api/windows.ui.core.preview.coreappwindowpreview.getidfromwindow?view=winrt-22621). This method returns the handle (HWND) of the window.
HRESULT __stdcall get_WindowHandle(Windows::UI::WindowId* windowId) noexcept;
};
using IsWindow = int(__stdcall*)(HWND hwnd);
// Assumes that the variable appWindow represents an handle to Windows::UI::WindowManagement::AppWindow (https://docs.microsoft.com/en-us/uwp/api/windows.ui.windowmanagement.appwindow?view=winrt-22000).
Windows::UI::WindowId windowId;
IApplicationWindow_HwndInterop* appWindowInterop;
__abi_ThrowIfFailed(reinterpret_cast<IUnknown*>(appWindow)->QueryInterface<IApplicationWindow_HwndInterop>(&appWindowInterop));
__abi_ThrowIfFailed(appWindowInterop->get_WindowHandle(&windowId));
// Check if the returned window handle is valid.
auto module = LoadLibraryA("User32.dll");
auto func = reinterpret_cast<IsWindow>(GetProcAddress(module, "IsWindow"));
bool isValid = func(reinterpret_cast<HWND>(windowId.Value)) != false;
FreeLibrary(module);
appWindowInterop->Release();
@JaiganeshKumaran
Copy link
Author

Special thanks to @ahmed605 for helping out.

@dongle-the-gadget
Copy link

C#?

[ComImport, Guid("B74EA3BC-43C1-521F-9C75-E5C15054D78C"), InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
public interface IApplicationWindow_HwndInterop
{
  Windows.UI.WindowId WindowHandle { get; }
}

@JaiganeshKumaran
Copy link
Author

C#?

[ComImport, Guid("B74EA3BC-43C1-521F-9C75-E5C15054D78C"), InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
public interface IApplicationWindow_HwndInterop
{
  Windows.UI.WindowId WindowHandle { get; }
}

That looks right.

@jonwis
Copy link

jonwis commented Jun 8, 2022

@dongle-the-gadget
Copy link

Consider also https://docs.microsoft.com/en-us/windows/win32/api/corewindow/nn-corewindow-icorewindowinterop which is fully supported.

As a caution - Windows::UI::WindowId may not always be a bit-blitted HWND - WinAppSDK has methods to convert from HWND to WindowId, like https://docs.microsoft.com/en-us/windows/windows-app-sdk/api/win32/microsoft.ui.interop/nf-microsoft-ui-interop-getwindowidfromwindow for ABI consumers and https://docs.microsoft.com/en-us/windows/apps/api-reference/cs-interop-apis/microsoft.ui/microsoft.ui.win32interop for C#.

#1: This is for AppWindow, not CoreWindow
#2: Windows App SDK doesn't support UWP.

@JaiganeshKumaran
Copy link
Author

JaiganeshKumaran commented Jul 9, 2022

@jonwis My bad, I confused the two, it looks like this interface is an undocumented one to get the handle (not ID) of an UWP AppWindow but for some reason, it seems to return the HWND as a bit-blitted Windows.UI.WindowId (maybe because it's a WinRT interface, not classic COM so HWND type isn't available?). I searched a bit and turned out CoreAppWindowPreview::GetIdFromWindow but as an integer. I'll update the description and comments in the snippet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment