Release 0.6

Tue Jan  4 13:01:33 1994  David Metcalfe <david@prism.demon.co.uk>

        * [window/caret.c]
        Modified code to use system timer.

Jan 9, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [windows/win.c]
	Windows create if required new XLIB MenuBar & CaptionBar.

	* [windows/defwnd.c]
	WM_CALCSIZE Move & Resize caption, menubar & scrollbars.
	(I'm not sure it's the good place for it, but it work...)

	* [loader/resource.c]
	optimize in FindResourceByNumber, make lseek() if next type ...

	* [controls/scroll.c]
	scrollbar buttons are now using system resources bitmaps.

	* [controls/caption.c] - new file ...
	captionbar showing title, close button with SysMenu,
	and other buttons using system resources bitmaps.

	* [controls/menu.c]
	New functions: SetMenuItemBitmaps() with 'glues',
	Make new version of LoadMenu() & ParseMenu(),
	( put #define USE_POPUPMENU ).
	Implementation of MenuBar functions.
	
	* [sysres.dll]
	New bitmaps for system such OBM_CLOSE, OBM_MINIMIZE, OBM_UPARROWI.
	New SYSMENU menu, it don't work yet ! :-((

Tue Jan 11 05:27:45 1994  julliard@di.epfl.ch (Alexandre Julliard

	* [memory/atom.c]
	Fixed a bug that could cause atoms to be case-sensitive.

	* [misc/rect.c]
	Bug fix in SubtractRect().

	* [objects/clipping.c]
	Bug fix when setting the clip mask to an empty region.

	* [windows/dce.c]
	Bug fix in ReleaseDC().

	* [windows/dialog.c]
	Call AdjustWindowRectEx() before creating the dialog window.
	Added support for DS_MODALFRAME style.

	* [windows/event.c]
	Cleaned up event handling and removed old Xt stuff.
	Moved double-click handling to windows/message.c

	* [windows/focus.c]
	Bug fix: only set the X focus when the window is viewable.

	* [windows/graphics.c]
	Rewritten DrawReliefRect() to use brush instead of pen, and
	to use the system colors.

	* [windows/message.c]
	Implemented WM_NCHITTEST message sending, and non-client
	mouse messages.
	Cleaned up double-click handling, and removed the Xt code.

	* [windows/nonclient.c]  (New file)
	Implemented AdjustWindowRect().
	Implemented WM_NCCALCSIZE, WM_NCHITTEST and WM_NCPAINT handling.

	* [windows/painting.c]
	Added sending of the WM_NCPAINT message in BeginPaint().

	* [windows/sysmetrics.c] [include/sysmetrics.h]  (New files)
	Implemented system metrics.

	* [windows/win.c]
	Bug fix in setting the parent and owner in CreateWindow().
	Removed the Xt code.

	* [windows/winpos.c]
	Added sending of the WM_NCPAINT message in SetWindowPos().
	Removed the Xt code.
diff --git a/windows/nonclient.c b/windows/nonclient.c
new file mode 100644
index 0000000..79f5893
--- /dev/null
+++ b/windows/nonclient.c
@@ -0,0 +1,461 @@
+/*
+ * Non-client area window functions
+ *
+ * Copyright 1994 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1994";
+
+#include "win.h"
+#include "sysmetrics.h"
+
+
+/***********************************************************************
+ *           NC_AdjustRect
+ *
+ * Compute the size of the window rectangle from the size of the
+ * client rectangle.
+ */
+static void NC_AdjustRect( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
+{
+    if ((style & WS_DLGFRAME) && 
+	((exStyle & WS_EX_DLGMODALFRAME) || !(style & WS_BORDER)))
+	InflateRect( rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
+    else if (style & WS_THICKFRAME)
+	InflateRect( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
+
+    if (style & WS_BORDER)
+	InflateRect( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER );
+
+    if ((style & WS_CAPTION) == WS_CAPTION)
+	rect->top -= SYSMETRICS_CYCAPTION - 1;
+
+    if (menu) rect->top -= SYSMETRICS_CYMENU + 1;
+
+    if (style & WS_VSCROLL) rect->right  += SYSMETRICS_CXVSCROLL;
+    if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
+}
+
+
+/***********************************************************************
+ *           AdjustWindowRect    (USER.102)
+ */
+void AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
+{
+    AdjustWindowRectEx( rect, style, menu, 0 );
+}
+
+
+/***********************************************************************
+ *           AdjustWindowRectEx    (USER.454)
+ */
+void AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
+{
+      /* Correct the window style */
+
+    if (!(style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
+	style |= WS_CAPTION;
+    if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
+
+#ifdef DEBUG_NONCLIENT
+    printf( "AdjustWindowRectEx: (%d,%d)-(%d,%d) %08x %d %08x\n",
+      rect->left, rect->top, rect->right, rect->bottom, style, menu, exStyle );
+#endif
+
+    NC_AdjustRect( rect, style, menu, exStyle );
+}
+
+
+/***********************************************************************
+ *           NC_HandleNCCalcSize
+ *
+ * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
+ */
+LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS *params )
+{
+    RECT tmpRect = { 0, 0, 0, 0 };
+    BOOL hasMenu;
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    
+    if (!wndPtr) return 0;
+
+    hasMenu = (!(wndPtr->dwStyle & WS_CHILD)) && (wndPtr->wIDmenu != 0);
+
+    NC_AdjustRect( &tmpRect, wndPtr->dwStyle, hasMenu, wndPtr->dwExStyle );
+    
+    params->rgrc[0].left   -= tmpRect.left;
+    params->rgrc[0].top    -= tmpRect.top;
+    params->rgrc[0].right  -= tmpRect.right;
+    params->rgrc[0].bottom -= tmpRect.bottom;
+    return 0;
+}
+
+
+/***********************************************************************
+ *           NC_HandleNCHitTest
+ *
+ * Handle a WM_NCHITTEST message. Called from DefWindowProc().
+ */
+LONG NC_HandleNCHitTest( HWND hwnd, POINT pt )
+{
+    RECT rect;
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return HTERROR;
+
+#ifdef DEBUG_NONCLIENT
+    printf( "NC_HandleNCHitTest: hwnd=%x pt=%d,%d\n", hwnd, pt.x, pt.y );
+#endif
+
+    if (hwnd == GetCapture()) return HTCLIENT;
+    GetWindowRect( hwnd, &rect );
+    if (!PtInRect( &rect, pt )) return HTNOWHERE;
+    ScreenToClient( hwnd, &pt );
+    GetClientRect( hwnd, &rect );
+    
+    if (PtInRect( &rect, pt )) return HTCLIENT;
+
+      /* Check vertical scroll bar */
+    if (wndPtr->dwStyle & WS_VSCROLL)
+    {
+	rect.right += SYSMETRICS_CXVSCROLL;
+	if (PtInRect( &rect, pt )) return HTVSCROLL;
+    }
+
+      /* Check horizontal scroll bar */
+    if (wndPtr->dwStyle & WS_HSCROLL)
+    {
+	rect.bottom += SYSMETRICS_CYHSCROLL;
+	if (PtInRect( &rect, pt ))
+	{
+	      /* Check size box */
+	    if ((wndPtr->dwStyle & WS_VSCROLL) &&
+		(pt.x >= rect.right - SYSMETRICS_CXVSCROLL)) return HTSIZE;
+	    return HTHSCROLL;
+	}
+    }
+
+      /* Check menu */
+    if ((!(wndPtr->dwStyle & WS_CHILD)) && (wndPtr->wIDmenu != 0))
+    {
+	rect.top -= SYSMETRICS_CYMENU + 1;
+	if (PtInRect( &rect, pt )) return HTMENU;
+    }
+
+      /* Check caption */
+    if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+    {
+	rect.top -= SYSMETRICS_CYCAPTION - 1;
+	if (PtInRect( &rect, pt ))
+	{
+	      /* Check system menu */
+	    if ((wndPtr->dwStyle & WS_SYSMENU) && (pt.x <= SYSMETRICS_CXSIZE))
+		return HTSYSMENU;
+	      /* Check maximize box */
+	    if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
+		rect.right -= SYSMETRICS_CXSIZE + 1;
+	    if (pt.x >= rect.right) return HTMAXBUTTON;
+	      /* Check minimize box */
+	    if (wndPtr->dwStyle & WS_MINIMIZEBOX)
+		rect.right -= SYSMETRICS_CXSIZE + 1;
+	    if (pt.x >= rect.right) return HTMINBUTTON;
+	    return HTCAPTION;
+	}
+    }
+    
+      /* Check non-sizing border */
+    if (!(wndPtr->dwStyle & WS_THICKFRAME) ||
+	((wndPtr->dwStyle & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME))
+	return HTBORDER;
+
+      /* Check top sizing border */
+    if (pt.y < rect.top)
+    {
+	if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
+	if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
+	return HTTOP;
+    }
+
+      /* Check bottom sizing border */
+    if (pt.y >= rect.bottom)
+    {
+	if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
+	if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
+	return HTBOTTOM;
+    }
+    
+      /* Check left sizing border */
+    if (pt.x < rect.left)
+    {
+	if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
+	if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
+	return HTLEFT;
+    }
+
+      /* Check right sizing border */
+    if (pt.x >= rect.right)
+    {
+	if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
+	if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
+	return HTRIGHT;
+    }
+
+      /* Should never get here */
+    return HTERROR;
+}
+
+
+/***********************************************************************
+ *           NC_DrawFrame
+ *
+ * Draw a window frame inside the given rectangle, and update the rectangle.
+ * The correct pen and brush must be selected in the DC.
+ */
+static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame )
+{
+    short width, height, tmp;
+
+    if (dlgFrame)
+    {
+	width = SYSMETRICS_CXDLGFRAME;
+	height = SYSMETRICS_CYDLGFRAME;
+    }
+    else
+    {
+	width = SYSMETRICS_CXFRAME - 1;
+	height = SYSMETRICS_CYFRAME - 1;
+    }
+
+      /* Draw frame */
+    PatBlt( hdc, rect->left, rect->top,
+	    rect->right - rect->left, height, PATCOPY );
+    PatBlt( hdc, rect->left, rect->top,
+	    width, rect->bottom - rect->top, PATCOPY );
+    PatBlt( hdc, rect->left, rect->bottom,
+	    rect->right - rect->left, -height, PATCOPY );
+    PatBlt( hdc, rect->right, rect->top,
+	    -width, rect->bottom - rect->top, PATCOPY );
+
+    if (dlgFrame)
+    {
+	InflateRect( rect, -width, -height );
+	return;
+    }
+    
+      /* Draw inner rectangle */
+    MoveTo( hdc, rect->left+width, rect->top+height );
+    LineTo( hdc, rect->right-width-1, rect->top+height );
+    LineTo( hdc, rect->right-width-1, rect->bottom-height-1 );
+    LineTo( hdc, rect->left+width, rect->bottom-height-1 );
+    LineTo( hdc, rect->left+width, rect->top+height );
+
+      /* Draw the decorations */
+    tmp = rect->top + SYSMETRICS_CYFRAME + SYSMETRICS_CYSIZE;
+    MoveTo( hdc, rect->left, tmp);
+    LineTo( hdc, rect->left+width, tmp );
+    MoveTo( hdc, rect->right-width-1, tmp );
+    LineTo( hdc, rect->right-1, tmp );
+
+    tmp = rect->bottom - 1 - SYSMETRICS_CYFRAME - SYSMETRICS_CYSIZE;
+    MoveTo( hdc, rect->left, tmp );
+    LineTo( hdc, rect->left+width, tmp );
+    MoveTo( hdc, rect->right-width-1, tmp );
+    LineTo( hdc, rect->right-1, tmp );
+
+    tmp = rect->left + SYSMETRICS_CXFRAME + SYSMETRICS_CXSIZE;
+    MoveTo( hdc, tmp, rect->top );
+    LineTo( hdc, tmp, rect->top+height );
+    MoveTo( hdc, tmp, rect->bottom-height-1 );
+    LineTo( hdc, tmp, rect->bottom-1 );
+
+    tmp = rect->right - 1 - SYSMETRICS_CXFRAME - SYSMETRICS_CYSIZE;
+    MoveTo( hdc, tmp, rect->top );
+    LineTo( hdc, tmp, rect->top+height );
+    MoveTo( hdc, tmp, rect->bottom-height-1 );
+    LineTo( hdc, tmp, rect->bottom-1 );
+
+    InflateRect( rect, -width-1, -height-1 );
+}
+
+
+/***********************************************************************
+ *           NC_DrawCaption
+ *
+ * Draw the window caption.
+ * The correct pen for the window frame must be selected in the DC.
+ */
+static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd, DWORD style )
+{
+    RECT r;
+    HBRUSH hbrushCaption, hbrushButtons;
+    char buffer[256];
+
+    hbrushButtons = CreateSolidBrush( GetSysColor( COLOR_BTNFACE ) );
+    hbrushCaption = CreateSolidBrush( GetSysColor( COLOR_ACTIVECAPTION ) );
+
+    MoveTo( hdc, rect->left, rect->bottom );
+    LineTo( hdc, rect->right-1, rect->bottom );
+
+    /* We should probably use OEM bitmaps (OBM_*) here */
+    if (style & WS_SYSMENU)
+    {
+	r = *rect;
+	r.right = r.left + SYSMETRICS_CYSIZE;
+	FillRect( hdc, &r, hbrushButtons );
+	MoveTo( hdc, r.right, r.top );
+	LineTo( hdc, r.right, r.bottom );
+	rect->left += SYSMETRICS_CXSIZE + 1;
+    }
+    if (style & WS_MAXIMIZEBOX)
+    {
+	r = *rect;
+	r.left = r.right - SYSMETRICS_CXSIZE;
+	FillRect( hdc, &r, hbrushButtons );
+	MoveTo( hdc, r.left-1, r.top );
+	LineTo( hdc, r.left-1, r.bottom );
+	DrawReliefRect( hdc, r, 2, 0 );
+	rect->right -= SYSMETRICS_CXSIZE + 1;
+    }
+    if (style & WS_MINIMIZEBOX)
+    {
+	r = *rect;
+	r.left = r.right - SYSMETRICS_CXSIZE;
+	FillRect( hdc, &r, hbrushButtons );
+	MoveTo( hdc, r.left-1, r.top );
+	LineTo( hdc, r.left-1, r.bottom );
+	DrawReliefRect( hdc, r, 2, 0 );
+	rect->right -= SYSMETRICS_CXSIZE + 1;
+    }
+
+    FillRect( hdc, rect, hbrushCaption );
+
+    if (GetWindowText( hwnd, buffer, 256 ))
+    {
+	SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
+	SetBkMode( hdc, TRANSPARENT );
+	DrawText( hdc, buffer, -1, rect,
+		 DT_SINGLELINE | DT_CENTER | DT_VCENTER );
+    }
+
+    DeleteObject( hbrushButtons );
+    DeleteObject( hbrushCaption );
+}
+
+
+/***********************************************************************
+ *           NC_HandleNCPaint
+ *
+ * Handle a WM_NCPAINT message. Called from DefWindowProc().
+ */
+LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn )
+{
+    HDC hdc;
+    RECT rect;
+    HBRUSH hbrushBorder = 0;
+    HPEN hpenFrame = 0;
+
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+
+#ifdef DEBUG_NONCLIENT
+    printf( "NC_HandleNCPaint: %d %d\n", hwnd, hrgn );
+#endif
+
+    if (!wndPtr || !hrgn) return 0;
+    if (!(wndPtr->dwStyle & (WS_BORDER | WS_DLGFRAME | WS_THICKFRAME)))
+	return 0;  /* Nothing to do! */
+
+    if (hrgn == 1) hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW );
+    else hdc = GetDCEx( hwnd, hrgn, DCX_CACHE | DCX_WINDOW | DCX_INTERSECTRGN);
+    if (!hdc) return 0;
+    if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
+		        wndPtr->rectClient.top-wndPtr->rectWindow.top,
+		        wndPtr->rectClient.right-wndPtr->rectWindow.left,
+		        wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
+	== NULLREGION)
+    {
+	ReleaseDC( hwnd, hdc );
+	return 0;
+    }
+
+    rect.top = rect.left = 0;
+    rect.right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
+    rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
+
+    hpenFrame = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_WINDOWFRAME) );
+    SelectObject( hdc, hpenFrame );
+    hbrushBorder = CreateSolidBrush( GetSysColor(COLOR_ACTIVEBORDER) );
+    SelectObject( hdc, hbrushBorder );
+
+    if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME))
+    {
+	MoveTo( hdc, 0, 0 );
+	LineTo( hdc, rect.right-1, 0 );
+	LineTo( hdc, rect.right-1, rect.bottom-1 );
+	LineTo( hdc, 0, rect.bottom-1 );
+	LineTo( hdc, 0, 0 );
+	InflateRect( &rect, -1, -1 );
+    }
+
+    if ((wndPtr->dwStyle & WS_DLGFRAME) &&
+	((wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) || 
+	 !(wndPtr->dwStyle & WS_BORDER))) NC_DrawFrame( hdc, &rect, TRUE );
+    else if (wndPtr->dwStyle & WS_THICKFRAME) NC_DrawFrame(hdc, &rect, FALSE);
+
+    if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+    {
+	RECT r = rect;
+	rect.top += SYSMETRICS_CYSIZE + 1;
+	r.bottom = rect.top - 1;
+	if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
+	{
+	    HBRUSH hbrushWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
+	    HBRUSH hbrushOld = SelectObject( hdc, hbrushWindow );
+	    PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1, PATCOPY );
+	    PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
+	    PatBlt( hdc, r.left, r.top, r.right-r.left, 1, PATCOPY );
+	    r.left++;
+	    r.right--;
+	    r.top++;
+	    SelectObject( hdc, hbrushOld );
+	    DeleteObject( hbrushWindow );
+	}
+	NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle );
+    }
+
+    if (wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL))
+    {
+	HBRUSH hbrushScroll = CreateSolidBrush( GetSysColor(COLOR_SCROLLBAR) );
+	HBRUSH hbrushOld = SelectObject( hdc, hbrushScroll );
+	if (wndPtr->dwStyle & WS_VSCROLL)
+	    PatBlt( hdc, rect.right - SYSMETRICS_CXVSCROLL, rect.top,
+		    SYSMETRICS_CXVSCROLL, rect.bottom-rect.top, PATCOPY );
+	if (wndPtr->dwStyle & WS_HSCROLL)
+	    PatBlt( hdc, rect.left, rect.bottom - SYSMETRICS_CYHSCROLL,
+		    rect.right-rect.left, SYSMETRICS_CYHSCROLL, PATCOPY );
+	SelectObject( hdc, hbrushOld );
+	DeleteObject( hbrushScroll );
+    }    
+
+    ReleaseDC( hwnd, hdc );
+    if (hbrushBorder) DeleteObject( hbrushBorder );
+    if (hpenFrame) DeleteObject( hpenFrame );    
+    return 0;
+}
+
+
+/***********************************************************************
+ *           NC_HandleNCMouseMsg
+ *
+ * Handle a non-client mouse message. Called from DefWindowProc().
+ */
+LONG NC_HandleNCMouseMsg( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
+{
+    switch(wParam)  /* Hit test code */
+    {
+    case HTSYSMENU:
+	if (msg == WM_NCLBUTTONDBLCLK)
+	    return SendMessage( hwnd, WM_SYSCOMMAND, SC_CLOSE, lParam );
+	break;
+    }
+    return 0;
+}
+