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;
+}
+