microsoft / microsoft-ui-xaml

Windows UI Library: the latest Windows 10 native controls and Fluent styles for your applications
MIT License
6.18k stars 667 forks source link

How To delate the entire titlebar #9750

Closed Tartarusome closed 18 hours ago

Tartarusome commented 3 weeks ago

I used win32 dll to set the height of titlebar to 0, which is equal to Windows.Style="None" if WPF. but the window would reserve a region with colored background, like the red region below. image

i write SetLayeredWindowAttributes(hWnd, 0, 0, LWA_ALPHA); but it doesnt work.

Here is my cs-behind `public sealed partial class DockWindow : Window { public DockWindow() { this.InitializeComponent(); //style=none IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);

    // Get the window's style
    int style = GetWindowLongPtr(hWnd, GWL_STYLE).ToInt32();

    // Modify the window's style to remove the caption
    SetWindowLongPtr(hWnd, GWL_STYLE, new IntPtr(style & ~(WS_CAPTION)));

    // Get the window's position and size
    RECT windowRect;
    GetWindowRect(hWnd, out windowRect);

    // Set the window's position and size to hide the title bar
    SetWindowPos(
        hWnd,
        IntPtr.Zero,
        windowRect.Left,
        windowRect.Top - 24,
        windowRect.Right - windowRect.Left,
        windowRect.Bottom - windowRect.Top + 24,
        SWP_NOZORDER | SWP_FRAMECHANGED
    );

    // Set the window's transparency
    SetLayeredWindowAttributes(hWnd, 0, 0, LWA_ALPHA); // 200 is the alpha value (0-255)
}

private const int GWL_STYLE = -16;
private const int WS_CAPTION = 0x00C00000;
private const int SWP_NOZORDER = 0x0004;
private const int SWP_FRAMECHANGED = 0x0020;
private const int LWA_ALPHA = 0x00000002;

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);

[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true)]
private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

[DllImport("user32.dll", SetLastError = true)]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

[DllImport("user32.dll", SetLastError = true)]
private static extern bool SetWindowPos(
    IntPtr hWnd,
    IntPtr hWndInsertAfter,
    int X,
    int Y,
    int cx,
    int cy,
    uint uFlags
);

[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

[DllImport("user32.dll", SetLastError = true)]
private static extern bool SetLayeredWindowAttributes(
    IntPtr hWnd,
    uint crKey,
    byte bAlpha,
    uint dwFlags
);

}`

castorix commented 3 weeks ago

With 1.4, I use OverlappedPresenter.SetBorderAndTitleBar(false, false) and OverlappedPresenter.IsResizable = false (removes WS_THICKFRAME)

Tartarusome commented 3 weeks ago

With 1.4, I use OverlappedPresenter.SetBorderAndTitleBar(false, false)在 1.4 中,我使用 OverlappedPresenter.SetBorderAndTitleBar(false, false) and OverlappedPresenter.IsResizable = false (removes WS_THICKFRAME)和 OverlappedPresenter.IsResizable = false(删除WS_THICKFRAME)

It works on 1.5.4 too, but how can I resize the window?Must I create a small triangle in the corner by myself?

castorix commented 3 weeks ago

It works on 1.5.4 too, but how can I resize the window?Must I create a small triangle in the corner by myself?

A way is to let it resizable and subclass it (SetWindowSubclass) to handle _WMNCCALCSIZE (mainly to increment the first RECT.top to reduce the size of top border) I tested on Windows 10 and I had to increment left and decrement right and bottom too (quick test with random values, should be calculated with APIs like AdjustWindowRect...) and set lParam to -1 in _WMNCACTIVATE, as MSDN says... and also SetWindowPos in Activated event for the first time the window is displayed) :

NoCaption_Resizable

Tartarusome commented 3 weeks ago

It works on 1.5.4 too, but how can I resize the window?Must I create a small triangle in the corner by myself?它也适用于 1.5.4,但是如何调整窗口大小?我必须自己在角落里创建一个小三角形吗?

A way is to let it resizable and subclass it (SetWindowSubclass) to handle _WMNCCALCSIZE (mainly to increment the first RECT.top to reduce the size of top border)一种方法是让它可调整大小并对其进行子类化 (SetWindowSubclass) 以处理WM_NCCALCSIZE(主要是增加第一个 RECT.top 以减小顶部边框的大小) I tested on Windows 10 and I had to increment left and decrement right and bottom too (quick test with random values, should be calculated with APIs like AdjustWindowRect...) and set lParam to -1 in _WMNCACTIVATE, as MSDN says... and also SetWindowPos in Activated event for the first time the window is displayed) :我在 Windows 10 上进行了测试,我也必须向左递增,向右递减右键和下键(使用随机值进行快速测试,应该使用 AdjustWindowRect 等 API 进行计算...)并在 WM_NCACTIVATE 年将 lParam 设置为 -1,正如 MSDN 所说......以及首次显示窗口时激活事件中的 SetWindowPos):

NoCaption_Resizable NoCaption_Resizable

Hey bro. I just found a perfect way.It looks like the following: image This code would totally hide the title bar and the three caption buttons, but preserve a 32 or maybe 48 px rectangle overlay that is draggable and transparent.And you can use SetTitleBar(rootGrid); and set it to be interactive, then you can pretend the rootGrid is the content of a no-titlebar-window. MS Learn Document

Here is the code. public DockWindow() { this.InitializeComponent(); ExtendsContentIntoTitleBar = true; SetTitleBar(Part_TitleBar); var TestTitleBar = AppWindow.TitleBar; **TestTitleBar.PreferredHeightOption = TitleBarHeightOption.Collapsed;** }

codendone commented 18 hours ago

It sounds like this has been solved.