mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-09 08:15:09 +03:00
Native window decorations: show Windows 11 snap layouts menu when hovering the mouse over the maximize button (issues #397 and #407)
This commit is contained in:
@@ -215,6 +215,26 @@ LRESULT CALLBACK FlatWndProc::WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, L
|
||||
case WM_NCHITTEST:
|
||||
return WmNcHitTest( hwnd, uMsg, wParam, lParam );
|
||||
|
||||
case WM_NCMOUSEMOVE:
|
||||
// if mouse is moved over some non-client areas,
|
||||
// send it also to the client area to allow Swing to process it
|
||||
// (required for Windows 11 maximize button)
|
||||
if( wParam == HTMAXBUTTON || wParam == HTCAPTION || wParam == HTSYSMENU )
|
||||
sendMessageToClientArea( hwnd, WM_MOUSEMOVE, lParam );
|
||||
break;
|
||||
|
||||
case WM_NCLBUTTONDOWN:
|
||||
case WM_NCLBUTTONUP:
|
||||
// if left mouse was pressed/released over maximize button,
|
||||
// send it also to the client area to allow Swing to process it
|
||||
// (required for Windows 11 maximize button)
|
||||
if( wParam == HTMAXBUTTON ) {
|
||||
int uClientMsg = (uMsg == WM_NCLBUTTONDOWN) ? WM_LBUTTONDOWN : WM_LBUTTONUP;
|
||||
sendMessageToClientArea( hwnd, uClientMsg, lParam );
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_NCRBUTTONUP:
|
||||
if( wParam == HTCAPTION || wParam == HTSYSMENU )
|
||||
openSystemMenu( hwnd, GET_X_LPARAM( lParam ), GET_Y_LPARAM( lParam ) );
|
||||
@@ -305,7 +325,7 @@ LRESULT FlatWndProc::WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lP
|
||||
|
||||
bool isMaximized = ::IsZoomed( hwnd );
|
||||
if( isMaximized && !isFullscreen() ) {
|
||||
// When a window is maximized, its size is actually a little bit more
|
||||
// When a window is maximized, its size is actually a little bit larger
|
||||
// than the monitor's work area. The window is positioned and sized in
|
||||
// such a way that the resize handles are outside of the monitor and
|
||||
// then the window is clipped to the monitor so that the resize handle
|
||||
@@ -354,6 +374,22 @@ LRESULT FlatWndProc::WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lPa
|
||||
if( lResult != HTCLIENT )
|
||||
return lResult;
|
||||
|
||||
// get mouse x/y in window coordinates
|
||||
LRESULT xy = screen2windowCoordinates( hwnd, lParam );
|
||||
int x = GET_X_LPARAM( xy );
|
||||
int y = GET_Y_LPARAM( xy );
|
||||
|
||||
int resizeBorderHeight = getResizeHandleHeight();
|
||||
bool isOnResizeBorder = (y < resizeBorderHeight) &&
|
||||
(::GetWindowLong( hwnd, GWL_STYLE ) & WS_THICKFRAME) != 0;
|
||||
|
||||
return onNcHitTest( x, y, isOnResizeBorder );
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts screen coordinates to window coordinates.
|
||||
*/
|
||||
LRESULT FlatWndProc::screen2windowCoordinates( HWND hwnd, LPARAM lParam ) {
|
||||
// get window rectangle needed to convert mouse x/y from screen to window coordinates
|
||||
RECT rcWindow;
|
||||
::GetWindowRect( hwnd, &rcWindow );
|
||||
@@ -362,11 +398,7 @@ LRESULT FlatWndProc::WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lPa
|
||||
int x = GET_X_LPARAM( lParam ) - rcWindow.left;
|
||||
int y = GET_Y_LPARAM( lParam ) - rcWindow.top;
|
||||
|
||||
int resizeBorderHeight = getResizeHandleHeight();
|
||||
bool isOnResizeBorder = (y < resizeBorderHeight) &&
|
||||
(::GetWindowLong( hwnd, GWL_STYLE ) & WS_THICKFRAME) != 0;
|
||||
|
||||
return onNcHitTest( x, y, isOnResizeBorder );
|
||||
return MAKELONG( x, y );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -429,6 +461,14 @@ JNIEnv* FlatWndProc::getEnv() {
|
||||
return env;
|
||||
}
|
||||
|
||||
void FlatWndProc::sendMessageToClientArea( HWND hwnd, int uMsg, LPARAM lParam ) {
|
||||
// get mouse x/y in window coordinates
|
||||
LRESULT xy = screen2windowCoordinates( hwnd, lParam );
|
||||
|
||||
// send message
|
||||
::SendMessage( hwnd, uMsg, 0, xy );
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the window's system menu.
|
||||
* The system menu is the menu that opens when the user presses Alt+Space or
|
||||
|
||||
@@ -54,6 +54,7 @@ private:
|
||||
LRESULT WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
|
||||
LRESULT WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
LRESULT screen2windowCoordinates( HWND hwnd, LPARAM lParam );
|
||||
int getResizeHandleHeight();
|
||||
bool hasAutohideTaskbar( UINT edge, RECT rcMonitor );
|
||||
BOOL isFullscreen();
|
||||
@@ -61,6 +62,7 @@ private:
|
||||
void fireStateChangedLaterOnce();
|
||||
JNIEnv* getEnv();
|
||||
|
||||
void sendMessageToClientArea( HWND hwnd, int uMsg, LPARAM lParam );
|
||||
void openSystemMenu( HWND hwnd, int x, int y );
|
||||
void setMenuItemState( HMENU systemMenu, int item, bool enabled );
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ extern "C" {
|
||||
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTCAPTION 2L
|
||||
#undef com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTSYSMENU
|
||||
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTSYSMENU 3L
|
||||
#undef com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTMAXBUTTON
|
||||
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTMAXBUTTON 9L
|
||||
#undef com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTTOP
|
||||
#define com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc_HTTOP 12L
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user