Proposal: Window Width/Height in Desktop
Proposal: Support Window Width/Height when in Desktop
Summary
For WinUI in Desktop apps:
- Support setting Width and Height on
Windowin XAML. - Support setting d:DesignWidth and d:DesignHeight on
Windowin XAML.
<Window Width="1200" Height="600"
d:DesignWidth="1000" d:DesignHeight="500">
Rationale
Many developers doing WinUI in Desktop will have a background in WPF and/or simply not be interested in doing a responsive design -- this is "in Desktop" after all. Without the ability to set Window size in a traditional way, I believe adoption will suffer due to too much forced change.
@JVimes, thanks for opening this request. I believe there should be APIs that allow developers to do this. The APIs should work for both, UWP and Desktop.
@marb2000 It appears not:

@JVimes, thanks for opening this request. I believe there should be APIs that allow developers to do this. The APIs should work for both, UWP and Desktop.
I'm wondering if there is any API to manage window size/position at all?
While these APIs doesn't exist in Desktop WinUI 3 apps, I published a sample to workaround it using the Win32 APIs.
Using the SetWindowPos API you can set the size and/or the position of a Window object.
Thanks for the workaround, @marb2000. The code also looks like a starting point to address the problem.
I assume there's no progress to report on setting size for a UWP/Desktop window? Couldn't get that SetWindowPos example to work in my basic app unfortunately.
Is there a workaround for getting the current size? I am working on an app whose layout is dependent on physical window size and just want to read the width of the window and am struggling to do so.
Is there a workaround for getting the current size? I am working on an app whose layout is dependent on physical window size and just want to read the width of the window and am struggling to do so.
Would that size include any window borders, and titlebar height, or just the client drawing area?
Ideally, just the client size.
On Mon, Apr 12, 2021, 21:24 Martin Anderson @.***> wrote:
Is there a workaround for getting the current size? I am working on an app whose layout is dependent on physical window size and just want to read the width of the window and am struggling to do so.
Would that size include any window borders, and titlebar height, or just the client drawing area?
โ You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/microsoft/microsoft-ui-xaml/issues/2731#issuecomment-818362600, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA5H6G26Q5AANEXOWVVXYP3TIOMNHANCNFSM4OFIVB3Q .
You can find a couple of helpers in GitHub that tell you the width and height of the Window. using Win32 APIs, WinUIEx from @dotMorten and DeskopWindow.
To get the size of the client area you should ask for the size of the XamlRoot. You can get the XamlRoot property from any UIElement in the layout. It could be than the XamlRoot is still null in the constructor, so I recommend use Loaded for instance.
The AppWindow class has methods Move, Resize and MoveAndResize. These can be used to set the size and location for windows. They cannot be used to prevent the user from resizing windows, though.
You can get an AppWindow instance from a Window instance via:
IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window);
WindowId windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd);
AppWindow appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
The
AppWindowclass has methodsMove,ResizeandMoveAndResize. These can be used to set the size and location for windows. They cannot be used to prevent the user from resizing windows, though.You can get an
AppWindowinstance from aWindowinstance via:IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window); WindowId windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd); AppWindow appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
I confirm it works. Thanks! But what exactly are this methods? why it's so difficult to obtain such a simple feature?
๐ ๐ ๐ UI library without ability to change window size.
this is painful, and as a person trying to write in C++ i have no clue as to what i can possibly use/do to set window size
this is painful, and as a person trying to write in C++ i have no clue as to what i can possibly use/do to set window size
As it has been said AppWindow.Resize works correctly. And if you use C++, you have access without P/Invoke to all the Win32 APIs (SetWindowPos, MoveWindow, SetWindowPlacement, etc...)
The
AppWindowclass has methodsMove,ResizeandMoveAndResize. These can be used to set the size and location for windows. They cannot be used to prevent the user from resizing windows, though.You can get an
AppWindowinstance from aWindowinstance via:IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window); WindowId windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd); AppWindow appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
You can use a Presenter for that
OverlappedPresenter overlappedPresenter = appWindow.Presenter as OverlappedPresenter;
overlappedPresenter.IsResizable = false;
Note The
AppWindow.Resize()requires the size to be already scaled using DPI of the monitor. It does not used the device independent values as WPF does.
@jozefizso Correct. The AppWindow API is not really a WinUI3 API - It's a generic Windows API (which is why I was rather disappointed seeing a recent release exposing AppWindow as a property directly on Window to avoid the code @eduardobragaxz has above), instead of just providing a first-class set of properties and methods directly on the WinUI Window class that is fully DPI aware.
This is one of the reasons I created the WinUIEx extension to help with this stuff, as it's rather complicated to having to deal with.
Aren't they working on converging Window and AppWindow?
DesignHeight and DesignWidth would make sense if Microsoft actually bothered to add a designer for WinUI 3
@eduardobragaxz From what I gather, they are converging behaviour on functionality exposed through both. This should essentially mean that Window.ExtendsContentIntoTitleBar will do the same thing as AppWindowTitleBar.ExtendsContentIntoTitleBar and Window.Title will do the same thing as AppWindow.Title. Maybe they will implement it in terms of Window calling through to AppWindow. For converging Window and AppWindow, that would be impossible if they want to keep to the currently documented fact that AppWindow is intended to be framework agnostic. Adding the Xaml functionality would go against this. We'll see how things go, but considering UWP WinUI, I wouldn't be surprised if Window never picks up anything else to control the underlying window and I would also not be surprised if eventually Window.Title and Window.ExtendsContentIntoTitleBar will end up marked as deprecated with the recommendation to use AppWindow.
@DarranRowe ohhh that makes a lot more sense ๐ It feels like a good thing.
I know it isn't, but using AppWindow feels weirdly hacky
Am I actually reading that there is no sane way to set the window size of a WinUI app? that seems... crazy. Am I crazy for thinking it's crazy? Or maybe I just can't read because I've been coding all day.
Am I actually reading that there is no sane way to set the window size of a WinUI app? that seems... crazy. Am I crazy for thinking it's crazy? Or maybe I just can't read because I've been coding all day.
For now you can only do it in code. On the Window code behind you can do
this.AppWindow.Resize(new(width, height))
Make sure you account for dpi
var scale = (this.Content as FrameworkElement).XamlRoot.RasterizationScale;
this.AppWindow.Resize(new((int)width*scale, (int)height*scale))
This is one reason that IMHO the AppWindow APIs really shouldnโt have been a property directly on Window since it doesnโt really understand WinUI and should have been reserved for non-WinUI scenarios.
Hey thank you for the information, for some reason (after trying to code for 10 hours straight), I wasn't putting together that I needed to sue this new (w, h) data structure in the Resize.
Sorry my message was a bit salty, I am a web developer trying to do Windows UI layout and I am finding it a bit tedious to say the least ๐
In my main app, I will be using a web UI and just using sockets, etc to do most of the work, but even though my layout is minimal, it's still frustrating when I can't make it look nice hehe.
I've just been bit by this as well while trying to render a splash screen with fixed dimensions. While trying to fix it by resizing the window using window.AppWindow().ResizeClient(), I hit another issue as window.Content().RasterizationScale() was being reported as 1.0 on a high-DPI display.
Having a Window API to accomplish this using logical pixels would be fantastic!
To account for the seemingly incorrect scale reported by UIElement.RasterizationScale(), I'm instead using GetDpiForMonitor() to compute the correct scaling factor for the monitor, scale = float(dpi) / 96.
To get the monitor associated with a window before and/or after activation, I'm using the following methods:
-
Primary monitor:
MonitorFromPoint({0, 0}, MONITOR_DEFAULTTOPRIMARY); -
Monitor at
(x, y)before activation:MonitorFromPoint({x, y}, MONITOR_DEFAULTTONEAREST); -
Monitor associated with window after activation:
MonitorFromWindow(GetWindowFromWindowId(window.AppWindow().Id()), MONITOR_DEFAULTTONEAREST);
With that, and as others have pointed out, positioning and resizing the window can be done like this, making sure to premultiply the coordinates and dimensions by scale:
window.AppWindow().Move({int(x), int(y)});
window.AppWindow().ResizeClient({int(width), int(height)});
Keep in mind that this is all C++/WinRT. I'd be so happy with a direct Window API that would hide all of the above complexity ๐
@kasperisage you should use the scale off XamlRoot
@dotMorten How does that work with multi-monitor setups where the monitors have different DPIs? To be clear, I have to both move and resize the window, taking into account the DPI of the monitor that corresponds to the final position of the window. Both the position and dimension are provided in logical pixels.