Implemented the system button behavior and associated it to the system
menu in win95. Also permit the SC_CLOSE item to be disabled.
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 8e37d09..9a1546a 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -26,10 +26,13 @@
#include "options.h"
#include "shellapi.h"
#include "cache.h"
+#include "bitmap.h"
DECLARE_DEBUG_CHANNEL(nonclient)
DECLARE_DEBUG_CHANNEL(shell)
+BOOL NC_DrawGrayButton(HDC hdc, int x, int y);
+
static HBITMAP16 hbitmapClose = 0;
static HBITMAP16 hbitmapCloseD = 0;
static HBITMAP16 hbitmapMinimize = 0;
@@ -39,6 +42,17 @@
static HBITMAP16 hbitmapRestore = 0;
static HBITMAP16 hbitmapRestoreD = 0;
+BYTE lpGrayMask[] = { 0xAA, 0xA0,
+ 0x55, 0x50,
+ 0xAA, 0xA0,
+ 0x55, 0x50,
+ 0xAA, 0xA0,
+ 0x55, 0x50,
+ 0xAA, 0xA0,
+ 0x55, 0x50,
+ 0xAA, 0xA0,
+ 0x55, 0x50};
+
#define SC_ABOUTWINE (SC_SCREENSAVE+1)
#define SC_PUTMARK (SC_SCREENSAVE+2)
@@ -711,9 +725,11 @@
if (wndPtr->dwStyle & WS_SYSMENU)
rect.left += GetSystemMetrics(SM_CXSIZE);
if (pt.x <= rect.left) return HTSYSMENU;
+
/* Check maximize box */
if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+
if (pt.x >= rect.right) return HTMAXBUTTON;
/* Check minimize box */
if (wndPtr->dwStyle & WS_MINIMIZEBOX)
@@ -857,13 +873,16 @@
if (pt.x > rect.right) return HTCLOSE;
/* Check maximize box */
- if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
+ /* In win95 there is automatically a Maximize button when there is a minimize one*/
+ if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
if (pt.x > rect.right) return HTMAXBUTTON;
/* Check minimize box */
- if (wndPtr->dwStyle & WS_MINIMIZEBOX)
+ /* In win95 there is automatically a Maximize button when there is a Maximize one*/
+ if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+
if (pt.x > rect.right) return HTMINBUTTON;
return HTCAPTION;
}
@@ -1061,17 +1080,20 @@
* void NC_DrawCloseButton95(
* HWND32 hwnd,
* HDC32 hdc,
- * BOOL32 down )
+ * BOOL32 down,
+ * BOOL bGrayed )
*
* Draws the Win95 close button.
*
+ * If bGrayed is true, then draw a disabled Close button
+ *
* Revision history
* 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
* Original implementation from NC_DrawSysButton95 source.
*
*****************************************************************************/
-static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down)
+static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
{
RECT rect;
HDC hdcMem;
@@ -1088,10 +1110,15 @@
hBmp = down ? hbitmapCloseD : hbitmapClose;
hOldBmp = SelectObject (hdcMem, hBmp);
GetObjectA (hBmp, sizeof(BITMAP), &bmp);
+
BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
+ if(bGrayed)
+ NC_DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
+ rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
+
SelectObject (hdcMem, hOldBmp);
DeleteDC (hdcMem);
}
@@ -1103,10 +1130,13 @@
* NC_DrawMaxButton95(
* HWND32 hwnd,
* HDC16 hdc,
- * BOOL32 down )
+ * BOOL32 down
+ * BOOL bGrayed )
*
* Draws the maximize button for Win95 style windows.
*
+ * If bGrayed is true, then draw a disabled Maximize button
+ *
* Bugs
* Many. Spacing might still be incorrect. Need to fit a close
* button between the max button and the edge.
@@ -1118,7 +1148,7 @@
*
*****************************************************************************/
-static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down )
+static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
{
RECT rect;
HDC hdcMem;
@@ -1131,18 +1161,24 @@
NC_GetInsideRect95( hwnd, &rect );
hdcMem = CreateCompatibleDC( hdc );
- hBmp = IsZoomed(hwnd) ?
- (down ? hbitmapRestoreD : hbitmapRestore ) :
- (down ? hbitmapMaximizeD: hbitmapMaximize);
+ hBmp = IsZoomed(hwnd) ?
+ (down ? hbitmapRestoreD : hbitmapRestore ) :
+ (down ? hbitmapMaximizeD: hbitmapMaximize);
hOldBmp=SelectObject( hdcMem, hBmp );
GetObjectA (hBmp, sizeof(BITMAP), &bmp);
-
+
if (wndPtr->dwStyle & WS_SYSMENU)
rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
+
+ if(bGrayed)
+ NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
+ rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
+
+
SelectObject (hdcMem, hOldBmp);
DeleteDC( hdcMem );
}
@@ -1154,10 +1190,13 @@
* NC_DrawMinButton95(
* HWND32 hwnd,
* HDC16 hdc,
- * BOOL32 down )
+ * BOOL32 down,
+ * BOOL bGrayed )
*
* Draws the minimize button for Win95 style windows.
*
+ * If bGrayed is true, then draw a disabled Minimize button
+ *
* Bugs
* Many. Spacing is still incorrect. Should scale the image with the
* title bar. And more...
@@ -1168,7 +1207,7 @@
*
*****************************************************************************/
-static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down )
+static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
{
RECT rect;
HDC hdcMem;
@@ -1190,15 +1229,21 @@
if (wndPtr->dwStyle & WS_SYSMENU)
rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
- if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
+ /* In win 95 there is always a Maximize box when there is a Minimize one */
+ if ((wndPtr->dwStyle & WS_MAXIMIZEBOX) || (wndPtr->dwStyle & WS_MINIMIZEBOX))
rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
+ if(bGrayed)
+ NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
+ rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
+
+
SelectObject (hdcMem, hOldBmp);
- DeleteDC( hdcMem );
+ DeleteDC( hdcMem );
}
WIN_ReleaseWndPtr(wndPtr);
}
@@ -1486,6 +1531,7 @@
WND *wndPtr = WIN_FindWndPtr( hwnd );
char buffer[256];
HPEN hPrevPen;
+ HMENU hSysMenu;
if (wndPtr->flags & WIN_MANAGED)
{
@@ -1514,22 +1560,36 @@
hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
}
-
+
if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
}
- if (style & WS_SYSMENU) {
- NC_DrawCloseButton95 (hwnd, hdc, FALSE);
+
+ if (style & WS_SYSMENU)
+ {
+ UINT state;
+
+ /* Go get the sysmenu */
+ hSysMenu = GetSystemMenu(hwnd, FALSE);
+ state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
+
+ /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
+ NC_DrawCloseButton95 (hwnd, hdc, FALSE,
+ ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
- }
- if (style & WS_MAXIMIZEBOX) {
- NC_DrawMaxButton95( hwnd, hdc, FALSE );
- r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
- }
- if (style & WS_MINIMIZEBOX) {
- NC_DrawMinButton95( hwnd, hdc, FALSE );
- r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+
+ if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
+ {
+ /* In win95 the two buttons are always there */
+ /* But if the menu item is not in the menu they're disabled*/
+
+ NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
+ r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+
+ NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
+ r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+ }
}
if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
@@ -2281,6 +2341,83 @@
/***********************************************************************
+ * NC_TrackMinMaxBox95
+ *
+ * Track a mouse button press on the minimize or maximize box.
+ *
+ * The big difference between 3.1 and 95 is the disabled button state.
+ * In win95 the system button can be disabled, so it can ignore the mouse
+ * event.
+ *
+ */
+static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
+{
+ MSG msg;
+ POINT16 pt16;
+ HDC hdc = GetWindowDC( hwnd );
+ BOOL pressed = TRUE;
+ UINT state;
+ DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
+ HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
+
+ void (*paintButton)(HWND, HDC16, BOOL, BOOL);
+
+ if (wParam == HTMINBUTTON)
+ {
+ /* If the style is not present, do nothing */
+ if (!(wndStyle & WS_MINIMIZEBOX))
+ return;
+
+ /* Check if the sysmenu item for minimize is there */
+ state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
+
+ paintButton = &NC_DrawMinButton95;
+ }
+ else
+ {
+ /* If the style is not present, do nothing */
+ if (!(wndStyle & WS_MAXIMIZEBOX))
+ return;
+
+ /* Check if the sysmenu item for maximize is there */
+ state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
+
+ paintButton = &NC_DrawMaxButton95;
+ }
+
+ SetCapture( hwnd );
+
+ (*paintButton)( hwnd, hdc, TRUE, FALSE);
+
+ do
+ {
+ BOOL oldstate = pressed;
+ MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
+ CONV_POINT32TO16( &msg.pt, &pt16 );
+
+ pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
+ if (pressed != oldstate)
+ (*paintButton)( hwnd, hdc, pressed, FALSE);
+ } while (msg.message != WM_LBUTTONUP);
+
+ (*paintButton)( hwnd, hdc, FALSE, FALSE);
+
+ ReleaseCapture();
+ ReleaseDC( hwnd, hdc );
+
+ /* If the item minimize or maximize of the sysmenu are not there */
+ /* or if the style is not present, do nothing */
+ if ((!pressed) || (state == 0xFFFFFFFF))
+ return;
+
+ if (wParam == HTMINBUTTON)
+ SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
+ else
+ SendMessage16( hwnd, WM_SYSCOMMAND,
+ IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
+}
+
+/***********************************************************************
* NC_TrackMinMaxBox
*
* Track a mouse button press on the minimize or maximize box.
@@ -2294,14 +2431,13 @@
void (*paintButton)(HWND, HDC16, BOOL);
SetCapture( hwnd );
- if (wParam == HTMINBUTTON)
- paintButton =
- (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMinButton : &NC_DrawMinButton95;
- else
- paintButton =
- (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMaxButton : &NC_DrawMaxButton95;
- (*paintButton)( hwnd, hdc, TRUE );
+ if (wParam == HTMINBUTTON)
+ paintButton = &NC_DrawMinButton;
+ else
+ paintButton = &NC_DrawMaxButton;
+
+ (*paintButton)( hwnd, hdc, TRUE);
do
{
@@ -2311,13 +2447,14 @@
pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
if (pressed != oldstate)
- (*paintButton)( hwnd, hdc, pressed );
+ (*paintButton)( hwnd, hdc, pressed);
} while (msg.message != WM_LBUTTONUP);
- (*paintButton)( hwnd, hdc, FALSE );
+ (*paintButton)( hwnd, hdc, FALSE);
ReleaseCapture();
ReleaseDC( hwnd, hdc );
+
if (!pressed) return;
if (wParam == HTMINBUTTON)
@@ -2338,12 +2475,25 @@
{
MSG msg;
POINT16 pt16;
- HDC hdc = GetWindowDC( hwnd );
+ HDC hdc;
BOOL pressed = TRUE;
+ HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
+ UINT state;
+
+ if(hSysMenu == 0)
+ return;
+
+ state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
+
+ /* If the item close of the sysmenu is disabled or not there do nothing */
+ if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
+ return;
+
+ hdc = GetWindowDC( hwnd );
SetCapture( hwnd );
- NC_DrawCloseButton95 (hwnd, hdc, TRUE);
+ NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
do
{
@@ -2353,10 +2503,10 @@
pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
if (pressed != oldstate)
- NC_DrawCloseButton95 (hwnd, hdc, pressed);
+ NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
} while (msg.message != WM_LBUTTONUP);
- NC_DrawCloseButton95 (hwnd, hdc, FALSE);
+ NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
ReleaseCapture();
ReleaseDC( hwnd, hdc );
@@ -2472,14 +2622,17 @@
case HTMINBUTTON:
case HTMAXBUTTON:
- NC_TrackMinMaxBox( hwnd, wParam );
+ if (TWEAK_WineLook == WIN31_LOOK)
+ NC_TrackMinMaxBox( hwnd, wParam );
+ else
+ NC_TrackMinMaxBox95( hwnd, wParam );
break;
case HTCLOSE:
if (TWEAK_WineLook >= WIN95_LOOK)
NC_TrackCloseButton95 (hwnd, wParam);
break;
-
+
case HTLEFT:
case HTRIGHT:
case HTTOP:
@@ -2622,3 +2775,36 @@
WIN_ReleaseWndPtr(wndPtr);
return 0;
}
+
+/*************************************************************
+* NC_DrawGrayButton
+*
+* Stub for the grayed button of the caption
+*
+*************************************************************/
+
+BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
+{
+ HBITMAP hMaskBmp;
+ HDC hdcMask = CreateCompatibleDC (0);
+ HBRUSH hOldBrush;
+
+ hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
+
+ if(hMaskBmp == 0)
+ return FALSE;
+
+ SelectObject (hdcMask, hMaskBmp);
+
+ /* Draw the grayed bitmap using the mask */
+ hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
+ BitBlt (hdc, x, y, 12, 10,
+ hdcMask, 0, 0, 0xB8074A);
+
+ /* Clean up */
+ SelectObject (hdc, hOldBrush);
+ DeleteObject(hMaskBmp);
+ DeleteDC (hdcMask);
+
+ return TRUE;
+}