terminal/src/cascadia/WindowsTerminal/NonClientIslandWindow.h
greg904 5dfc021d8e Use standard 1px window borders on NC Island Window (#3394)
We take the standard window frame except that we remove the top part
(see `NonClientIslandWindow::_OnNcCalcSize`), then we put little 1 pixel
wide top border back in the client area using
`DwmExtendFrameIntoClientArea` and then we put the XAML island and the
drag bar on top.

Most of this PR is comments to explain how the code works and also
removing complex code that was needed to handle the weird cases when the
borders were custom.

I've also refactored a little bit the `NonClientIslandWindow` class.

* Fix DwmExtendFrameIntoClientArea values
* Fix WM_NCHITTEST handling
* Position the XAML island window correctly
* Fix weird colors in drag bar and hide old title bar buttons
* Fix the window's position when maximized
* Add support for dark theme on the frame
* DRY shared code between conhost and new terminal
* Fix drag bar and remove dead code
* Remove dead code and use cached DPI
* Refactor code
* Remove impossible TODO
* Use system metrics instead of hardcoding resize border height
* Use theme from app settings instead of system theme. Improve comments. Remove unused DWM frame on maximize.
* Fix initial position DPI handling bug and apply review changes
* Fix thick borders with DPI > 96

Closes #3064.
Closes #1307.
Closes #3136.
Closes #1897.
Closes #3222.
Closes #1859.
2019-11-04 15:45:40 -08:00

79 lines
2.9 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Module Name:
- NonClientIslandWindow.h
Abstract:
- This class represents a window hosting two XAML Islands. One is in the client
area of the window, as it is in the base IslandWindow class. The second is in
the titlebar of the window, in the "non-client" area of the window. This
enables an app to place xaml content in the titlebar.
- Placing content in the frame is enabled with DwmExtendFrameIntoClientArea. See
https://docs.microsoft.com/en-us/windows/desktop/dwm/customframe
for information on how this is done.
Author(s):
Mike Griese (migrie) April-2019
--*/
#include "pch.h"
#include "IslandWindow.h"
#include "../../types/inc/Viewport.hpp"
#include <dwmapi.h>
#include <wil/resource.h>
class NonClientIslandWindow : public IslandWindow
{
public:
// this is the same for all DPIs
static constexpr const int topBorderVisibleHeight = 1;
NonClientIslandWindow(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme) noexcept;
virtual ~NonClientIslandWindow() override;
virtual void OnSize(const UINT width, const UINT height) override;
[[nodiscard]] virtual LRESULT MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept override;
void Initialize() override;
void OnAppInitialized() override;
void SetContent(winrt::Windows::UI::Xaml::UIElement content) override;
void SetTitlebarContent(winrt::Windows::UI::Xaml::UIElement content);
void OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme) override;
private:
std::optional<COORD> _oldIslandPos;
winrt::TerminalApp::TitlebarControl _titlebar{ nullptr };
winrt::Windows::UI::Xaml::UIElement _clientContent{ nullptr };
wil::unique_hbrush _backgroundBrush;
COLORREF _backgroundBrushColor;
winrt::Windows::UI::Xaml::Controls::Border _dragBar{ nullptr };
wil::unique_hrgn _dragBarRegion;
winrt::Windows::UI::Xaml::ElementTheme _theme;
bool _isMaximized;
int _GetResizeHandleHeight() const noexcept;
RECT _GetDragAreaRect() const noexcept;
int _GetTopBorderHeight() const noexcept;
[[nodiscard]] LRESULT _OnNcCreate(WPARAM wParam, LPARAM lParam) noexcept override;
[[nodiscard]] LRESULT _OnNcCalcSize(const WPARAM wParam, const LPARAM lParam) noexcept;
[[nodiscard]] LRESULT _OnNcHitTest(POINT ptMouse) const noexcept;
[[nodiscard]] LRESULT _OnPaint() noexcept;
void _OnMaximizeChange() noexcept;
void _OnDragBarSizeChanged(winrt::Windows::Foundation::IInspectable sender, winrt::Windows::UI::Xaml::SizeChangedEventArgs eventArgs) const;
[[nodiscard]] HRESULT _UpdateFrameMargins() const noexcept;
void _UpdateMaximizedState();
void _UpdateIslandPosition(const UINT windowWidth, const UINT windowHeight);
void _UpdateIslandRegion() const;
void _UpdateFrameTheme() const;
};