#include <windows.h>
#include <user32.h>
#include <window.h>
-#include <debug.h>
#include <user32/wininternal.h>
#include <string.h>
+#include <menu.h>
+#include <cursor.h>
+#include <winpos.h>
-/* GLOBALS *******************************************************************/
+#define NDEBUG
+#include <debug.h>
-static HBITMAP hbitmapClose;
-static HBITMAP hbitmapMinimize;
-static HBITMAP hbitmapMinimizeD;
-static HBITMAP hbitmapMaximize;
-static HBITMAP hbitmapMaximizeD;
-static HBITMAP hbitmapRestore;
-static HBITMAP hbitmapRestoreD;
+/* GLOBALS *******************************************************************/
-static COLORREF SysColours[] =
+static HBITMAP hbSysMenu;
+/* TODO: widgets will be cached here.
+static HBITMAP hbClose;
+static HBITMAP hbCloseD;
+static HBITMAP hbMinimize;
+static HBITMAP hbMinimizeD;
+static HBITMAP hbRestore;
+static HBITMAP hbRestoreD;
+static HBITMAP hbMaximize;
+static HBITMAP hbScrUp;
+static HBITMAP hbScrDwn;
+static HBITMAP hbScrLeft;
+static HBITMAP hbScrRight;
+*/
+
+
+static COLORREF SysColours[29] =
{
RGB(224, 224, 224) /* COLOR_SCROLLBAR */,
- RGB(192, 192, 192) /* COLOR_BACKGROUND */,
- RGB(0, 64, 128) /* COLOR_ACTIVECAPTION */,
- RGB(255, 255, 255) /* COLOR_INACTIVECAPTION */,
- RGB(255, 255, 255) /* COLOR_MENU */,
+ RGB(58, 110, 165) /* COLOR_BACKGROUND */,
+ RGB(0, 0, 128) /* COLOR_ACTIVECAPTION */,
+ RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */,
+ RGB(192, 192, 192) /* COLOR_MENU */,
RGB(255, 255, 255) /* COLOR_WINDOW */,
RGB(0, 0, 0) /* COLOR_WINDOWFRAME */,
RGB(0, 0, 0) /* COLOR_MENUTEXT */,
RGB(255, 255, 255) /* COLOR_INACTIVEBORDER */,
RGB(255, 255, 232) /* COLOR_APPWORKSPACE */,
RGB(224, 224, 224) /* COLOR_HILIGHT */,
- RGB(0, 0, 0) /* COLOR_HILIGHTTEXT */,
+ RGB(0, 0, 128) /* COLOR_HILIGHTTEXT */,
RGB(192, 192, 192) /* COLOR_BTNFACE */,
RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
RGB(192, 192, 192) /* COLOR_GRAYTEXT */,
RGB(0, 0, 0) /* COLOR_BTNTEXT */,
- RGB(0, 0, 0) /* COLOR_INACTIVECAPTIONTEXT */,
+ RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */,
RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
RGB(192, 192, 192) /* COLOR_3DLIGHT */,
static ATOM AtomInternalPos;
+/* Bits in the dwKeyData */
+#define KEYDATA_ALT 0x2000
+
/* FUNCTIONS *****************************************************************/
+BOOL
+IsMaxBoxActive(HWND hWnd)
+{
+ ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE);
+ return (uStyle & WS_MAXIMIZEBOX);
+}
+
+BOOL
+IsCloseBoxActive(HWND hWnd)
+{
+ ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE);
+ return (uStyle & WS_SYSMENU);
+}
+
+BOOL
+IsMinBoxActive(HWND hWnd)
+{
+ ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE);
+ return (uStyle & WS_MINIMIZEBOX);
+}
+
+INT
+UIGetFrameSizeX(HWND hWnd)
+{
+ ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE);
+
+ if ( uStyle & WS_THICKFRAME )
+ return GetSystemMetrics(SM_CXSIZEFRAME);
+ else
+ return GetSystemMetrics(SM_CXFRAME);
+}
+
+INT
+UIGetFrameSizeY(HWND hWnd)
+{
+ ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE);
+
+ if (uStyle & WS_THICKFRAME)
+ return GetSystemMetrics(SM_CYSIZEFRAME);
+ else
+ return GetSystemMetrics(SM_CYFRAME);
+}
+
VOID
UserSetupInternalPos(VOID)
{
- LPSTR Str = "SysIP";
- AtomInternalPos = GlobalAddAtomA(Str);
+ LPSTR Str = "SysIP";
+ AtomInternalPos = GlobalAddAtomA(Str);
+}
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetSysColor(int nIndex)
+{
+ return SysColours[nIndex];
}
-/* ReactOS extension */
+/*
+ * @implemented
+ */
HPEN STDCALL
GetSysColorPen(int nIndex)
{
- return(CreatePen(PS_SOLID, 1, SysColours[nIndex]));
+ return CreatePen(PS_SOLID, 1, SysColours[nIndex]);
}
+/*
+ * @implemented
+ */
HBRUSH STDCALL
GetSysColorBrush(int nIndex)
{
- return(CreateSolidBrush(SysColours[nIndex]));
+ return CreateSolidBrush(SysColours[nIndex]);
}
-
+/*
+ * @unimplemented
+ */
LRESULT STDCALL
-DefFrameProcA(HWND hWnd,
+DefFrameProcA( HWND hWnd,
HWND hWndMDIClient,
UINT uMsg,
WPARAM wParam,
- LPARAM lParam)
+ LPARAM lParam )
{
- return((LRESULT)0);
+ UNIMPLEMENTED;
+ return ((LRESULT)0);
}
+/*
+ * @unimplemented
+ */
LRESULT STDCALL
DefFrameProcW(HWND hWnd,
HWND hWndMDIClient,
WPARAM wParam,
LPARAM lParam)
{
- return((LRESULT)0);
+ UNIMPLEMENTED;
+ return ((LRESULT)0);
}
+PINTERNALPOS
+UserGetInternalPos(HWND hWnd)
+{
+ PINTERNALPOS lpPos;
+ lpPos = (PINTERNALPOS)GetPropA(hWnd, (LPSTR)(DWORD)AtomInternalPos);
+ return(lpPos);
+}
-BOOL
+BOOL
DefWndRedrawIconTitle(HWND hWnd)
{
- PINTERNALPOS lpPos = (PINTERNALPOS)GetPropA(hWnd,
- (LPSTR)(DWORD)AtomInternalPos);
- if (lpPos != NULL)
+ PINTERNALPOS lpPos = (PINTERNALPOS)GetPropA(hWnd, (LPSTR)(DWORD)AtomInternalPos);
+
+ if (lpPos != NULL)
{
- if (lpPos->IconTitle != NULL)
- {
- SendMessageA(lpPos->IconTitle, WM_SHOWWINDOW, TRUE, 0);
- InvalidateRect(lpPos->IconTitle, NULL, TRUE);
- return(TRUE);
- }
+ if (lpPos->IconTitle != NULL)
+ {
+ SendMessageA(lpPos->IconTitle, WM_SHOWWINDOW, TRUE, 0);
+ InvalidateRect(lpPos->IconTitle, NULL, TRUE);
+ return(TRUE);
+ }
}
- return(FALSE);
+ return(FALSE);
}
BOOL
UserHasMenu(HWND hWnd, ULONG Style)
{
- return(!(Style & WS_CHILD) && GetWindowLong(hWnd, GWL_ID) != 0);
+ return (!(Style & WS_CHILD) && GetMenu(hWnd) != 0);
}
ULONG
UserHasAnyFrameStyle(ULONG Style, ULONG ExStyle)
{
- return((Style & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) ||
- (ExStyle & WS_EX_DLGMODALFRAME) ||
- (!(Style & (WS_CHILD | WS_POPUP))));
+ return ((Style & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) ||
+ (ExStyle & WS_EX_DLGMODALFRAME) ||
+ (!(Style & (WS_CHILD | WS_POPUP))));
}
ULONG
UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle)
{
- return((ExStyle & WS_EX_DLGMODALFRAME) ||
- ((Style & WS_DLGFRAME) && (!(Style & WS_THICKFRAME))));
+ return ((ExStyle & WS_EX_DLGMODALFRAME) ||
+ ((Style & WS_DLGFRAME) && (!(Style & WS_THICKFRAME))));
}
ULONG
UserHasThickFrameStyle(ULONG Style, ULONG ExStyle)
{
- return((Style & WS_THICKFRAME) &&
- (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)));
+ return ((Style & WS_THICKFRAME) &&
+ (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)));
}
-ULONG
+ULONG
UserHasThinFrameStyle(ULONG Style, ULONG ExStyle)
{
- return((Style & WS_BORDER) ||
- (!(Style & (WS_CHILD | WS_POPUP))));
+ return ((Style & WS_BORDER) || (!(Style & (WS_CHILD | WS_POPUP))));
}
ULONG
UserHasBigFrameStyle(ULONG Style, ULONG ExStyle)
{
- return((Style & (WS_THICKFRAME | WS_DLGFRAME)) ||
- (ExStyle & WS_EX_DLGMODALFRAME));
+ return ((Style & (WS_THICKFRAME | WS_DLGFRAME)) ||
+ (ExStyle & WS_EX_DLGMODALFRAME));
}
-static void UserGetInsideRectNC( HWND hwnd, RECT *rect )
+void
+UserGetInsideRectNC(HWND hWnd, RECT *rect)
{
- RECT WindowRect;
- ULONG Style;
- ULONG ExStyle;
+ RECT WindowRect;
+ ULONG Style;
+ ULONG ExStyle;
- Style = GetWindowLong(hwnd, GWL_STYLE);
- ExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
- GetWindowRect(hwnd, &WindowRect);
- rect->top = rect->left = 0;
- rect->right = WindowRect.right - WindowRect.left;
- rect->bottom = WindowRect.bottom - WindowRect.top;
-
- if (Style & WS_ICONIC)
+ Style = GetWindowLongW(hWnd, GWL_STYLE);
+ ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
+ GetWindowRect(hWnd, &WindowRect);
+ rect->top = rect->left = 0;
+ rect->right = WindowRect.right - WindowRect.left;
+ rect->bottom = WindowRect.bottom - WindowRect.top;
+
+ if (Style & WS_ICONIC)
{
- return;
+ return;
}
- /* Remove frame from rectangle */
- if (UserHasThickFrameStyle(Style, ExStyle ))
- {
- InflateRect( rect, -GetSystemMetrics(SM_CXFRAME),
- -GetSystemMetrics(SM_CYFRAME) );
- }
+ /* Remove frame from rectangle */
+ if (UserHasThickFrameStyle(Style, ExStyle ))
+ {
+ InflateRect(rect, -GetSystemMetrics(SM_CXFRAME),
+ -GetSystemMetrics(SM_CYFRAME));
+ }
else
- {
- if (UserHasDlgFrameStyle(Style, ExStyle ))
- {
- InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME),
- -GetSystemMetrics(SM_CYDLGFRAME));
- /* FIXME: this isn't in NC_AdjustRect? why not? */
- if (ExStyle & WS_EX_DLGMODALFRAME)
- InflateRect( rect, -1, 0 );
- }
- else
- {
- if (UserHasThinFrameStyle(Style, ExStyle))
- {
- InflateRect(rect, -GetSystemMetrics(SM_CXBORDER),
- -GetSystemMetrics(SM_CYBORDER));
- }
- }
- }
+ {
+ if (UserHasDlgFrameStyle(Style, ExStyle ))
+ {
+ InflateRect(rect, -GetSystemMetrics(SM_CXDLGFRAME),
+ -GetSystemMetrics(SM_CYDLGFRAME));
+ /* FIXME: this isn't in NC_AdjustRect? why not? */
+ if (ExStyle & WS_EX_DLGMODALFRAME)
+ InflateRect( rect, -1, 0 );
+ }
+ else
+ {
+ if (UserHasThinFrameStyle(Style, ExStyle))
+ {
+ InflateRect(rect, -GetSystemMetrics(SM_CXBORDER),
+ -GetSystemMetrics(SM_CYBORDER));
+ }
+ }
+ }
}
-void UserDrawSysButton( HWND hwnd, HDC hdc, BOOL down )
+WINBOOL
+UserDrawSysMenuButton(HWND hWnd, HDC hDC, LPRECT Rect, BOOL down)
{
- RECT rect;
- HDC hdcMem;
- HBITMAP hbitmap;
- ULONG Style;
+ HDC hDcMem;
+ HBITMAP hSavedBitmap;
- Style = GetWindowLong(hwnd, GWL_STYLE);
- UserGetInsideRectNC( hwnd, &rect );
- hdcMem = CreateCompatibleDC( hdc );
- hbitmap = SelectObject( hdcMem, hbitmapClose );
- BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE),
- GetSystemMetrics(SM_CYSIZE), hdcMem,
- (Style & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
- down ? NOTSRCCOPY : SRCCOPY );
- SelectObject( hdcMem, hbitmap );
- DeleteDC( hdcMem );
-}
+ if (!hbSysMenu)
+ {
+ hbSysMenu = (HBITMAP)LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
+ }
+ hDcMem = CreateCompatibleDC(hDC);
+ if (!hDcMem)
+ {
+ return FALSE;
+ }
+ hSavedBitmap = SelectObject(hDcMem, hbSysMenu);
+ if (!hSavedBitmap)
+ {
+ DeleteDC(hDcMem);
+ return FALSE;
+ }
-static void UserDrawMaxButton( HWND hwnd, HDC hdc, BOOL down )
-{
- RECT rect;
- HDC hdcMem;
-
- UserGetInsideRectNC( hwnd, &rect );
- hdcMem = CreateCompatibleDC( hdc );
- SelectObject( hdcMem, (IsZoomed(hwnd)
- ? (down ? hbitmapRestoreD : hbitmapRestore)
- : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
- BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSMSIZE) - 1, rect.top,
- GetSystemMetrics(SM_CXSMSIZE) + 1, GetSystemMetrics(SM_CYSMSIZE), hdcMem, 0, 0,
- SRCCOPY );
- DeleteDC( hdcMem );
-}
+ BitBlt(hDC, Rect->left + 2, Rect->top + 3, 16, 14, hDcMem,
+ (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ?
+ GetSystemMetrics(SM_CXSIZE): 0, 0, SRCCOPY);
-static void UserDrawMinButton( HWND hwnd, HDC hdc, BOOL down)
-{
- RECT rect;
- HDC hdcMem;
-
- UserGetInsideRectNC(hwnd, &rect);
- hdcMem = CreateCompatibleDC(hdc);
- SelectObject(hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize));
- if (GetWindowLong(hwnd, GWL_STYLE) & WS_MAXIMIZEBOX)
- {
- rect.right -= GetSystemMetrics(SM_CXSMSIZE)+1;
- }
- BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSMSIZE) - 1, rect.top,
- GetSystemMetrics(SM_CXSMSIZE) + 1, GetSystemMetrics(SM_CYSMSIZE),
- hdcMem, 0, 0,
- SRCCOPY );
- DeleteDC( hdcMem );
+ SelectObject(hDcMem, hSavedBitmap);
+ DeleteDC(hDcMem);
+ return TRUE;
}
-static void UserDrawCaptionNC( HDC hdc, RECT *rect, HWND hwnd,
- DWORD style, BOOL active )
+/*
+ * FIXME:
+ * Cache bitmaps, then just bitblt instead of calling DFC() (and
+ * wasting precious CPU cycles) every time
+ */
+static void
+UserDrawCaptionButton(HWND hWnd, HDC hDC, BOOL bDown, ULONG Type)
{
- RECT r = *rect;
- char buffer[256];
+ RECT rect;
+ INT iBmpWidth = GetSystemMetrics(SM_CXSIZE) - 2;
+ INT iBmpHeight = GetSystemMetrics(SM_CYSIZE) - 4;
+ INT OffsetX = UIGetFrameSizeX(hWnd);
+ INT OffsetY = UIGetFrameSizeY(hWnd);
- if (!hbitmapClose)
- {
- hbitmapClose = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_CLOSE));
- hbitmapMinimize = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_REDUCE) );
- hbitmapMinimizeD = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_REDUCED) );
- hbitmapMaximize = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_ZOOM) );
- hbitmapMaximizeD = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_ZOOMD) );
- hbitmapRestore = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_RESTORE) );
- hbitmapRestoreD = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_RESTORED) );
+ if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_SYSMENU))
+ {
+ return;
}
-
- if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_DLGMODALFRAME)
+
+ GetWindowRect(hWnd, &rect);
+
+ rect.right = rect.right - rect.left;
+ rect.bottom = rect.bottom - rect.top;
+ rect.left = rect.top = 0;
+
+ switch(Type)
{
- HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
- 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-1, r.right-r.left, 1, PATCOPY );
- r.left++;
- r.right--;
- SelectObject( hdc, hbrushOld );
+ case DFCS_CAPTIONMIN:
+ {
+ if ((GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) == TRUE)
+ return; /* ToolWindows don't have min/max buttons */
+
+ SetRect(&rect, rect.right - OffsetX - (iBmpWidth * 3) - 5,
+ OffsetY + 2, rect.right - (iBmpWidth * 2) - OffsetX - 5,
+ rect.top + iBmpHeight + OffsetY + 2);
+ DrawFrameControl(hDC, &rect, DFC_CAPTION,
+ DFCS_CAPTIONMIN | (bDown ? DFCS_PUSHED : 0) |
+ (IsMinBoxActive(hWnd) ? 0 : DFCS_INACTIVE));
+ break;
+ }
+ case DFCS_CAPTIONMAX:
+ {
+ if ((GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) == TRUE)
+ return; /* ToolWindows don't have min/max buttons */
+
+ SetRect(&rect, rect.right - OffsetX - (iBmpWidth * 2) - 5,
+ OffsetY + 2, rect.right - iBmpWidth - OffsetX - 5,
+ rect.top + iBmpHeight + OffsetY + 2);
+ DrawFrameControl(hDC, &rect, DFC_CAPTION,
+ (IsZoomed(hWnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX) |
+ (bDown ? DFCS_PUSHED : 0) |
+ (IsMaxBoxActive(hWnd) ? 0 : DFCS_INACTIVE));
+ break;
+ }
+ case DFCS_CAPTIONCLOSE:
+ {
+ SetRect(&rect, rect.right - OffsetX - iBmpWidth - 3,
+ OffsetY + 2, rect.right - OffsetX - 3,
+ rect.top + iBmpHeight + OffsetY + 2 );
+ DrawFrameControl(hDC, &rect, DFC_CAPTION,
+ (DFCS_CAPTIONCLOSE | (bDown ? DFCS_PUSHED : 0) |
+ (IsCloseBoxActive(hWnd) ? 0 : DFCS_INACTIVE)));
+ break;
+ }
}
+}
- MoveToEx( hdc, r.left, r.bottom, NULL );
- LineTo( hdc, r.right, r.bottom );
+// Enabling this will cause captions to draw smoother, but slower:
+// #define DOUBLE_BUFFER_CAPTION
+// NOTE: Double buffering appears to be broken for this at the moment
- if (style & WS_SYSMENU)
+/*
+ * @implemented
+ */
+WINBOOL STDCALL
+DrawCaption(
+ HWND hWnd,
+ HDC hDC,
+ LPRECT lprc,
+ UINT uFlags)
+{
+ NONCLIENTMETRICSW nclm;
+ BOOL result = FALSE;
+ RECT r = *lprc;
+ UINT VCenter = 0, Padding = 0, Height;
+ WCHAR buffer[256];
+ HFONT hFont = NULL;
+ HFONT hOldFont = NULL;
+ HBRUSH OldBrush = NULL;
+ HDC MemDC = NULL;
+ int ButtonWidth;
+
+#ifdef DOUBLE_BUFFER_CAPTION
+ HBITMAP MemBMP = NULL, OldBMP = NULL;
+
+ MemDC = CreateCompatibleDC(hDC);
+ if (! MemDC) goto cleanup;
+ MemBMP = CreateCompatibleBitmap(hDC, lprc->right - lprc->left, lprc->bottom - lprc->top);
+ if (! MemBMP) goto cleanup;
+ OldBMP = SelectObject(MemDC, MemBMP);
+ if (! OldBMP) goto cleanup;
+#else
+ MemDC = hDC;
+
+ OffsetViewportOrgEx(MemDC, lprc->left, lprc->top, NULL);
+#endif
+
+ // If DC_GRADIENT is specified, a Win 98/2000 style caption gradient should
+ // be painted. For now, that flag is ignored:
+ // Windows 98/Me, Windows 2000/XP: When this flag is set, the function uses
+ // COLOR_GRADIENTACTIVECAPTION (if the DC_ACTIVE flag was set) or
+ // COLOR_GRADIENTINACTIVECAPTION for the title-bar color.
+
+ // Draw the caption background
+ if (uFlags & DC_INBUTTON)
{
- UserDrawSysButton( hwnd, hdc, FALSE );
- r.left += GetSystemMetrics(SM_CXSIZE) + 1;
- MoveToEx( hdc, r.left - 1, r.top, NULL );
- LineTo( hdc, r.left - 1, r.bottom );
+ OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_BTNFACE : COLOR_BTNSHADOW) );
+ if (! OldBrush) goto cleanup;
+ if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, PATCOPY )) goto cleanup;
}
- if (style & WS_MAXIMIZEBOX)
+ else
{
- UserDrawMaxButton( hwnd, hdc, FALSE );
- r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
+ // DC_GRADIENT check should go here somewhere
+ OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
+ if (! OldBrush) goto cleanup;
+ if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, PATCOPY )) goto cleanup;
}
- if (style & WS_MINIMIZEBOX)
+
+ /* Windows behaves like this */
+ Height = GetSystemMetrics(SM_CYCAPTION) - 1;
+
+ VCenter = (lprc->bottom - lprc->top) / 2;
+ Padding = VCenter - (Height / 2);
+
+ r.left = Padding;
+ r.right = r.left + (lprc->right - lprc->left);
+ r.top = Padding;
+ r.bottom = r.top + (Height / 2);
+
+ if (uFlags & DC_ICON)
{
- UserDrawMinButton( hwnd, hdc, FALSE );
- r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
+ // For some reason the icon isn't centered correctly...
+ r.top --;
+ UserDrawSysMenuButton(hWnd, MemDC, &r, FALSE);
+ r.top ++;
}
-
- FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
- COLOR_INACTIVECAPTION) );
-
- if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
+
+ r.top ++;
+ r.left += 2;
+
+ if ((uFlags & DC_TEXT) && (GetWindowTextW( hWnd, buffer, sizeof(buffer)/sizeof(buffer[0]) )))
+ {
+ // Duplicate odd behaviour from Windows:
+ if ((! uFlags & DC_SMALLCAP) || (uFlags & DC_ICON) || (uFlags & DC_INBUTTON) ||
+ (! uFlags & DC_ACTIVE))
+ r.left += GetSystemMetrics(SM_CXSIZE) + Padding;
+
+ r.right = (lprc->right - lprc->left);
+ ButtonWidth = GetSystemMetrics(SM_CXSIZE) - 2;
+ if (GetWindowLongW(hWnd, GWL_STYLE) & WS_SYSMENU)
{
- NONCLIENTMETRICS nclm;
- HFONT hFont, hOldFont;
+ r.right -= 3 + ButtonWidth;
+ if (! (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
+ {
+ r.right -= 2 + 2 * ButtonWidth;
+ }
+ }
+ r.right -= 2;
- nclm.cbSize = sizeof(NONCLIENTMETRICS);
- SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
- if (style & WS_EX_TOOLWINDOW)
+ nclm.cbSize = sizeof(nclm);
+ if (! SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &nclm, 0)) goto cleanup;
+
+ if (uFlags & DC_INBUTTON)
+ SetTextColor(MemDC, SysColours[ uFlags & DC_ACTIVE ? COLOR_BTNTEXT : COLOR_GRAYTEXT]);
+ else
+ SetTextColor(MemDC, SysColours[ uFlags & DC_ACTIVE ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT]);
+
+ SetBkMode( MemDC, TRANSPARENT );
+ if (GetWindowLongW(hWnd, GWL_STYLE) & WS_EX_TOOLWINDOW)
+// if (uFlags & DC_SMALLCAP) // incorrect
hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont);
- else
+ else
hFont = CreateFontIndirectW(&nclm.lfCaptionFont);
- hOldFont = SelectObject(hdc, hFont);
- if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
- else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
- SetBkMode( hdc, TRANSPARENT );
- /*DrawTextA( hdc, buffer, -1, &r,
- DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );*/
- TextOutA(hdc, r.left+5, r.top+2, buffer, strlen(buffer));
- DeleteObject (SelectObject (hdc, hOldFont));
+ if (! hFont) goto cleanup;
+
+ hOldFont = SelectObject(MemDC, hFont);
+ if (! hOldFont) goto cleanup;
+
+ DrawTextW(MemDC, buffer, wcslen(buffer), &r, DT_VCENTER | DT_END_ELLIPSIS);
+ // Old method:
+ // TextOutW(hDC, r.left + (GetSystemMetrics(SM_CXDLGFRAME) * 2), lprc->top + (nclm.lfCaptionFont.lfHeight / 2), buffer, wcslen(buffer));
+ }
+
+ if (uFlags & DC_BUTTONS)
+ {
+ // Windows XP draws the caption buttons with DC_BUTTONS
+// r.left += GetSystemMetrics(SM_CXSIZE) + 1;
+// UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
+// r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
+// UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
+// UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
}
+
+#ifdef DOUBLE_BUFFER_CAPTION
+ if (! BitBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
+ MemDC, 0, 0, SRCCOPY)) goto cleanup;
+#endif
+
+ result = TRUE;
+
+ cleanup :
+ if (MemDC)
+ {
+ if (OldBrush) SelectObject(MemDC, OldBrush);
+ if (hOldFont) SelectObject(MemDC, hOldFont);
+ if (hFont) DeleteObject(hFont);
+#ifdef DOUBLE_BUFFER_CAPTION
+ if (OldBMP) SelectObject(MemDC, OldBMP);
+ if (MemBMP) DeleteObject(MemBMP);
+ DeleteDC(MemDC);
+#else
+ OffsetViewportOrgEx(MemDC, -lprc->left, -lprc->top, NULL);
+#endif
+ }
+
+ return result;
}
-VOID
-UserDrawFrameNC(HDC hdc, RECT* rect, BOOL dlgFrame, BOOL active)
+
+
+static void
+UserDrawCaptionNC (
+ HDC hDC,
+ RECT *rect,
+ HWND hWnd,
+ DWORD style,
+ BOOL active )
{
- INT width, height;
-
- if (dlgFrame)
- {
- width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
- height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
- SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
- COLOR_INACTIVECAPTION) );
- }
- else
- {
- width = GetSystemMetrics(SM_CXFRAME) - 2;
- height = GetSystemMetrics(SM_CYFRAME) - 2;
- SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
- COLOR_INACTIVEBORDER) );
- }
+ POINT OldPos;
+ HPEN lPen, oPen;
+ RECT r = *rect;
+ UINT capflags = 0;
+
+ capflags = DC_ICON | DC_TEXT;
+ capflags |= (active & DC_ACTIVE);
+
+ if (GetWindowLongW(hWnd, GWL_STYLE) & WS_EX_TOOLWINDOW)
+ capflags |= DC_SMALLCAP;
+
+// Old code:
+// PatBlt(hDC,rect->left + GetSystemMetrics(SM_CXFRAME), rect->top +
+// GetSystemMetrics(SM_CYFRAME), rect->right - (GetSystemMetrics(SM_CXFRAME) * 2), (rect->top +
+// GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
+
+ r.left += GetSystemMetrics(SM_CXFRAME);
+ r.top += GetSystemMetrics(SM_CYFRAME);
+ r.right -= GetSystemMetrics(SM_CXFRAME);
+ r.bottom = r.top + GetSystemMetrics(SM_CYCAPTION) - 1;
+// GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
+
+ DrawCaption(hWnd, hDC, &r, capflags);
+
+ /* draw line below caption */
+ lPen = GetSysColorPen(COLOR_MENU);
+ oPen = SelectObject(hDC, lPen);
+ MoveToEx(hDC, r.left, r.bottom, &OldPos);
+ LineTo(hDC, r.right, r.bottom);
+ MoveToEx(hDC, OldPos.x, OldPos.y, NULL);
+ SelectObject(hDC, oPen);
+ r.bottom++;
- /* 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 - 1,
- rect->right - rect->left, -height, PATCOPY );
- PatBlt( hdc, rect->right - 1, rect->top,
- -width, rect->bottom - rect->top, PATCOPY );
+ if (style & WS_SYSMENU)
+ {
+// UserDrawSysMenuButton( hWnd, hDC, FALSE);
+ r.left += GetSystemMetrics(SM_CXSIZE) + 1;
+ UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
+ r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
+ UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
+ UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
+ }
+}
- if (dlgFrame)
- {
- InflateRect( rect, -width, -height );
- }
- else
- {
- INT decYOff = GetSystemMetrics(SM_CXFRAME) +
- GetSystemMetrics(SM_CXSIZE) - 1;
- INT decXOff = GetSystemMetrics(SM_CYFRAME) +
- GetSystemMetrics(SM_CYSIZE) - 1;
- /* Draw inner rectangle */
-
- SelectObject( hdc, GetStockObject(NULL_BRUSH) );
- Rectangle( hdc, rect->left + width, rect->top + height,
- rect->right - width , rect->bottom - height );
-
- /* Draw the decorations */
-
- MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
- LineTo( hdc, rect->left + width, rect->top + decYOff );
- MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
- LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
- MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
- LineTo( hdc, rect->left + width, rect->bottom - decYOff );
- MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
- LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
-
- MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
- LineTo( hdc, rect->left + decXOff, rect->top + height);
- MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
- LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
- MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
- LineTo( hdc, rect->right - decXOff, rect->top + height );
- MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
- LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
-
- InflateRect( rect, -width - 1, -height - 1 );
- }
+static VOID
+UserDrawFrameNC(HDC hDC, RECT* rect, BOOL dlgFrame, BOOL active)
+{
+ DrawEdge(hDC, rect,EDGE_RAISED, BF_RECT | BF_MIDDLE);
}
+
+void
+SCROLL_DrawScrollBar (HWND hWnd, HDC hDC, INT nBar, BOOL arrows, BOOL interior);
+
VOID
DefWndDoPaintNC(HWND hWnd, HRGN clip)
{
- ULONG Active;
- HDC hDc;
+ BOOL Active = FALSE;
+ HDC hDC;
RECT rect;
ULONG Style;
ULONG ExStyle;
+ int wFrame = 0;
- Active = GetWindowLongW(hWnd, GWL_STYLE) & WIN_NCACTIVATED;
- Style = GetWindowLong(hWnd, GWL_STYLE);
- ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
+ if (GetActiveWindow() == hWnd) Active = TRUE;
+ Style = GetWindowLongW(hWnd, GWL_STYLE);
+ ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
- hDc = GetDCEx(hWnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
+ hDC = GetDCEx(hWnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
((clip > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0));
- if (hDc == 0)
+ if (hDC == 0)
{
return;
}
rect.right = rect.right - rect.left;
rect.bottom = rect.bottom - rect.top;
rect.top = rect.left = 0;
-
- SelectObject(hDc, GetSysColorPen(COLOR_WINDOWFRAME));
- if (UserHasAnyFrameStyle(Style, ExStyle))
- {
- SelectObject(hDc, GetStockObject(NULL_BRUSH));
- Rectangle(hDc, 0, 0, rect.right, rect.bottom);
- InflateRect(&rect, -1, -1);
- }
-
+ SelectObject(hDC, GetSysColorPen(COLOR_WINDOWFRAME));
if (UserHasThickFrameStyle(Style, ExStyle))
{
- UserDrawFrameNC(hDc, &rect, FALSE, Active);
+ UserDrawFrameNC(hDC, &rect, FALSE, Active);
+ wFrame = GetSystemMetrics(SM_CXSIZEFRAME);
}
else if (UserHasDlgFrameStyle(Style, ExStyle))
{
- UserDrawFrameNC(hDc, &rect, TRUE, Active);
+ UserDrawFrameNC(hDC, &rect, TRUE, Active);
+ wFrame = GetSystemMetrics(SM_CXDLGFRAME);
}
-
if (Style & WS_CAPTION)
{
RECT r = rect;
r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
- rect.top += GetSystemMetrics(SM_CYSIZE) +
+ rect.top += GetSystemMetrics(SM_CYSIZE) +
GetSystemMetrics(SM_CYBORDER);
- UserDrawCaptionNC(hDc, &r, hWnd, Style, Active);
+ UserDrawCaptionNC(hDC, &r, hWnd, Style, Active);
}
- /* FIXME: Draw menu bar. */
+ /* Draw menu bar. */
+ if (UserHasMenu(hWnd, Style))
+ {
+ RECT r = rect;
+ r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
+ r.left += wFrame;
+ r.right -= wFrame;
+ rect.top += MenuDrawMenuBar(hDC, &r, hWnd, FALSE);
+ }
- /* FIXME: Draw scroll bars. */
+ /* Draw scrollbars */
+ if (Style & WS_VSCROLL)
+ SCROLL_DrawScrollBar(hWnd, hDC, SB_VERT, TRUE, TRUE);
+ if (Style & WS_HSCROLL)
+ SCROLL_DrawScrollBar(hWnd, hDC, SB_HORZ, TRUE, TRUE);
- /* FIXME: Draw size box. */
-
- ReleaseDC(hWnd, hDc);
+ /* FIXME: Draw size box.*/
+
+ ReleaseDC(hWnd, hDC);
}
+
LRESULT
DefWndPaintNC(HWND hWnd, HRGN clip)
{
return(0);
}
+
LRESULT
DefWndHitTestNC(HWND hWnd, POINT Point)
{
RECT WindowRect;
- ULONG Style = GetWindowLong(hWnd, GWL_STYLE);
- ULONG ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
+ ULONG Style = GetWindowLongW(hWnd, GWL_STYLE);
+ ULONG ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
GetWindowRect(hWnd, &WindowRect);
-
if (!PtInRect(&WindowRect, Point))
- {
+ {
return(HTNOWHERE);
}
if (Style & WS_MINIMIZE)
}
return(HTRIGHT);
}
- }
+ }
}
- else
+ else
{
if (UserHasDlgFrameStyle(Style, ExStyle))
{
if ((Style & WS_CAPTION) == WS_CAPTION)
{
- WindowRect.top += GetSystemMetrics(SM_CYCAPTION) -
- GetSystemMetrics(SM_CYBORDER);
+ WindowRect.top += (GetSystemMetrics(SM_CYCAPTION) -
+ GetSystemMetrics(SM_CYBORDER));
if (!PtInRect(&WindowRect, Point))
{
if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW))
{
WindowRect.left += GetSystemMetrics(SM_CXSIZE);
+ WindowRect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
}
if (Point.x <= WindowRect.left)
{
return(HTSYSMENU);
}
+ if (WindowRect.right <= Point.x)
+ {
+ return(HTCLOSE);
+ }
- if (Style & WS_MAXIMIZEBOX)
+ if (Style & WS_MAXIMIZEBOX || Style & WS_MINIMIZEBOX)
{
- WindowRect.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
+ WindowRect.right -= GetSystemMetrics(SM_CXSIZE);
}
if (Point.x >= WindowRect.right)
{
if (Style & WS_MINIMIZEBOX)
{
- WindowRect.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
+ WindowRect.right -= GetSystemMetrics(SM_CXSIZE);
}
if (Point.x >= WindowRect.right)
{
if ((Style & WS_VSCROLL) &&
(Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXVSCROLL))))
{
- return(HTSIZE);
+ return(HTBOTTOMRIGHT);
}
return(HTHSCROLL);
}
return(HTNOWHERE);
}
-VOID
-DefWndTrackMinMaxBox(HWND hWnd, WPARAM wParam)
+VOID STATIC
+DefWndDoButton(HWND hWnd, WPARAM wParam)
{
- HDC hDC = GetWindowDC(hWnd);
- BOOL Pressed = TRUE;
MSG Msg;
-
+ BOOL InBtn = TRUE, HasBtn = FALSE;
+ ULONG Btn;
+ WPARAM SCMsg, CurBtn = wParam, OrigBtn = wParam;
+
+ switch(wParam)
+ {
+ case HTCLOSE:
+ Btn = DFCS_CAPTIONCLOSE;
+ SCMsg = SC_CLOSE;
+ HasBtn = IsCloseBoxActive(hWnd);
+ break;
+ case HTMINBUTTON:
+ Btn = DFCS_CAPTIONMIN;
+ SCMsg = SC_MINIMIZE;
+ HasBtn = IsMinBoxActive(hWnd);
+ break;
+ case HTMAXBUTTON:
+ Btn = DFCS_CAPTIONMAX;
+ SCMsg = SC_MAXIMIZE;
+ HasBtn = IsMaxBoxActive(hWnd);
+ break;
+ default:
+ return;
+ }
+
+ if(!HasBtn)
+ return;
+
SetCapture(hWnd);
-
- if (wParam == HTMINBUTTON)
- {
- UserDrawMinButton(hWnd, hDC, TRUE);
- }
- else
+ UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), HasBtn , Btn);
+
+ while(1)
+ {
+ GetMessageW(&Msg, 0, 0, 0);
+ switch(Msg.message)
{
- UserDrawMaxButton(hWnd, hDC, TRUE);
+ case WM_NCLBUTTONUP:
+ case WM_LBUTTONUP:
+ if(InBtn)
+ goto done;
+ else
+ {
+ ReleaseCapture();
+ return;
+ }
+ case WM_NCMOUSEMOVE:
+ case WM_MOUSEMOVE:
+ CurBtn = DefWndHitTestNC(hWnd, Msg.pt);
+ if(InBtn != (CurBtn == OrigBtn))
+ {
+ UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), (CurBtn == OrigBtn) , Btn);
+ }
+ InBtn = CurBtn == OrigBtn;
+ break;
}
+ }
+
+done:
+ UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), FALSE , Btn);
+ ReleaseCapture();
+ SendMessageA(hWnd, WM_SYSCOMMAND, SCMsg, 0);
+ return;
+}
- for(;;)
- {
- BOOL OldState = Pressed;
-
- GetMessageA(hWnd, &Msg, 0, 0);
- if (Msg.message == WM_LBUTTONUP)
- {
- break;
- }
- if (Msg.message != WM_MOUSEMOVE)
- {
- continue;
- }
+VOID STATIC
+DefWndDoScrollBarDown(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ POINT Point;
+ DWORD hit;
+ Point.x = SLOWORD(lParam);
+ Point.y = SHIWORD(lParam);
+
+ hit = SCROLL_HitTest(hWnd, (wParam == HTHSCROLL) ? SB_HORZ : SB_VERT, Point, FALSE);
+
+ if(hit)
+ DbgPrint("SCROLL_HitTest() == 0x%x\n", hit);
+
+ SendMessageA(hWnd, WM_SYSCOMMAND, Msg + (UINT)wParam, lParam);
+}
- Pressed = DefWndHitTestNC(hWnd, Msg.pt) == wParam;
- if (Pressed != OldState)
- {
- if (wParam == HTMINBUTTON)
- {
- UserDrawMinButton(hWnd, hDC, Pressed);
- }
- else
- {
- UserDrawMaxButton(hWnd, hDC, Pressed);
+LRESULT
+DefWndHandleLButtonDownNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ switch (wParam)
+ {
+ case HTCAPTION:
+ {
+ HWND hTopWnd = GetAncestor(hWnd, GA_ROOT);
+ if (SetActiveWindow(hTopWnd) || GetActiveWindow() == hTopWnd)
+ {
+ SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam);
+ }
+ break;
+ }
+ case HTSYSMENU:
+ {
+ if (GetWindowLongW(hWnd, GWL_STYLE) & WS_SYSMENU)
+ {
+ if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
+ {
+ HDC hDC = GetWindowDC(hWnd);
+// UserDrawSysMenuButton(hWnd, hDC, TRUE);
+ ReleaseDC(hWnd, hDC);
+ }
+ SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU,
+ lParam);
}
- }
+ break;
+ }
+ case HTMENU:
+ {
+ SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTMENU, lParam);
+ break;
+ }
+ case HTHSCROLL:
+ {
+ DefWndDoScrollBarDown(hWnd, SC_HSCROLL, HTHSCROLL, lParam);
+ //SendMessageA(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam);
+ break;
+ }
+ case HTVSCROLL:
+ {
+ DefWndDoScrollBarDown(hWnd, SC_VSCROLL, HTVSCROLL, lParam);
+ //SendMessageA(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam);
+ break;
+ }
+ case HTMINBUTTON:
+ case HTMAXBUTTON:
+ case HTCLOSE:
+ {
+ DefWndDoButton(hWnd, wParam);
+ break;
+ }
+ case HTLEFT:
+ case HTRIGHT:
+ case HTTOP:
+ case HTBOTTOM:
+ case HTTOPLEFT:
+ case HTTOPRIGHT:
+ case HTBOTTOMLEFT:
+ case HTBOTTOMRIGHT:
+ {
+ SendMessageA(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
+ break;
+ }
}
+ return(0);
+}
- if (Pressed)
- {
- if (wParam == HTMINBUTTON)
- {
- UserDrawMinButton(hWnd, hDC, FALSE);
- }
- else
- {
- UserDrawMaxButton(hWnd, hDC, FALSE);
- }
- }
- ReleaseCapture();
- ReleaseDC(hWnd, hDC);
+LRESULT
+DefWndHandleLButtonDblClkNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ UNIMPLEMENTED;
+ return(0);
+}
- if (!Pressed)
- {
- return;
- }
- if (wParam == HTMINBUTTON)
- {
- SendMessageA(hWnd, WM_SYSCOMMAND, SC_MINIMIZE,
- MAKELONG(Msg.pt.x, Msg.pt.y));
- }
- else
- {
- SendMessageA(hWnd, WM_SYSCOMMAND,
- IsZoomed(hWnd) ? SC_RESTORE : SC_MAXIMIZE,
- MAKELONG(Msg.pt.x, Msg.pt.y));
- }
+LRESULT
+DefWndHandleLButtonUpNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ UNIMPLEMENTED;
+ return(0);
+}
+
+
+LRESULT
+DefWndHandleActiveNC(HWND hWnd, WPARAM wParam)
+{
+ UNIMPLEMENTED;
+ return(0);
}
+
VOID
-DefWndDrawSysButton(HWND hWnd, HDC hDC, BOOL Down)
+DefWndSetRedraw(HWND hWnd, WPARAM wParam)
{
- RECT Rect;
- HDC hDcMem;
- HBITMAP hSavedBitmap;
-
- UserGetInsideRectNC(hWnd, &Rect);
- hDcMem = CreateCompatibleDC(hDC);
- hSavedBitmap = SelectObject(hDcMem, hbitmapClose);
- BitBlt(hDC, Rect.left, Rect.top, GetSystemMetrics(SM_CXSIZE),
- GetSystemMetrics(SM_CYSIZE), hDcMem,
- (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) ?
- GetSystemMetrics(SM_CXSIZE): 0, 0, Down ? NOTSRCCOPY : SRCCOPY);
- SelectObject(hDcMem, hSavedBitmap);
- DeleteDC(hDcMem);
+ UNIMPLEMENTED;
}
+
LRESULT
-DefWndHandleLButtonDownNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
-{
- switch (wParam)
- {
- case HTCAPTION:
- {
- HWND hTopWnd = GetAncestor(hWnd, GA_ROOT);
- if (SetActiveWindow(hTopWnd) || GetActiveWindow() == hTopWnd)
- {
- SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam);
- }
- break;
- }
- case HTSYSMENU:
- {
- if (GetWindowLong(hWnd, GWL_STYLE) & WS_SYSMENU)
- {
- if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE))
- {
- HDC hDC = GetWindowDC(hWnd);
- DefWndDrawSysButton(hWnd, hDC, TRUE);
- ReleaseDC(hWnd, hDC);
- }
- SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU,
- lParam);
- }
- break;
- }
-
- case HTMENU:
- SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
- break;
-
- case HTHSCROLL:
- SendMessageA(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam);
- break;
-
- case HTVSCROLL:
- SendMessageA(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam);
- break;
-
- case HTMINBUTTON:
- case HTMAXBUTTON:
- DefWndTrackMinMaxBox(hWnd, wParam);
- break;
-
- case HTLEFT:
- case HTRIGHT:
- case HTTOP:
- case HTBOTTOM:
- case HTTOPLEFT:
- case HTTOPRIGHT:
- case HTBOTTOMLEFT:
- case HTBOTTOMRIGHT:
- SendMessageA(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
- break;
- }
- return(0);
-}
-
-LRESULT
-DefWndHandleLButtonDblClkNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
-{
- /* FIXME: Implement this. */
- return(0);
-}
-
-LRESULT
-DefWndHandleActiveNC(HWND hWnd, WPARAM wParam)
-{
- /* FIXME: Implement this. */
- return(0);
-}
-
-VOID
-DefWndSetRedraw(HWND hWnd, WPARAM wParam)
-{
-}
-
-LRESULT
DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
/* Not for child windows. */
case HTCLIENT:
{
- HICON hCursor = (HICON)GetClassLong(hWnd, GCL_HCURSOR);
+ HICON hCursor = (HICON)GetClassLongW(hWnd, GCL_HCURSOR);
if (hCursor)
{
SetCursor(hCursor);
return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW)));
}
+static LONG
+DefWndStartSizeMove(HWND hWnd, WPARAM wParam, POINT *capturePoint)
+{
+ LONG hittest = 0;
+ POINT pt;
+ MSG msg;
+ RECT rectWindow;
+ ULONG Style = GetWindowLongW(hWnd, GWL_STYLE);
+
+ GetWindowRect(hWnd, &rectWindow);
+
+ if ((wParam & 0xfff0) == SC_MOVE)
+ {
+ /* Move pointer at the center of the caption */
+ RECT rect;
+ UserGetInsideRectNC(hWnd, &rect);
+ if (Style & WS_SYSMENU)
+ rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
+ if (Style & WS_MINIMIZEBOX)
+ rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+ if (Style & WS_MAXIMIZEBOX)
+ rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
+ pt.x = rectWindow.left + (rect.right - rect.left) / 2;
+ pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
+ hittest = HTCAPTION;
+ *capturePoint = pt;
+ }
+ else /* SC_SIZE */
+ {
+ while(!hittest)
+ {
+ GetMessageW(&msg, NULL, 0, 0);
+ switch(msg.message)
+ {
+ case WM_MOUSEMOVE:
+ hittest = DefWndHitTestNC(hWnd, msg.pt);
+ if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
+ hittest = 0;
+ break;
+
+ case WM_LBUTTONUP:
+ return 0;
+
+ case WM_KEYDOWN:
+ switch(msg.wParam)
+ {
+ case VK_UP:
+ hittest = HTTOP;
+ pt.x =(rectWindow.left+rectWindow.right)/2;
+ pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
+ break;
+ case VK_DOWN:
+ hittest = HTBOTTOM;
+ pt.x =(rectWindow.left+rectWindow.right)/2;
+ pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
+ break;
+ case VK_LEFT:
+ hittest = HTLEFT;
+ pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
+ pt.y =(rectWindow.top+rectWindow.bottom)/2;
+ break;
+ case VK_RIGHT:
+ hittest = HTRIGHT;
+ pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
+ pt.y =(rectWindow.top+rectWindow.bottom)/2;
+ break;
+ case VK_RETURN:
+ case VK_ESCAPE: return 0;
+ }
+ }
+ }
+ *capturePoint = pt;
+ }
+ SetCursorPos( pt.x, pt.y );
+ DefWndHandleSetCursor(hWnd, (WPARAM)hWnd, MAKELONG(hittest, WM_MOUSEMOVE));
+ return hittest;
+}
+
+#define ON_LEFT_BORDER(hit) \
+ (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
+#define ON_RIGHT_BORDER(hit) \
+ (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
+#define ON_TOP_BORDER(hit) \
+ (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
+#define ON_BOTTOM_BORDER(hit) \
+ (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
+
+VOID STATIC
+UserDrawWindowFrame(HDC hdc, const RECT *rect,
+ ULONG width, ULONG height, DWORD rop )
+{
+ HBRUSH hbrush = SelectObject( hdc, GetStockObject( GRAY_BRUSH ) );
+ PatBlt( hdc, rect->left, rect->top,
+ rect->right - rect->left - width, height, rop );
+ PatBlt( hdc, rect->left, rect->top + height, width,
+ rect->bottom - rect->top - height, rop );
+ PatBlt( hdc, rect->left + width, rect->bottom - 1,
+ rect->right - rect->left - width, -height, rop );
+ PatBlt( hdc, rect->right - 1, rect->top, -width,
+ rect->bottom - rect->top - height, rop );
+ SelectObject( hdc, hbrush );
+}
+
+VOID STATIC
+UserDrawMovingFrame(HDC hdc, RECT *rect, BOOL thickframe)
+{
+ if (thickframe)
+ {
+ UserDrawWindowFrame(hdc, rect, GetSystemMetrics(SM_CXFRAME),
+ GetSystemMetrics(SM_CYFRAME), PATINVERT );
+ }
+ else DrawFocusRect( hdc, rect );
+}
+
+VOID STATIC
+DefWndDoSizeMove(HWND hwnd, WORD wParam)
+{
+ MSG msg;
+ RECT sizingRect, mouseRect, origRect;
+ HDC hdc;
+ LONG hittest = (LONG)(wParam & 0x0f);
+ HCURSOR hDragCursor = 0, hOldCursor = 0;
+ POINT minTrack, maxTrack;
+ POINT capturePoint, pt;
+ ULONG Style = GetWindowLongW(hwnd, GWL_STYLE);
+ ULONG ExStyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
+ BOOL thickframe = UserHasThickFrameStyle(Style, ExStyle);
+ BOOL iconic = Style & WS_MINIMIZE;
+ BOOL moved = FALSE;
+ DWORD dwPoint = GetMessagePos();
+ BOOL DragFullWindows = FALSE;
+ HWND hWndParent;
+
+ SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
+
+ pt.x = SLOWORD(dwPoint);
+ pt.y = SHIWORD(dwPoint);
+ capturePoint = pt;
+
+ if (IsZoomed(hwnd) || !IsWindowVisible(hwnd))
+ {
+ return;
+ }
+
+ if ((wParam & 0xfff0) == SC_MOVE)
+ {
+ if (!hittest)
+ {
+ hittest = DefWndStartSizeMove(hwnd, wParam, &capturePoint);
+ }
+ if (!hittest)
+ {
+ return;
+ }
+ }
+ else /* SC_SIZE */
+ {
+ if (!thickframe)
+ {
+ return;
+ }
+ if (hittest && hittest != HTSYSMENU)
+ {
+ hittest += 2;
+ }
+ else
+ {
+ SetCapture(hwnd);
+ hittest = DefWndStartSizeMove(hwnd, wParam, &capturePoint);
+ if (!hittest)
+ {
+ ReleaseCapture();
+ return;
+ }
+ }
+ }
+
+ if (Style & WS_CHILD)
+ {
+ hWndParent = GetParent(hwnd);
+ }
+
+ /* Get min/max info */
+
+ WinPosGetMinMaxInfo(hwnd, NULL, NULL, &minTrack, &maxTrack);
+ GetWindowRect(hwnd, &sizingRect);
+ origRect = sizingRect;
+ if (Style & WS_CHILD)
+ {
+ GetClientRect(hWndParent, &mouseRect );
+ }
+ else
+ {
+ SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN),
+ GetSystemMetrics(SM_CYSCREEN));
+ }
+ if (ON_LEFT_BORDER(hittest))
+ {
+ mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
+ mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
+ }
+ else if (ON_RIGHT_BORDER(hittest))
+ {
+ mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
+ mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
+ }
+ if (ON_TOP_BORDER(hittest))
+ {
+ mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
+ mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
+ }
+ else if (ON_BOTTOM_BORDER(hittest))
+ {
+ mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
+ mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
+ }
+ if (Style & WS_CHILD)
+ {
+ MapWindowPoints( hWndParent, 0, (LPPOINT)&mouseRect, 2 );
+ }
+ SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
+
+ if (GetCapture() != hwnd) SetCapture( hwnd );
+
+ if (Style & WS_CHILD)
+ {
+ /* Retrieve a default cache DC (without using the window style) */
+ hdc = GetDCEx(hWndParent, 0, DCX_CACHE);
+ }
+ else
+ {
+ hdc = GetDC( 0 );
+ }
+
+ if( iconic ) /* create a cursor for dragging */
+ {
+ HICON hIcon = (HICON)GetClassLongW(hwnd, GCL_HICON);
+ if(!hIcon) hIcon = (HICON)SendMessageW( hwnd, WM_QUERYDRAGICON, 0, 0L);
+ if( hIcon ) hDragCursor = CursorIconToCursor( hIcon, TRUE );
+ if( !hDragCursor ) iconic = FALSE;
+ }
+
+ /* invert frame if WIN31_LOOK to indicate mouse click on caption */
+ if( !iconic && !DragFullWindows)
+ {
+ UserDrawMovingFrame( hdc, &sizingRect, thickframe );
+ }
+
+ while(1)
+ {
+ int dx = 0, dy = 0;
+
+ GetMessageW(&msg, 0, 0, 0);
+
+ /* Exit on button-up, Return, or Esc */
+ if ((msg.message == WM_LBUTTONUP) ||
+ ((msg.message == WM_KEYDOWN) &&
+ ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
+
+ if (msg.message == WM_PAINT)
+ {
+ if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
+ UpdateWindow( msg.hwnd );
+ if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
+ continue;
+ }
+
+ if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
+ continue; /* We are not interested in other messages */
+
+ pt = msg.pt;
+
+ if (msg.message == WM_KEYDOWN) switch(msg.wParam)
+ {
+ case VK_UP: pt.y -= 8; break;
+ case VK_DOWN: pt.y += 8; break;
+ case VK_LEFT: pt.x -= 8; break;
+ case VK_RIGHT: pt.x += 8; break;
+ }
+
+ pt.x = max( pt.x, mouseRect.left );
+ pt.x = min( pt.x, mouseRect.right );
+ pt.y = max( pt.y, mouseRect.top );
+ pt.y = min( pt.y, mouseRect.bottom );
+
+ dx = pt.x - capturePoint.x;
+ dy = pt.y - capturePoint.y;
+
+ if (dx || dy)
+ {
+ if( !moved )
+ {
+ moved = TRUE;
+
+ if( iconic ) /* ok, no system popup tracking */
+ {
+ hOldCursor = SetCursor(hDragCursor);
+ ShowCursor( TRUE );
+ WinPosShowIconTitle( hwnd, FALSE );
+ }
+ }
+
+ if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
+ else
+ {
+ RECT newRect = sizingRect;
+ WPARAM wpSizingHit = 0;
+
+ if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
+ if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
+ else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
+ if (ON_TOP_BORDER(hittest)) newRect.top += dy;
+ else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
+ if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
+ capturePoint = pt;
+
+ /* determine the hit location */
+ if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
+ wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
+ SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
+
+ if (!iconic)
+ {
+ if(!DragFullWindows)
+ UserDrawMovingFrame( hdc, &newRect, thickframe );
+ else {
+ /* To avoid any deadlocks, all the locks on the windows
+ structures must be suspended before the SetWindowPos */
+ SetWindowPos( hwnd, 0, newRect.left, newRect.top,
+ newRect.right - newRect.left,
+ newRect.bottom - newRect.top,
+ ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
+ }
+ }
+ sizingRect = newRect;
+ }
+ }
+ }
+
+ ReleaseCapture();
+ if( iconic )
+ {
+ if( moved ) /* restore cursors, show icon title later on */
+ {
+ ShowCursor( FALSE );
+ SetCursor( hOldCursor );
+ }
+ DestroyCursor( hDragCursor );
+ }
+ else if(!DragFullWindows)
+ UserDrawMovingFrame( hdc, &sizingRect, thickframe );
+
+ if (Style & WS_CHILD)
+ ReleaseDC( hWndParent, hdc );
+ else
+ ReleaseDC( 0, hdc );
+
+ SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
+ SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
+
+ /* window moved or resized */
+ if (moved)
+ {
+ /* if the moving/resizing isn't canceled call SetWindowPos
+ * with the new position or the new size of the window
+ */
+ if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
+ {
+ /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
+ if(!DragFullWindows)
+ SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
+ sizingRect.right - sizingRect.left,
+ sizingRect.bottom - sizingRect.top,
+ ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
+ }
+ else { /* restore previous size/position */
+ if(DragFullWindows)
+ SetWindowPos( hwnd, 0, origRect.left, origRect.top,
+ origRect.right - origRect.left,
+ origRect.bottom - origRect.top,
+ ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
+ }
+ }
+
+ if( IsWindow(hwnd) )
+ if( Style & WS_MINIMIZE )
+ {
+ /* Single click brings up the system menu when iconized */
+
+ if( !moved )
+ {
+ if( Style & WS_SYSMENU )
+ SendMessageA( hwnd, WM_SYSCOMMAND,
+ SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
+ }
+ else WinPosShowIconTitle( hwnd, TRUE );
+ }
+}
+
+
LRESULT
DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
{
- /* FIXME: Implement system commands. */
+ switch (wParam & 0xfff0)
+ {
+ case SC_MOVE:
+ case SC_SIZE:
+ DefWndDoSizeMove(hWnd, wParam);
+ break;
+ case SC_CLOSE:
+ SendMessageA(hWnd, WM_CLOSE, 0, 0);
+ break;
+ case SC_MOUSEMENU:
+ MenuTrackMouseMenuBar(hWnd, wParam, Pt);
+ break;
+ case SC_KEYMENU:
+ MenuTrackKbdMenuBar(hWnd, wParam, Pt.x);
+ break;
+ default:
+ /* FIXME: Implement */
+ UNIMPLEMENTED;
+ break;
+ }
+
return(0);
}
+
VOID
DefWndAdjustRect(RECT* Rect, ULONG Style, BOOL Menu, ULONG ExStyle)
{
if (UserHasThickFrameStyle(Style, ExStyle))
{
- InflateRect(Rect, GetSystemMetrics(SM_CXFRAME),
+ InflateRect(Rect, GetSystemMetrics(SM_CXFRAME),
GetSystemMetrics(SM_CYFRAME));
}
else if (UserHasDlgFrameStyle(Style, ExStyle))
}
if (Style & WS_CAPTION)
{
- Rect->top -= GetSystemMetrics(SM_CYCAPTION) -
- GetSystemMetrics(SM_CYBORDER);
+ Rect->top -= (GetSystemMetrics(SM_CYCAPTION) -
+ GetSystemMetrics(SM_CYBORDER)) + 1;
}
if (Menu)
{
LRESULT STDCALL
DefWndNCCalcSize(HWND hWnd, RECT* Rect)
{
- LRESULT Result = 0;
- LONG Style = GetClassLongW(hWnd, GCL_STYLE);
- RECT TmpRect = {0, 0, 0, 0};
+ LRESULT Result = 0;
+ LONG Style = GetClassLongW(hWnd, GCL_STYLE);
+ RECT TmpRect = {0, 0, 0, 0};
- if (Style & CS_VREDRAW)
+ if (Style & CS_VREDRAW)
{
- Result |= WVR_VREDRAW;
+ Result |= WVR_VREDRAW;
}
- if (Style & CS_HREDRAW)
+ if (Style & CS_HREDRAW)
{
- Result |= WVR_HREDRAW;
+ Result |= WVR_HREDRAW;
}
- if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE))
+ if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
{
- DefWndAdjustRect(&TmpRect, GetWindowLong(hWnd, GWL_STYLE),
- FALSE, GetWindowLong(hWnd, GWL_EXSTYLE));
- Rect->left -= TmpRect.left;
- Rect->top -= TmpRect.top;
- Rect->right -= TmpRect.right;
- Rect->bottom -= TmpRect.bottom;
- /* FIXME: Adjust if the window has a menu. */
- Rect->bottom = max(Rect->top, Rect->bottom);
- Rect->right = max(Rect->left, Rect->right);
+ DefWndAdjustRect(&TmpRect, GetWindowLongW(hWnd, GWL_STYLE),
+ FALSE, GetWindowLongW(hWnd, GWL_EXSTYLE));
+ Rect->left -= TmpRect.left;
+ Rect->top -= TmpRect.top;
+ Rect->right -= TmpRect.right;
+ Rect->bottom -= TmpRect.bottom;
+ if (UserHasMenu(hWnd, GetWindowLongW(hWnd, GWL_STYLE)))
+ {
+ Rect->top += MenuGetMenuBarHeight(hWnd, Rect->right - Rect->left,
+ -TmpRect.left, -TmpRect.top) + 1;
+ }
+ if (Rect->top > Rect->bottom)
+ Rect->bottom = Rect->top;
+ if (Rect->left > Rect->right)
+ Rect->right = Rect->left;
}
- return(Result);
+
+ return (Result);
}
LRESULT
DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos)
{
- /* FIXME: Implement this. */
- return(0);
-}
+ POINT maxSize, minTrack;
+ LONG style = GetWindowLongA(hWnd, GWL_STYLE);
-LRESULT STDCALL
-User32DefWindowProc(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- BOOL bUnicode)
-{
- switch (Msg)
+ if (Pos->flags & SWP_NOSIZE) return 0;
+ if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
{
- case WM_NCPAINT:
- {
- return(DefWndPaintNC(hWnd, (HRGN)wParam));
- }
-
- case WM_NCHITTEST:
- {
- POINT Point;
- Point.x = SLOWORD(lParam);
- Point.y = SHIWORD(lParam);
- return(DefWndHitTestNC(hWnd, Point));
- }
-
- case WM_NCLBUTTONDOWN:
- {
- return(DefWndHandleLButtonDownNC(hWnd, wParam, lParam));
- }
-
- case WM_LBUTTONDBLCLK:
- case WM_NCLBUTTONDBLCLK:
- {
- return(DefWndHandleLButtonDblClkNC(hWnd, wParam, lParam));
- }
-
- case WM_NCRBUTTONDOWN:
- {
- if (wParam == HTCAPTION)
- {
- SetCapture(hWnd);
- }
- break;
- }
-
- case WM_RBUTTONUP:
- {
- POINT Pt;
- if (hWnd == GetCapture())
- {
- ReleaseCapture();
- }
- Pt.x = SLOWORD(lParam);
- Pt.y = SHIWORD(lParam);
- ClientToScreen(hWnd, &Pt);
- lParam = MAKELPARAM(Pt.x, Pt.y);
- if (bUnicode)
- {
- SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
- }
- else
- {
- SendMessageA (hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
- }
- break;
- }
-
- case WM_NCRBUTTONUP:
- {
- /* Wine does nothing here. */
- break;
- }
-
- case WM_CONTEXTMENU:
- {
- if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
- {
- if (bUnicode)
- {
- SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
- }
- else
- {
- SendMessageA(hWnd, WM_CONTEXTMENU, wParam, lParam);
- }
- }
- else
- {
- LONG HitCode;
- POINT Pt;
-
- Pt.x = SLOWORD(lParam);
- Pt.y = SHIWORD(lParam);
-
- if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
- {
- ScreenToClient(GetParent(hWnd), &Pt);
- }
-
- HitCode = DefWndHitTestNC(hWnd, Pt);
-
- if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
- {
- TrackPopupMenu(GetSystemMenu(hWnd, FALSE),
- TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
- Pt.x, Pt.y, 0, hWnd, NULL);
- }
- }
- break;
- }
-
- case WM_NCACTIVATE:
- {
- return(DefWndHandleActiveNC(hWnd, wParam));
- }
-
- case WM_NCDESTROY:
- {
- return(0);
- }
-
- case WM_PRINT:
- {
- return(0);
- }
-
- case WM_PAINTICON:
- case WM_PAINT:
- {
- PAINTSTRUCT Ps;
- HDC hDc = BeginPaint(hWnd, &Ps);
- if (hDc)
- {
- HICON hIcon;
- if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE &&
- (hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON)) != NULL)
- {
- RECT WindowRect;
- INT x, y;
- GetWindowRect(hWnd, &WindowRect);
- x = (WindowRect.right - WindowRect.left -
- GetSystemMetrics(SM_CXICON)) / 2;
- y = (WindowRect.bottom - WindowRect.top -
- GetSystemMetrics(SM_CYICON)) / 2;
- DrawIcon(hDc, x, y, hIcon);
- }
- EndPaint(hWnd, &Ps);
- }
- return(0);
- }
-
- case WM_SYNCPAINT:
- {
- HRGN hRgn;
- hRgn = CreateRectRgn(0, 0, 0, 0);
- if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
- {
- RedrawWindow(hWnd, NULL, hRgn,
- RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
- RDW_ALLCHILDREN);
- }
- DeleteObject(hRgn);
- return(0);
- }
-
- case WM_SETREDRAW:
- {
- DefWndSetRedraw(hWnd, wParam);
- return(0);
- }
-
- case WM_CLOSE:
- {
- DestroyWindow(hWnd);
- return(0);
- }
-
- case WM_MOUSEACTIVATE:
- {
- if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
- {
- LONG Ret;
- if (bUnicode)
- {
- Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
- wParam, lParam);
- }
- else
- {
- Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
- wParam, lParam);
- }
- if (Ret)
- {
- return(Ret);
- }
- }
- return((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
- }
-
- case WM_ACTIVATE:
- {
- if (LOWORD(lParam) != WA_INACTIVE &&
- GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE)
- {
- /* Check if the window is minimized. */
- SetFocus(hWnd);
- }
- break;
- }
-
- case WM_MOUSEWHEEL:
- {
- if (GetWindowLong(hWnd, GWL_STYLE & WS_CHILD))
- {
- if (bUnicode)
- {
- return(SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
- wParam, lParam));
- }
- else
- {
- return(SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
- wParam, lParam));
- }
- }
- break;
- }
-
- case WM_ERASEBKGND:
- case WM_ICONERASEBKGND:
- {
- RECT Rect;
- HBRUSH hBrush = (HBRUSH)GetClassLongW(hWnd, GCL_HBRBACKGROUND);
- GetClipBox((HDC)wParam, &Rect);
- FillRect((HDC)wParam, &Rect, hBrush);
- return(1);
- }
-
- case WM_GETDLGCODE:
- {
- return(0);
- }
-
- /* FIXME: Implement colour controls. */
-
- case WM_SETCURSOR:
- {
- if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
- {
- if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
- {
- BOOL bResult;
- if (bUnicode)
- {
- bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR,
- wParam, lParam);
- }
- else
- {
- bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR,
- wParam, lParam);
- }
- if (bResult)
- {
- return(TRUE);
- }
- }
- }
- return(DefWndHandleSetCursor(hWnd, wParam, lParam));
- }
-
- case WM_SYSCOMMAND:
- {
- POINT Pt;
- Pt.x = SLOWORD(lParam);
- Pt.y = SHIWORD(lParam);
- return(DefWndHandleSysCommand(hWnd, wParam, Pt));
- }
-
- /* FIXME: Handle key messages. */
+ WinPosGetMinMaxInfo(hWnd, &maxSize, NULL, &minTrack, NULL);
+ Pos->cx = min(Pos->cx, maxSize.x);
+ Pos->cy = min(Pos->cy, maxSize.y);
+ if (!(style & WS_MINIMIZE))
+ {
+ if (Pos->cx < minTrack.x) Pos->cx = minTrack.x;
+ if (Pos->cy < minTrack.y) Pos->cy = minTrack.y;
+ }
+ }
+ return 0;
+}
- case WM_SHOWWINDOW:
- {
- if (lParam)
- {
- return(0);
- }
- /* FIXME: Check for a popup window. */
- if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE && !wParam) ||
- (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE) && wParam))
- {
- return(0);
- }
- ShowWindow(hWnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE);
- break;
- }
+/* Undocumented flags. */
+#define SWP_NOCLIENTMOVE 0x0800
+#define SWP_NOCLIENTSIZE 0x1000
- case WM_CANCELMODE:
- {
- /* FIXME: Check for a desktop. */
- if (GetCapture() == hWnd)
- {
- ReleaseCapture();
- }
- break;
- }
+LRESULT
+DefWndHandleWindowPosChanged(HWND hWnd, WINDOWPOS* Pos)
+{
+ RECT rect;
- case WM_VKEYTOITEM:
- case WM_CHARTOITEM:
- return(-1);
+ GetClientRect(hWnd, &rect);
- case WM_DROPOBJECT:
- /* FIXME: Implement this. */
- break;
+ if (!(Pos->flags & SWP_NOCLIENTMOVE))
+ SendMessageW(hWnd, WM_MOVE, 0, MAKELONG(rect.left, rect.top));
- case WM_QUERYDROPOBJECT:
- {
- if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
- {
- return(1);
- }
- break;
- }
+ if (!(Pos->flags & SWP_NOCLIENTSIZE))
+ {
+ WPARAM wp = SIZE_RESTORED;
+ if (IsZoomed(hWnd)) wp = SIZE_MAXIMIZED;
+ else if (IsIconic(hWnd)) wp = SIZE_MINIMIZED;
+ SendMessageW(hWnd, WM_SIZE, wp,
+ MAKELONG(rect.right - rect.left, rect.bottom - rect.top));
+ }
- case WM_QUERYDRAGICON:
- {
- UINT Len;
- HICON hIcon;
+ return 0;
+}
- hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON);
- if (hIcon)
- {
- return((LRESULT)hIcon);
- }
- for (Len = 1; Len < 64; Len++)
- {
- if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCE(Len))) != NULL)
- {
- return((LRESULT)hIcon);
- }
- }
- return((LRESULT)LoadIconW(0, IDI_APPLICATION));
- }
+/***********************************************************************
+ * DefWndControlColor
+ *
+ * Default colors for control painting.
+ */
+static HBRUSH
+DefWndControlColor(HDC hDC, UINT ctlType)
+{
+ if (CTLCOLOR_SCROLLBAR == ctlType)
+ {
+ HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
+ COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
+ SetTextColor(hDC, GetSysColor(COLOR_3DFACE));
+ SetBkColor(hDC, bk);
+
+ /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
+ * we better use 0x55aa bitmap brush to make scrollbar's background
+ * look different from the window background.
+ */
+ if (bk == GetSysColor(COLOR_WINDOW))
+ {
+#if 0 /* FIXME */
+ return CACHE_GetPattern55AABrush();
+#else
+ return NULL;
+#endif
+ }
+ UnrealizeObject(hb);
+ return hb;
+ }
- /* FIXME: WM_ISACTIVEICON */
+ SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
- case WM_NOTIFYFORMAT:
- {
- if (IsWindowUnicode(hWnd))
- {
- return(NFR_UNICODE);
- }
- else
- {
- return(NFR_ANSI);
- }
- }
+ if ((CTLCOLOR_EDIT == ctlType) || (CTLCOLOR_LISTBOX == ctlType))
+ {
+ SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
+ }
+ else
+ {
+ SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
+ return GetSysColorBrush(COLOR_3DFACE);
+ }
- case WM_SETICON:
- {
- INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
- HICON hOldIcon = (HICON)GetClassLongW(hWnd, Index);
- SetClassLongW(hWnd, Index, lParam);
- SetWindowPos(hWnd, 0, 0, 0, 0, 0,
- SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
- SWP_NOACTIVATE | SWP_NOZORDER);
- return((LRESULT)hOldIcon);
- }
+ return GetSysColorBrush(COLOR_WINDOW);
+}
- case WM_GETICON:
- {
- INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
- return(GetClassLongW(hWnd, Index));
- }
- case WM_HELP:
- {
- if (bUnicode)
- {
- SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
- }
- else
- {
- SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
- }
- break;
- }
+LRESULT STDCALL
+User32DefWindowProc(HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ BOOL bUnicode)
+{
+ switch (Msg)
+ {
+ case WM_NCPAINT:
+ {
+ return (DefWndPaintNC(hWnd, (HRGN)wParam));
+ }
+
+ case WM_NCCALCSIZE:
+ {
+ return (DefWndNCCalcSize(hWnd, (RECT*)lParam));
+ }
+
+ case WM_WINDOWPOSCHANGING:
+ {
+ return (DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
+ }
+
+ case WM_WINDOWPOSCHANGED:
+ {
+ return (DefWndHandleWindowPosChanged(hWnd, (WINDOWPOS*)lParam));
+ }
+
+ case WM_NCHITTEST:
+ {
+ POINT Point;
+ Point.x = SLOWORD(lParam);
+ Point.y = SHIWORD(lParam);
+ return (DefWndHitTestNC(hWnd, Point));
+ }
+
+ case WM_NCLBUTTONDOWN:
+ {
+ return (DefWndHandleLButtonDownNC(hWnd, wParam, lParam));
+ }
+
+ case WM_NCLBUTTONUP:
+ {
+ return (DefWndHandleLButtonUpNC(hWnd, wParam, lParam));
+ }
+
+ case WM_LBUTTONDBLCLK:
+ case WM_NCLBUTTONDBLCLK:
+ {
+ return (DefWndHandleLButtonDblClkNC(hWnd, wParam, lParam));
+ }
+
+ case WM_NCRBUTTONDOWN:
+ {
+ if (wParam == HTCAPTION)
+ {
+ SetCapture(hWnd);
+ }
+ break;
+ }
+
+ case WM_RBUTTONUP:
+ {
+ POINT Pt;
+ if (hWnd == GetCapture())
+ {
+ ReleaseCapture();
+ }
+ Pt.x = SLOWORD(lParam);
+ Pt.y = SHIWORD(lParam);
+ ClientToScreen(hWnd, &Pt);
+ lParam = MAKELPARAM(Pt.x, Pt.y);
+ if (bUnicode)
+ {
+ SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
+ }
+ else
+ {
+ SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
+ }
+ break;
+ }
+
+ case WM_CONTEXTMENU:
+ {
+ if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
+ {
+ if (bUnicode)
+ {
+ SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
+ }
+ else
+ {
+ SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam);
+ }
+ }
+ else
+ {
+ LONG HitCode;
+ POINT Pt;
+
+ Pt.x = SLOWORD(lParam);
+ Pt.y = SHIWORD(lParam);
+ if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
+ {
+ ScreenToClient(GetParent(hWnd), &Pt);
+ }
+
+ HitCode = DefWndHitTestNC(hWnd, Pt);
+
+ if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
+ {
+ TrackPopupMenu(GetSystemMenu(hWnd, FALSE),
+ TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ Pt.x, Pt.y, 0, hWnd, NULL);
+ }
+ }
+ break;
+ }
+
+ case WM_NCACTIVATE:
+ {
+ return (DefWndHandleActiveNC(hWnd, wParam));
+ }
+
+ case WM_PRINT:
+ {
+ /* FIXME: Implement. */
+ return (0);
+ }
+
+ case WM_PAINTICON:
+ case WM_PAINT:
+ {
+ PAINTSTRUCT Ps;
+ HDC hDC = BeginPaint(hWnd, &Ps);
+ if (hDC)
+ {
+ HICON hIcon;
+ if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE &&
+ (hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON)) != NULL)
+ {
+ RECT WindowRect;
+ INT x, y;
+ GetWindowRect(hWnd, &WindowRect);
+ x = (WindowRect.right - WindowRect.left -
+ GetSystemMetrics(SM_CXICON)) / 2;
+ y = (WindowRect.bottom - WindowRect.top -
+ GetSystemMetrics(SM_CYICON)) / 2;
+ DrawIcon(hDC, x, y, hIcon);
+ }
+ if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_CLIENTEDGE)
+ {
+ RECT WindowRect;
+ GetClientRect(hWnd, &WindowRect);
+ DrawEdge(hDC, &WindowRect, EDGE_SUNKEN, BF_RECT);
+ }
+ EndPaint(hWnd, &Ps);
+ }
+ return (0);
+ }
+
+ case WM_SYNCPAINT:
+ {
+ HRGN hRgn;
+ hRgn = CreateRectRgn(0, 0, 0, 0);
+ if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
+ {
+ RedrawWindow(hWnd, NULL, hRgn,
+ RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
+ RDW_ALLCHILDREN);
+ }
+ DeleteObject(hRgn);
+ return (0);
+ }
+
+ case WM_SETREDRAW:
+ {
+ DefWndSetRedraw(hWnd, wParam);
+ return (0);
+ }
+
+ case WM_CLOSE:
+ {
+ DestroyWindow(hWnd);
+ return (0);
+ }
+
+ case WM_MOUSEACTIVATE:
+ {
+ if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
+ {
+ LONG Ret;
+ if (bUnicode)
+ {
+ Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
+ wParam, lParam);
+ }
+ else
+ {
+ Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
+ wParam, lParam);
+ }
+ if (Ret)
+ {
+ return (Ret);
+ }
+ }
+ return ((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
+ }
+
+ case WM_ACTIVATE:
+ {
+ /* Check if the window is minimized. */
+ if (LOWORD(lParam) != WA_INACTIVE &&
+ !(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
+ {
+ SetFocus(hWnd);
+ }
+ break;
+ }
+
+ case WM_MOUSEWHEEL:
+ {
+ if (GetWindowLongW(hWnd, GWL_STYLE & WS_CHILD))
+ {
+ if (bUnicode)
+ {
+ return (SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
+ wParam, lParam));
+ }
+ else
+ {
+ return (SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
+ wParam, lParam));
+ }
+ }
+ break;
+ }
+
+ case WM_ERASEBKGND:
+ case WM_ICONERASEBKGND:
+ {
+ RECT Rect;
+ HBRUSH hBrush = (HBRUSH)GetClassLongW(hWnd, GCL_HBRBACKGROUND);
+
+ if (NULL == hBrush)
+ {
+ return 0;
+ }
+ if (0 == (((DWORD) hBrush) & 0xffff0000))
+ {
+ hBrush = GetSysColorBrush((DWORD) hBrush - 1);
+ }
+ GetClipBox((HDC)wParam, &Rect);
+ FillRect((HDC)wParam, &Rect, hBrush);
+ return (1);
+ }
+
+ case WM_CTLCOLORMSGBOX:
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLORDLG:
+ case WM_CTLCOLORSTATIC:
+ case WM_CTLCOLORSCROLLBAR:
+ return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
+
+ case WM_SETCURSOR:
+ {
+ if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
+ {
+ if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
+ {
+ BOOL bResult;
+ if (bUnicode)
+ {
+ bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR,
+ wParam, lParam);
+ }
+ else
+ {
+ bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR,
+ wParam, lParam);
+ }
+ if (bResult)
+ {
+ return(TRUE);
+ }
+ }
+ }
+ return (DefWndHandleSetCursor(hWnd, wParam, lParam));
+ }
+
+ case WM_SYSCOMMAND:
+ {
+ POINT Pt;
+ Pt.x = SLOWORD(lParam);
+ Pt.y = SHIWORD(lParam);
+ return (DefWndHandleSysCommand(hWnd, wParam, Pt));
+ }
+
+ /* FIXME: Handle key messages. */
+/*
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ case WM_SYSCHAR:
+*/
+
+ /* FIXME: This is also incomplete. */
+ case WM_SYSKEYDOWN:
+ {
+ if (HIWORD(lParam) & KEYDATA_ALT)
+ {
+ if (wParam == VK_F4) /* Try to close the window */
+ {
+ HWND top = GetAncestor(hWnd, GA_ROOT);
+ if (!(GetClassLongW(top, GCL_STYLE) & CS_NOCLOSE))
+ {
+ if (bUnicode)
+ PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
+ else
+ PostMessageA(top, WM_SYSCOMMAND, SC_CLOSE, 0);
+ }
+ }
+ }
+ break;
+ }
+
+ case WM_SHOWWINDOW:
+ {
+ LONG Style;
+
+ if (!lParam)
+ return 0;
+ Style = GetWindowLongW(hWnd, GWL_STYLE);
+ if (!(Style & WS_POPUP))
+ return 0;
+ if ((Style & WS_VISIBLE) && wParam)
+ return 0;
+ if (!(Style & WS_VISIBLE) && !wParam)
+ return 0;
+ if (!GetWindow(hWnd, GW_OWNER))
+ return 0;
+ ShowWindow(hWnd, wParam ? SW_SHOWNA : SW_HIDE);
+ break;
+ }
+
+ case WM_CANCELMODE:
+ {
+ /* FIXME: Check for a desktop. */
+ if (GetCapture() == hWnd)
+ {
+ ReleaseCapture();
+ }
+ break;
+ }
+
+ case WM_VKEYTOITEM:
+ case WM_CHARTOITEM:
+ return (-1);
+
+ case WM_DROPOBJECT:
+ /* FIXME: Implement this. */
+ break;
+
+ case WM_QUERYDROPOBJECT:
+ {
+ if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
+ {
+ return(1);
+ }
+ break;
+ }
+
+ case WM_QUERYDRAGICON:
+ {
+ UINT Len;
+ HICON hIcon;
+
+ hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON);
+ if (hIcon)
+ {
+ return ((LRESULT)hIcon);
+ }
+ for (Len = 1; Len < 64; Len++)
+ {
+ if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
+ {
+ return((LRESULT)hIcon);
+ }
+ }
+ return ((LRESULT)LoadIconW(0, IDI_APPLICATION));
+ }
+
+ /* FIXME: WM_ISACTIVEICON */
+
+ case WM_NOTIFYFORMAT:
+ {
+ if (IsWindowUnicode(hWnd))
+ {
+ return(NFR_UNICODE);
+ }
+ else
+ {
+ return(NFR_ANSI);
+ }
+ }
+
+ case WM_SETICON:
+ {
+ INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
+ HICON hOldIcon = (HICON)GetClassLongW(hWnd, Index);
+ SetClassLongW(hWnd, Index, lParam);
+ SetWindowPos(hWnd, 0, 0, 0, 0, 0,
+ SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOACTIVATE | SWP_NOZORDER);
+ return ((LRESULT)hOldIcon);
+ }
+
+ case WM_GETICON:
+ {
+ INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
+ return (GetClassLongW(hWnd, Index));
+ }
+
+ case WM_HELP:
+ {
+ if (bUnicode)
+ {
+ SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
+ }
+ else
+ {
+ SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
+ }
+ break;
+ }
+
+ case WM_QUERYOPEN:
+ case WM_QUERYENDSESSION:
+ {
+ return (1);
+ }
}
- return 0;
+ return 0;
}
+
LRESULT STDCALL
DefWindowProcA(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
- LRESULT Result;
- static LPSTR WindowTextAtom = 0;
- PSTR WindowText;
+ static LPSTR WindowTextAtom = 0;
+ PSTR WindowText;
- switch (Msg)
+ switch (Msg)
{
- case WM_NCCREATE:
- {
- CREATESTRUCTA* Cs = (CREATESTRUCTA*)lParam;
- if (HIWORD(Cs->lpszName))
- {
- WindowTextAtom =
- (LPSTR)(ULONG)GlobalAddAtomA("USER32!WindowTextAtomA");
- WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
- strlen(Cs->lpszName) * sizeof(CHAR));
- strcpy(WindowText, Cs->lpszName);
- SetPropA(hWnd, WindowTextAtom, WindowText);
- }
- return(1);
- }
-
- case WM_NCCALCSIZE:
- {
- return(DefWndNCCalcSize(hWnd, (RECT*)lParam));
- }
-
- case WM_WINDOWPOSCHANGING:
- {
- return(DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
- }
-
- case WM_GETTEXTLENGTH:
- {
- if (WindowTextAtom == 0 ||
- (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
- {
- return(0);
- }
- return(strlen(WindowText));
- }
-
- case WM_GETTEXT:
- {
- if (WindowTextAtom == 0 ||
- (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
- {
- if (wParam > 1)
- {
- ((PSTR)lParam) = '\0';
- }
- return(0);
- }
- strncpy((LPSTR)lParam, WindowText, wParam);
- return(min(wParam, strlen(WindowText)));
- }
-
- case WM_SETTEXT:
- {
- if (WindowTextAtom != 0)
- {
- WindowTextAtom =
- (LPSTR)(DWORD)GlobalAddAtomA("USER32!WindowTextAtomW");
- }
- if (WindowTextAtom != 0 &&
- (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
- }
- WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
- strlen((PSTR)lParam) * sizeof(CHAR));
- strcpy(WindowText, (PSTR)lParam);
- SetPropA(hWnd, WindowTextAtom, WindowText);
- }
-
- case WM_NCDESTROY:
- {
- if (WindowTextAtom != 0 &&
- (WindowText = RemovePropA(hWnd, WindowTextAtom)) == NULL)
- {
- RtlFreeHeap(GetProcessHeap(), 0, WindowText);
- }
- if (WindowTextAtom != 0)
- {
- GlobalDeleteAtom((ATOM)(ULONG)WindowTextAtom);
- }
- /* FIXME: Destroy scroll bars here as well. */
- return(0);
- }
-
- default:
- Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
- break;
+ case WM_NCCREATE:
+ {
+ CREATESTRUCTA *Cs = (CREATESTRUCTA*)lParam;
+ if (HIWORD(Cs->lpszName))
+ {
+ if (0 == WindowTextAtom)
+ {
+ WindowTextAtom =
+ (LPSTR)(ULONG)GlobalAddAtomA("USER32!WindowTextAtomA");
+ }
+ WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+ strlen(Cs->lpszName) * sizeof(CHAR));
+ strcpy(WindowText, Cs->lpszName);
+ SetPropA(hWnd, WindowTextAtom, WindowText);
+ }
+ return (1);
+ }
+
+ case WM_GETTEXTLENGTH:
+ {
+ if (WindowTextAtom == 0 ||
+ (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
+ {
+ return(0);
+ }
+ return (strlen(WindowText));
+ }
+
+ case WM_GETTEXT:
+ {
+ if (WindowTextAtom == 0 ||
+ (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
+ {
+ if (wParam > 1)
+ {
+ *((PSTR)lParam) = '\0';
+ }
+ return (0);
+ }
+ strncpy((LPSTR)lParam, WindowText, wParam);
+ return (min(wParam, strlen(WindowText)));
+ }
+
+ case WM_SETTEXT:
+ {
+ if (0 == WindowTextAtom)
+ {
+ WindowTextAtom =
+ (LPSTR)(DWORD)GlobalAddAtomA("USER32!WindowTextAtomA");
+ }
+ if (WindowTextAtom != 0 &&
+ (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
+ }
+ WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+ (strlen((PSTR)lParam) + 1) * sizeof(CHAR));
+ strcpy(WindowText, (PSTR)lParam);
+ SetPropA(hWnd, WindowTextAtom, WindowText);
+ if (0 != (GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION))
+ {
+ DefWndPaintNC(hWnd, (HRGN) 1);
+ }
+ return (1);
+ }
+
+/*
+ FIXME: Implement these.
+ case WM_IME_CHAR:
+ case WM_IME_KEYDOWN:
+ case WM_IME_KEYUP:
+ case WM_IME_STARTCOMPOSITION:
+ case WM_IME_COMPOSITION:
+ case WM_IME_ENDCOMPOSITION:
+ case WM_IME_SELECT:
+ case WM_IME_SETCONTEXT:
+*/
+
+ case WM_NCDESTROY:
+ {
+ if (WindowTextAtom != 0 &&
+ (WindowText = RemovePropA(hWnd, WindowTextAtom)) == NULL)
+ {
+ RtlFreeHeap(GetProcessHeap(), 0, WindowText);
+ }
+ return(0);
+ }
}
- return(Result);
+ return User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
}
+
LRESULT STDCALL
DefWindowProcW(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
- LRESULT Result;
- static LPWSTR WindowTextAtom = 0;
- PWSTR WindowText;
+ static LPWSTR WindowTextAtom = 0;
+ PWSTR WindowText;
- switch (Msg)
+ switch (Msg)
{
- case WM_NCCREATE:
- {
- CREATESTRUCTW* Cs = (CREATESTRUCTW*)lParam;
- if (HIWORD(Cs->lpszName))
- {
- WindowTextAtom =
- (LPWSTR)(DWORD)GlobalAddAtomW(L"USER32!WindowTextAtomW");
- WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
- wcslen(Cs->lpszName) * sizeof(WCHAR));
- wcscpy(WindowText, Cs->lpszName);
- SetPropW(hWnd, WindowTextAtom, WindowText);
- }
- return(1);
- }
-
- case WM_NCCALCSIZE:
- {
- return(DefWndNCCalcSize(hWnd, (RECT*)lParam));
- }
-
- case WM_WINDOWPOSCHANGING:
- {
- return(DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
- }
-
- case WM_GETTEXTLENGTH:
- {
- if (WindowTextAtom == 0 ||
- (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
- {
- return(0);
- }
- return(wcslen(WindowText));
- }
-
- case WM_GETTEXT:
- {
- if (WindowTextAtom == 0 ||
- (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
- {
- if (wParam > 1)
- {
- ((PWSTR)lParam) = '\0';
- }
- return(0);
- }
- wcsncpy((PWSTR)lParam, WindowText, wParam);
- return(min(wParam, wcslen(WindowText)));
- }
-
- case WM_SETTEXT:
- {
- if (WindowTextAtom != 0)
- {
- WindowTextAtom =
- (LPWSTR)(DWORD)GlobalAddAtom(L"USER32!WindowTextAtomW");
- }
- if (WindowTextAtom != 0 &&
- (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
- }
- WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
- wcslen((PWSTR)lParam) * sizeof(WCHAR));
- wcscpy(WindowText, (PWSTR)lParam);
- SetPropW(hWnd, WindowTextAtom, WindowText);
- }
-
- case WM_NCDESTROY:
- {
- if (WindowTextAtom != 0 &&
- (WindowText = RemovePropW(hWnd, WindowTextAtom)) == NULL)
- {
- RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
- }
- if (WindowTextAtom != 0)
- {
- GlobalDeleteAtom((ATOM)(DWORD)WindowTextAtom);
- }
- /* FIXME: Destroy scroll bars here as well. */
- return(0);
- }
-
- default:
- Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
- break;
+ case WM_NCCREATE:
+ {
+ CREATESTRUCTW* CreateStruct = (CREATESTRUCTW*)lParam;
+ if (HIWORD(CreateStruct->lpszName))
+ {
+ if (0 == WindowTextAtom)
+ {
+ WindowTextAtom =
+ (LPWSTR)(DWORD)GlobalAddAtomW(L"USER32!WindowTextAtomW");
+ }
+ WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+ wcslen(CreateStruct->lpszName) * sizeof(WCHAR));
+ wcscpy(WindowText, CreateStruct->lpszName);
+ SetPropW(hWnd, WindowTextAtom, WindowText);
+ }
+ return (1);
+ }
+
+ case WM_GETTEXTLENGTH:
+ {
+ if (WindowTextAtom == 0 ||
+ (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
+ {
+ return(0);
+ }
+ return (wcslen(WindowText));
+ }
+
+ case WM_GETTEXT:
+ {
+ if (WindowTextAtom == 0 ||
+ (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
+ {
+ if (wParam > 1)
+ {
+ ((PWSTR)lParam) = '\0';
+ }
+ return (0);
+ }
+ wcsncpy((PWSTR)lParam, WindowText, wParam);
+ return (min(wParam, wcslen(WindowText)));
+ }
+
+ case WM_SETTEXT:
+ {
+ if (WindowTextAtom == 0)
+ {
+ WindowTextAtom =
+ (LPWSTR)(DWORD)GlobalAddAtomW(L"USER32!WindowTextAtomW");
+ }
+ if (WindowTextAtom != 0 &&
+ (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
+ }
+ WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+ (wcslen((PWSTR)lParam) + 1) * sizeof(WCHAR));
+ wcscpy(WindowText, (PWSTR)lParam);
+ SetPropW(hWnd, WindowTextAtom, WindowText);
+ if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
+ {
+ DefWndPaintNC(hWnd, (HRGN)1);
+ }
+ return (1);
+ }
+
+ case WM_IME_CHAR:
+ {
+ SendMessageW(hWnd, WM_CHAR, wParam, lParam);
+ return (0);
+ }
+
+ case WM_IME_SETCONTEXT:
+ {
+ /* FIXME */
+ return (0);
+ }
+
+ case WM_NCDESTROY:
+ {
+ if (WindowTextAtom != 0 &&
+ (WindowText = RemovePropW(hWnd, WindowTextAtom)) == NULL)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
+ }
+ return (0);
+ }
}
- return(Result);
+ return User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
}