77
88#include " ../../../codegen/react/components/rnwcore/ModalHostView.g.h"
99#include < ComponentView.Experimental.interop.h>
10+ #include < dwmapi.h>
1011#include < winrt/Microsoft.UI.Content.h>
1112#include < winrt/Microsoft.UI.Input.h>
1213#include < winrt/Microsoft.UI.Windowing.h>
@@ -112,6 +113,12 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
112113 m_rnWindow.AppWindow ().Title (titleValue);
113114 }
114115
116+ if (m_rnWindow &&
117+ (newViewProps.hideTitleBar != oldViewProps.hideTitleBar ||
118+ newViewProps.hideBorder != oldViewProps.hideBorder )) {
119+ UpdateTitleBarAndBorder ();
120+ }
121+
115122 ::Microsoft::ReactNativeSpecs::BaseModalHostView<ModalHostView>::UpdateProps (view, newProps, oldProps);
116123 }
117124
@@ -258,6 +265,61 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
258265 }
259266 }
260267
268+ void UpdateTitleBarAndBorder () noexcept {
269+ if (!m_rnWindow) {
270+ return ;
271+ }
272+
273+ auto overlappedPresenter = winrt::Microsoft::UI::Windowing::OverlappedPresenter::Create ();
274+
275+ // Configure presenter for modal behavior
276+ overlappedPresenter.IsModal (true );
277+
278+ // modal should only have close button
279+ overlappedPresenter.IsMinimizable (false );
280+ overlappedPresenter.IsMaximizable (false );
281+
282+ // Apply the presenter to the window
283+ m_rnWindow.AppWindow ().SetPresenter (overlappedPresenter);
284+
285+ // We only hide the borders if the titlebar is also hidden.
286+ const bool hideBorders = m_localProps->hideTitleBar .value_or (false ) && m_localProps->hideBorder .value_or (false );
287+
288+ auto titleBar = m_rnWindow.AppWindow ().TitleBar ();
289+ titleBar.ResetToDefault ();
290+ overlappedPresenter.IsResizable (false );
291+
292+ overlappedPresenter.SetBorderAndTitleBar (!hideBorders, !m_localProps->hideTitleBar .value_or (false ));
293+
294+ auto hwnd = GetWindowFromWindowId (m_rnWindow.AppWindow ().Id ());
295+
296+ if (hideBorders) {
297+ const DWMNCRENDERINGPOLICY ncPolicy = DWMNCRP_DISABLED;
298+ ::DwmSetWindowAttribute (hwnd, DWMWA_NCRENDERING_POLICY, &ncPolicy, sizeof (ncPolicy));
299+
300+ const DWM_WINDOW_CORNER_PREFERENCE cornerPref = DWMWCP_DEFAULT;
301+ ::DwmSetWindowAttribute (hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPref, sizeof (cornerPref));
302+
303+ const COLORREF zeroColor = 0 ;
304+ ::DwmSetWindowAttribute (hwnd, DWMWA_BORDER_COLOR, &zeroColor, sizeof (zeroColor));
305+ ::DwmSetWindowAttribute (hwnd, DWMWA_CAPTION_COLOR, &zeroColor, sizeof (zeroColor));
306+ ::DwmSetWindowAttribute (hwnd, DWMWA_TEXT_COLOR, &zeroColor, sizeof (zeroColor));
307+ } else {
308+ const DWMNCRENDERINGPOLICY ncPolicy = DWMNCRP_USEWINDOWSTYLE;
309+ ::DwmSetWindowAttribute (hwnd, DWMWA_NCRENDERING_POLICY, &ncPolicy, sizeof (ncPolicy));
310+
311+ const DWM_WINDOW_CORNER_PREFERENCE cornerPref = DWMWCP_DEFAULT;
312+ ::DwmSetWindowAttribute (hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPref, sizeof (cornerPref));
313+
314+ const COLORREF zeroColor = DWMWA_COLOR_DEFAULT;
315+ ::DwmSetWindowAttribute (hwnd, DWMWA_BORDER_COLOR, &zeroColor, sizeof (zeroColor));
316+ ::DwmSetWindowAttribute (hwnd, DWMWA_CAPTION_COLOR, &zeroColor, sizeof (zeroColor));
317+ ::DwmSetWindowAttribute (hwnd, DWMWA_TEXT_COLOR, &zeroColor, sizeof (zeroColor));
318+
319+ titleBar.IconShowOptions (winrt::Microsoft::UI::Windowing::IconShowOptions::HideIconAndSystemMenu);
320+ }
321+ }
322+
261323 // creates a new modal window
262324 void EnsureModalCreated (const winrt::Microsoft::ReactNative::ComponentView &view) {
263325 if (m_popUp) {
@@ -282,22 +344,8 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
282344 m_rnWindow = winrt::Microsoft::ReactNative::ReactNativeWindow::CreateFromContentSiteBridgeAndIsland (
283345 m_popUp, winrt::Microsoft::ReactNative::ReactNativeIsland::CreatePortal (portal));
284346 m_rnWindow.ResizePolicy (winrt::Microsoft::ReactNative::ContentSizePolicy::None);
285- auto overlappedPresenter = winrt::Microsoft::UI::Windowing::OverlappedPresenter::Create ();
286-
287- // Configure presenter for modal behavior
288- overlappedPresenter.IsModal (true );
289- overlappedPresenter.SetBorderAndTitleBar (true , true );
290-
291- // modal should only have close button
292- overlappedPresenter.IsMinimizable (false );
293- overlappedPresenter.IsMaximizable (false );
294-
295- // Apply the presenter to the window
296- m_rnWindow.AppWindow ().SetPresenter (overlappedPresenter);
297347
298- // Hide the title bar icon
299- m_rnWindow.AppWindow ().TitleBar ().IconShowOptions (
300- winrt::Microsoft::UI::Windowing::IconShowOptions::HideIconAndSystemMenu);
348+ UpdateTitleBarAndBorder ();
301349
302350 // Set initial title using the stored local props
303351 if (m_localProps && m_localProps->title .has_value ()) {
0 commit comments