mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 13:45:50 +00:00
[UXTHEME] -Implement support for non rectangular caption buttons in WM_NCHITTEST handling. Please note that non rectangular buttons or buttons with no gaps between them are HACKY for XP so hittesting will never work properly (we really mimic windows xp here). Cache the position of caption buttons in the WINDOWINFO. CORE-13171
svn path=/trunk/; revision=74960
This commit is contained in:
parent
30ad304570
commit
438d60c401
3 changed files with 118 additions and 67 deletions
|
@ -222,15 +222,88 @@ ThemeEndBufferedPaint(PDRAW_CONTEXT pcontext, int x, int y, int cx, int cy)
|
||||||
pcontext->hDC = pcontext->hDCScreen;
|
pcontext->hDC = pcontext->hDCScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThemeCalculateCaptionButtonsPos(HWND hWnd, HTHEME htheme)
|
||||||
|
{
|
||||||
|
PWND_DATA pwndData;
|
||||||
|
DWORD style;
|
||||||
|
INT ButtonWidth, ButtonHeight, iPartId, i;
|
||||||
|
WINDOWINFO wi = {sizeof(wi)};
|
||||||
|
RECT rcCurrent;
|
||||||
|
|
||||||
|
/* First of all check if we have something to do here */
|
||||||
|
style = GetWindowLongW(hWnd, GWL_STYLE);
|
||||||
|
if((style & (WS_CAPTION | WS_SYSMENU)) != (WS_CAPTION | WS_SYSMENU))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Get theme data for this window */
|
||||||
|
pwndData = ThemeGetWndData(hWnd);
|
||||||
|
if (pwndData == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!htheme)
|
||||||
|
htheme = pwndData->hthemeWindow;
|
||||||
|
|
||||||
|
if(!GetWindowInfo(hWnd, &wi))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Calculate the area of the caption */
|
||||||
|
rcCurrent.top = rcCurrent.left = 0;
|
||||||
|
rcCurrent.right = wi.rcWindow.right - wi.rcWindow.left;
|
||||||
|
rcCurrent.bottom = wi.rcWindow.bottom - wi.rcWindow.top;
|
||||||
|
|
||||||
|
/* Add a padding around the objects of the caption */
|
||||||
|
InflateRect(&rcCurrent, -(int)wi.cyWindowBorders-BUTTON_GAP_SIZE,
|
||||||
|
-(int)wi.cyWindowBorders-BUTTON_GAP_SIZE);
|
||||||
|
|
||||||
|
for (i = CLOSEBUTTON; i <= HELPBUTTON; i++)
|
||||||
|
{
|
||||||
|
SIZE ButtonSize;
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case CLOSEBUTTON:
|
||||||
|
iPartId = wi.dwExStyle & WS_EX_TOOLWINDOW ? WP_SMALLCLOSEBUTTON : WP_CLOSEBUTTON;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAXBUTTON:
|
||||||
|
iPartId = wi.dwStyle & WS_MAXIMIZE ? WP_RESTOREBUTTON : WP_MAXBUTTON;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MINBUTTON:
|
||||||
|
iPartId = wi.dwStyle & WS_MINIMIZE ? WP_RESTOREBUTTON : WP_MINBUTTON;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
iPartId = WP_HELPBUTTON ;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetThemePartSize(htheme, NULL, iPartId, 0, NULL, TS_MIN, &ButtonSize);
|
||||||
|
|
||||||
|
ButtonHeight = GetSystemMetrics( wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMSIZE : SM_CYSIZE);
|
||||||
|
ButtonWidth = MulDiv(ButtonSize.cx, ButtonHeight, ButtonSize.cy);
|
||||||
|
|
||||||
|
ButtonHeight -= 4;
|
||||||
|
ButtonWidth -= 4;
|
||||||
|
|
||||||
|
SetRect(&pwndData->rcCaptionButtons[i],
|
||||||
|
rcCurrent.right - ButtonWidth,
|
||||||
|
rcCurrent.top,
|
||||||
|
rcCurrent.right,
|
||||||
|
rcCurrent.top + ButtonHeight);
|
||||||
|
|
||||||
|
rcCurrent.right -= ButtonWidth + BUTTON_GAP_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ThemeDrawCaptionButton(PDRAW_CONTEXT pcontext,
|
ThemeDrawCaptionButton(PDRAW_CONTEXT pcontext,
|
||||||
RECT* prcCurrent,
|
|
||||||
CAPTIONBUTTON buttonId,
|
CAPTIONBUTTON buttonId,
|
||||||
INT iStateId)
|
INT iStateId)
|
||||||
{
|
{
|
||||||
RECT rcPart;
|
INT iPartId;
|
||||||
INT ButtonWidth, ButtonHeight, iPartId;
|
PWND_DATA pwndData = ThemeGetWndData(pcontext->hWnd);
|
||||||
SIZE ButtonSize;
|
if (!pwndData)
|
||||||
|
return;
|
||||||
|
|
||||||
switch(buttonId)
|
switch(buttonId)
|
||||||
{
|
{
|
||||||
|
@ -267,22 +340,7 @@ ThemeDrawCaptionButton(PDRAW_CONTEXT pcontext,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetThemePartSize(pcontext->theme, pcontext->hDC, iPartId, 0, NULL, TS_MIN, &ButtonSize);
|
DrawThemeBackground(pcontext->theme, pcontext->hDC, iPartId, iStateId, &pwndData->rcCaptionButtons[buttonId], NULL);
|
||||||
|
|
||||||
ButtonHeight = GetSystemMetrics( pcontext->wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMSIZE : SM_CYSIZE);
|
|
||||||
ButtonWidth = MulDiv(ButtonSize.cx, ButtonHeight, ButtonSize.cy);
|
|
||||||
|
|
||||||
ButtonHeight -= 4;
|
|
||||||
ButtonWidth -= 4;
|
|
||||||
|
|
||||||
/* Calculate the position */
|
|
||||||
rcPart.top = prcCurrent->top;
|
|
||||||
rcPart.right = prcCurrent->right;
|
|
||||||
rcPart.bottom = rcPart.top + ButtonHeight ;
|
|
||||||
rcPart.left = rcPart.right - ButtonWidth ;
|
|
||||||
prcCurrent->right -= ButtonWidth + BUTTON_GAP_SIZE;
|
|
||||||
|
|
||||||
DrawThemeBackground(pcontext->theme, pcontext->hDC, iPartId, iStateId, &rcPart, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD
|
static DWORD
|
||||||
|
@ -302,25 +360,14 @@ ThemeGetButtonState(DWORD htCurrect, DWORD htHot, DWORD htDown, BOOL Active)
|
||||||
static void
|
static void
|
||||||
ThemeDrawCaptionButtons(PDRAW_CONTEXT pcontext, DWORD htHot, DWORD htDown)
|
ThemeDrawCaptionButtons(PDRAW_CONTEXT pcontext, DWORD htHot, DWORD htDown)
|
||||||
{
|
{
|
||||||
RECT rcCurrent;
|
|
||||||
|
|
||||||
/* Calculate the area of the caption */
|
|
||||||
rcCurrent.top = rcCurrent.left = 0;
|
|
||||||
rcCurrent.right = pcontext->wi.rcWindow.right - pcontext->wi.rcWindow.left;
|
|
||||||
rcCurrent.bottom = pcontext->CaptionHeight;
|
|
||||||
|
|
||||||
/* Add a padding around the objects of the caption */
|
|
||||||
InflateRect(&rcCurrent, -(int)pcontext->wi.cyWindowBorders-BUTTON_GAP_SIZE,
|
|
||||||
-(int)pcontext->wi.cyWindowBorders-BUTTON_GAP_SIZE);
|
|
||||||
|
|
||||||
/* Draw the buttons */
|
/* Draw the buttons */
|
||||||
ThemeDrawCaptionButton(pcontext, &rcCurrent, CLOSEBUTTON,
|
ThemeDrawCaptionButton(pcontext, CLOSEBUTTON,
|
||||||
ThemeGetButtonState(HTCLOSE, htHot, htDown, pcontext->Active));
|
ThemeGetButtonState(HTCLOSE, htHot, htDown, pcontext->Active));
|
||||||
ThemeDrawCaptionButton(pcontext, &rcCurrent, MAXBUTTON,
|
ThemeDrawCaptionButton(pcontext, MAXBUTTON,
|
||||||
ThemeGetButtonState(HTMAXBUTTON, htHot, htDown, pcontext->Active));
|
ThemeGetButtonState(HTMAXBUTTON, htHot, htDown, pcontext->Active));
|
||||||
ThemeDrawCaptionButton(pcontext, &rcCurrent, MINBUTTON,
|
ThemeDrawCaptionButton(pcontext, MINBUTTON,
|
||||||
ThemeGetButtonState(HTMINBUTTON, htHot, htDown, pcontext->Active));
|
ThemeGetButtonState(HTMINBUTTON, htHot, htDown, pcontext->Active));
|
||||||
ThemeDrawCaptionButton(pcontext, &rcCurrent, HELPBUTTON,
|
ThemeDrawCaptionButton(pcontext, HELPBUTTON,
|
||||||
ThemeGetButtonState(HTHELP, htHot, htDown, pcontext->Active));
|
ThemeGetButtonState(HTHELP, htHot, htDown, pcontext->Active));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,10 +413,10 @@ ThemeDrawCaption(PDRAW_CONTEXT pcontext, RECT* prcCurrent)
|
||||||
{
|
{
|
||||||
iState = pcontext->Active ? BUTTON_NORMAL : BUTTON_INACTIVE;
|
iState = pcontext->Active ? BUTTON_NORMAL : BUTTON_INACTIVE;
|
||||||
|
|
||||||
ThemeDrawCaptionButton(pcontext, &rcPart, CLOSEBUTTON, iState);
|
ThemeDrawCaptionButton(pcontext, CLOSEBUTTON, iState);
|
||||||
ThemeDrawCaptionButton(pcontext, &rcPart, MAXBUTTON, iState);
|
ThemeDrawCaptionButton(pcontext, MAXBUTTON, iState);
|
||||||
ThemeDrawCaptionButton(pcontext, &rcPart, MINBUTTON, iState);
|
ThemeDrawCaptionButton(pcontext, MINBUTTON, iState);
|
||||||
ThemeDrawCaptionButton(pcontext, &rcPart, HELPBUTTON, iState);
|
ThemeDrawCaptionButton(pcontext, HELPBUTTON, iState);
|
||||||
}
|
}
|
||||||
|
|
||||||
rcPart.top += 3 ;
|
rcPart.top += 3 ;
|
||||||
|
@ -851,23 +898,11 @@ DefWndNCHitTest(HWND hWnd, POINT Point)
|
||||||
|
|
||||||
if (!PtInRect(&WindowRect, Point))
|
if (!PtInRect(&WindowRect, Point))
|
||||||
{
|
{
|
||||||
INT ButtonWidth;
|
|
||||||
|
|
||||||
if (wi.dwExStyle & WS_EX_TOOLWINDOW)
|
|
||||||
ButtonWidth = GetSystemMetrics(SM_CXSMSIZE);
|
|
||||||
else
|
|
||||||
ButtonWidth = GetSystemMetrics(SM_CXSIZE);
|
|
||||||
|
|
||||||
ButtonWidth -= 4;
|
|
||||||
ButtonWidth += BUTTON_GAP_SIZE;
|
|
||||||
|
|
||||||
if (wi.dwStyle & WS_SYSMENU)
|
if (wi.dwStyle & WS_SYSMENU)
|
||||||
{
|
{
|
||||||
if (wi.dwExStyle & WS_EX_TOOLWINDOW)
|
PWND_DATA pwndData = ThemeGetWndData(hWnd);
|
||||||
{
|
|
||||||
WindowRect.right -= ButtonWidth;
|
if (!(wi.dwExStyle & WS_EX_TOOLWINDOW))
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// if(!(wi.dwExStyle & WS_EX_DLGMODALFRAME))
|
// if(!(wi.dwExStyle & WS_EX_DLGMODALFRAME))
|
||||||
// FIXME: The real test should check whether there is
|
// FIXME: The real test should check whether there is
|
||||||
|
@ -876,22 +911,22 @@ DefWndNCHitTest(HWND hWnd, POINT Point)
|
||||||
// See win32ss/user/user32/windows/nonclient.c!DefWndNCHitTest
|
// See win32ss/user/user32/windows/nonclient.c!DefWndNCHitTest
|
||||||
// and win32ss/user/ntuser/nonclient.c!GetNCHitEx which does
|
// and win32ss/user/ntuser/nonclient.c!GetNCHitEx which does
|
||||||
// the test better.
|
// the test better.
|
||||||
WindowRect.left += ButtonWidth;
|
WindowRect.left += GetSystemMetrics(SM_CXSMICON);
|
||||||
WindowRect.right -= ButtonWidth;
|
}
|
||||||
|
|
||||||
|
if (pwndData)
|
||||||
|
{
|
||||||
|
POINT pt = {Point.x - wi.rcWindow.left, Point.y - wi.rcWindow.top};
|
||||||
|
if (PtInRect(&pwndData->rcCaptionButtons[CLOSEBUTTON], pt))
|
||||||
|
return HTCLOSE;
|
||||||
|
if (PtInRect(&pwndData->rcCaptionButtons[MAXBUTTON], pt))
|
||||||
|
return HTMAXBUTTON;
|
||||||
|
if (PtInRect(&pwndData->rcCaptionButtons[MINBUTTON], pt))
|
||||||
|
return HTMINBUTTON;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Point.x < WindowRect.left)
|
if (Point.x < WindowRect.left)
|
||||||
return HTSYSMENU;
|
return HTSYSMENU;
|
||||||
if (WindowRect.right <= Point.x)
|
|
||||||
return HTCLOSE;
|
|
||||||
if (wi.dwStyle & WS_MAXIMIZEBOX || wi.dwStyle & WS_MINIMIZEBOX)
|
|
||||||
WindowRect.right -= ButtonWidth;
|
|
||||||
if (Point.x >= WindowRect.right)
|
|
||||||
return HTMAXBUTTON;
|
|
||||||
if (wi.dwStyle & WS_MINIMIZEBOX)
|
|
||||||
WindowRect.right -= ButtonWidth;
|
|
||||||
if (Point.x >= WindowRect.right)
|
|
||||||
return HTMINBUTTON;
|
|
||||||
return HTCAPTION;
|
return HTCAPTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1111,8 +1146,12 @@ HRESULT WINAPI DrawNCPreview(HDC hDC,
|
||||||
|
|
||||||
/* Paint the window on the preview hDC */
|
/* Paint the window on the preview hDC */
|
||||||
rcCurrent = context.wi.rcWindow;
|
rcCurrent = context.wi.rcWindow;
|
||||||
|
OffsetRect( &rcCurrent, -context.wi.rcWindow.left, -context.wi.rcWindow.top);
|
||||||
|
SetViewportOrgEx(hDC, context.wi.rcWindow.left, context.wi.rcWindow.top, NULL);
|
||||||
|
ThemeCalculateCaptionButtonsPos(hwndDummy, context.theme);
|
||||||
ThemePaintWindow(&context, &rcCurrent, FALSE);
|
ThemePaintWindow(&context, &rcCurrent, FALSE);
|
||||||
|
SetViewportOrgEx(hDC, 0, 0, NULL);
|
||||||
|
|
||||||
context.hDC = NULL;
|
context.hDC = NULL;
|
||||||
CloseThemeData (context.theme);
|
CloseThemeData (context.theme);
|
||||||
CloseThemeData (context.scrolltheme);
|
CloseThemeData (context.scrolltheme);
|
||||||
|
|
|
@ -286,6 +286,14 @@ ThemePreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR
|
||||||
{
|
{
|
||||||
switch(Msg)
|
switch(Msg)
|
||||||
{
|
{
|
||||||
|
case WM_CREATE:
|
||||||
|
case WM_STYLECHANGED:
|
||||||
|
case WM_SIZE:
|
||||||
|
case WM_WINDOWPOSCHANGED:
|
||||||
|
{
|
||||||
|
ThemeCalculateCaptionButtonsPos(hWnd, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case WM_THEMECHANGED:
|
case WM_THEMECHANGED:
|
||||||
{
|
{
|
||||||
PWND_DATA pwndData = ThemeGetWndData(hWnd);
|
PWND_DATA pwndData = ThemeGetWndData(hWnd);
|
||||||
|
@ -319,6 +327,8 @@ ThemePreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR
|
||||||
CloseThemeData(pwndData->hthemeScrollbar);
|
CloseThemeData(pwndData->hthemeScrollbar);
|
||||||
pwndData->hthemeScrollbar = NULL;
|
pwndData->hthemeScrollbar = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThemeCalculateCaptionButtonsPos(hWnd, NULL);
|
||||||
}
|
}
|
||||||
case WM_NCCREATE:
|
case WM_NCCREATE:
|
||||||
{
|
{
|
||||||
|
|
|
@ -151,6 +151,7 @@ typedef struct _WND_DATA
|
||||||
HTHEME hthemeWindow;
|
HTHEME hthemeWindow;
|
||||||
HTHEME hthemeScrollbar;
|
HTHEME hthemeScrollbar;
|
||||||
|
|
||||||
|
RECT rcCaptionButtons[4];
|
||||||
UINT lastHitTest;
|
UINT lastHitTest;
|
||||||
BOOL HasAppDefinedRgn;
|
BOOL HasAppDefinedRgn;
|
||||||
BOOL HasThemeRgn;
|
BOOL HasThemeRgn;
|
||||||
|
@ -239,6 +240,7 @@ typedef enum {
|
||||||
#define SCROLL_MIN_RECT 4
|
#define SCROLL_MIN_RECT 4
|
||||||
|
|
||||||
LRESULT CALLBACK ThemeWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, WNDPROC DefWndProc);
|
LRESULT CALLBACK ThemeWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, WNDPROC DefWndProc);
|
||||||
|
void ThemeCalculateCaptionButtonsPos(HWND hWnd, HTHEME htheme);
|
||||||
void ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT Bar, POINT* pt);
|
void ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT Bar, POINT* pt);
|
||||||
VOID NC_TrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt);
|
VOID NC_TrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt);
|
||||||
void ThemeInitDrawContext(PDRAW_CONTEXT pcontext, HWND hWnd, HRGN hRgn);
|
void ThemeInitDrawContext(PDRAW_CONTEXT pcontext, HWND hWnd, HRGN hRgn);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue