uwp-xamlwinui-3winuiwinui-xaml

How to Move/drag a WinUI 3 Window with no title bar


I want to have a winUI 3 Window with no title bar and draggable from his entire client area.

Like I used to do in Winforms and WPF, I tried using a win32 call (the "sendMeaasge") (see code below). But it seems to be broken in WinUI 3 because it doesn't drag the window on the pointer pressed but only when the pointer is released.

below is the code using the "sendMessage" win32 api call. when using this, the window is moved only when the pointer is released.

public sealed partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();

        //Remove the title bar
        (AppWindow?.Presenter as OverlappedPresenter)?.SetBorderAndTitleBar(false, false);
        Content = new Grid() { Background = new SolidColorBrush(Colors.Transparent) };
        this.Content.PointerPressed += MainWindow_PointerPressed;
    }

    private void MainWindow_PointerPressed(object sender, PointerRoutedEventArgs e)
    {
        ReleaseCapture();
        var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
        SendMessage(hwnd, WM_NCLBUTTONDOWN, (IntPtr)HTCAPTION, IntPtr.Zero);
    }

    private const int WM_NCLBUTTONDOWN = 0xA1;
    private const int HTCAPTION = 0x2;

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool ReleaseCapture();
}

I also try using the pointerPressed, pointerMoved and pointerReleased and moving the window manually but is really not smooth enough. I would like the mouse and touch to both work, so that is why I don't want to use the position of the cursor to move the window.


Solution

  • You can try making the Window content as a TitleBar:

    <Window
        x:Class="WinUIApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="using:WinUIApp4"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Frame
            x:Name="ContentFrame"
            Background="Transparent">
            <TextBlock Text="Your content here..." />
        </Frame>
    
    </Window>
    
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            CustomizeWindow();
        }
    
        private void CustomizeWindow()
        {
            if (AppWindow?.Presenter is not OverlappedPresenter presenter)
            {
                return;
            }
    
            presenter.SetBorderAndTitleBar(hasBorder: false, hasTitleBar: false);
            ExtendsContentIntoTitleBar = true;
            SetTitleBar(this.ContentFrame);
        }
    }