return hIcon;
}
-WCHAR *UserGetWindowCaption(HWND hwnd)
-{
- INT len = 512;
- WCHAR *text;
- text = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
- if (text) InternalGetWindowText(hwnd, text, len);
- return text;
-}
-
-HRESULT WINAPI ThemeDrawCaptionText(PDRAW_CONTEXT pcontext, RECT* pRect, int iPartId, int iStateId, LPCWSTR pszText)
+HRESULT WINAPI ThemeDrawCaptionText(PDRAW_CONTEXT pcontext, RECT* pRect, int iPartId, int iStateId)
{
HRESULT hr;
HFONT hFont = NULL;
LOGFONTW logfont;
COLORREF textColor;
COLORREF oldTextColor;
+ int align = CA_LEFT;
+ int drawStyles = DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS;
+
+ WCHAR buffer[50];
+ WCHAR *pszText = buffer;
+ INT len;
+
+ len = InternalGetWindowText(pcontext->hWnd, NULL, 0);
+ if (!len)
+ return S_OK;
+
+ len++; /* From now on this is the size of the buffer so include the null */
+
+ if (len > ARRAYSIZE(buffer))
+ {
+ pszText = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!pszText)
+ return E_OUTOFMEMORY;
+ }
+
+ InternalGetWindowText(pcontext->hWnd, pszText, len);
hr = GetThemeSysFont(0,TMT_CAPTIONFONT,&logfont);
if(SUCCEEDED(hr))
else
textColor = GetSysColor(COLOR_CAPTIONTEXT);
+ GetThemeEnumValue(pcontext->theme, iPartId, iStateId, TMT_CONTENTALIGNMENT, &align);
+ if (align == CA_CENTER)
+ drawStyles |= DT_CENTER;
+ else if (align == CA_RIGHT)
+ drawStyles |= DT_RIGHT;
+
oldTextColor = SetTextColor(pcontext->hDC, textColor);
DrawThemeText(pcontext->theme,
pcontext->hDC,
iPartId,
iStateId,
pszText,
- lstrlenW(pszText),
- DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS,
+ len - 1,
+ drawStyles,
0,
pRect);
SetTextColor(pcontext->hDC, oldTextColor);
- if(hFont)
+ if (hFont)
{
SelectObject(pcontext->hDC, oldFont);
DeleteObject(hFont);
}
+ if (pszText != buffer)
+ {
+ HeapFree(GetProcessHeap(), 0, pszText);
+ }
return S_OK;
}
GetWindowInfo(hWnd, &pcontext->wi);
pcontext->hWnd = hWnd;
pcontext->Active = IsWindowActive(hWnd, pcontext->wi.dwExStyle);
- pcontext->theme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"WINDOW");
- pcontext->scrolltheme = MSSTYLES_OpenThemeClass(ActiveThemeFile, NULL, L"SCROLLBAR");
+ pcontext->theme = GetNCCaptionTheme(hWnd, pcontext->wi.dwStyle);
+ pcontext->scrolltheme = GetNCScrollbarTheme(hWnd, pcontext->wi.dwStyle);
pcontext->CaptionHeight = pcontext->wi.cyWindowBorders;
pcontext->CaptionHeight += GetSystemMetrics(pcontext->wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION );
{
ReleaseDC(pcontext->hWnd ,pcontext->hDC);
- CloseThemeData (pcontext->theme);
- CloseThemeData (pcontext->scrolltheme);
-
if(pcontext->hRgn != NULL)
{
DeleteObject(pcontext->hRgn);
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
ThemeDrawCaptionButton(PDRAW_CONTEXT pcontext,
- RECT* prcCurrent,
CAPTIONBUTTON buttonId,
INT iStateId)
{
- RECT rcPart;
- INT ButtonWidth, ButtonHeight, iPartId;
- SIZE ButtonSize;
+ INT iPartId;
+ PWND_DATA pwndData = ThemeGetWndData(pcontext->hWnd);
+ if (!pwndData)
+ return;
switch(buttonId)
{
return;
}
- GetThemePartSize(pcontext->theme, pcontext->hDC, iPartId, 0, NULL, TS_MIN, &ButtonSize);
-
- 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);
+ DrawThemeBackground(pcontext->theme, pcontext->hDC, iPartId, iStateId, &pwndData->rcCaptionButtons[buttonId], NULL);
}
static DWORD
static void
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 */
- ThemeDrawCaptionButton(pcontext, &rcCurrent, CLOSEBUTTON,
+ ThemeDrawCaptionButton(pcontext, CLOSEBUTTON,
ThemeGetButtonState(HTCLOSE, htHot, htDown, pcontext->Active));
- ThemeDrawCaptionButton(pcontext, &rcCurrent, MAXBUTTON,
+ ThemeDrawCaptionButton(pcontext, MAXBUTTON,
ThemeGetButtonState(HTMAXBUTTON, htHot, htDown, pcontext->Active));
- ThemeDrawCaptionButton(pcontext, &rcCurrent, MINBUTTON,
+ ThemeDrawCaptionButton(pcontext, MINBUTTON,
ThemeGetButtonState(HTMINBUTTON, htHot, htDown, pcontext->Active));
- ThemeDrawCaptionButton(pcontext, &rcCurrent, HELPBUTTON,
+ ThemeDrawCaptionButton(pcontext, HELPBUTTON,
ThemeGetButtonState(HTHELP, htHot, htDown, pcontext->Active));
}
RECT rcPart;
int iPart, iState;
HICON hIcon;
- WCHAR *CaptionText;
// See also win32ss/user/ntuser/nonclient.c!UserDrawCaptionBar
// and win32ss/user/ntuser/nonclient.c!UserDrawCaption
else
hIcon = NULL;
- CaptionText = UserGetWindowCaption(pcontext->hWnd);
-
/* Get the caption part and state id */
if (pcontext->wi.dwStyle & WS_MINIMIZE)
iPart = WP_MINCAPTION;
{
iState = pcontext->Active ? BUTTON_NORMAL : BUTTON_INACTIVE;
- ThemeDrawCaptionButton(pcontext, &rcPart, CLOSEBUTTON, iState);
- ThemeDrawCaptionButton(pcontext, &rcPart, MAXBUTTON, iState);
- ThemeDrawCaptionButton(pcontext, &rcPart, MINBUTTON, iState);
- ThemeDrawCaptionButton(pcontext, &rcPart, HELPBUTTON, iState);
+ ThemeDrawCaptionButton(pcontext, CLOSEBUTTON, iState);
+ ThemeDrawCaptionButton(pcontext, MAXBUTTON, iState);
+ ThemeDrawCaptionButton(pcontext, MINBUTTON, iState);
+ ThemeDrawCaptionButton(pcontext, HELPBUTTON, iState);
}
rcPart.top += 3 ;
rcPart.right -= 4;
/* Draw the caption */
- if (CaptionText)
- {
- ThemeDrawCaptionText(pcontext, &rcPart, iPart, iState, CaptionText);
- HeapFree(GetProcessHeap(), 0, CaptionText);
- }
+ ThemeDrawCaptionText(pcontext, &rcPart, iPart, iState);
}
static void
DRAW_CONTEXT context;
TRACKMOUSEEVENT tme;
DWORD style;
- PWND_CONTEXT pcontext;
+ PWND_DATA pwndData;
/* First of all check if we have something to do here */
style = GetWindowLongW(hWnd, GWL_STYLE);
return 0;
/* Get theme data for this window */
- pcontext = ThemeGetWndContext(hWnd);
- if (pcontext == NULL)
+ pwndData = ThemeGetWndData(hWnd);
+ if (pwndData == NULL)
return 0;
/* Begin tracking in the non client area if we are not tracking yet */
ThemeInitDrawContext(&context, hWnd, 0);
if (context.wi.dwStyle & WS_SYSMENU)
{
- if (HT_ISBUTTON(ht) || HT_ISBUTTON(pcontext->lastHitTest))
+ if (HT_ISBUTTON(ht) || HT_ISBUTTON(pwndData->lastHitTest))
ThemeDrawCaptionButtons(&context, ht, 0);
}
if (context.wi.dwStyle & WS_HSCROLL)
{
- if (ht == HTHSCROLL || pcontext->lastHitTest == HTHSCROLL)
+ if (ht == HTHSCROLL || pwndData->lastHitTest == HTHSCROLL)
ThemeDrawScrollBar(&context, SB_HORZ , ht == HTHSCROLL ? pt : NULL);
}
if (context.wi.dwStyle & WS_VSCROLL)
{
- if (ht == HTVSCROLL || pcontext->lastHitTest == HTVSCROLL)
+ if (ht == HTVSCROLL || pwndData->lastHitTest == HTVSCROLL)
ThemeDrawScrollBar(&context, SB_VERT, ht == HTVSCROLL ? pt : NULL);
}
ThemeCleanupDrawContext(&context);
- pcontext->lastHitTest = ht;
+ pwndData->lastHitTest = ht;
return 0;
}
{
DRAW_CONTEXT context;
DWORD style;
- PWND_CONTEXT pWndContext;
+ PWND_DATA pwndData;
/* First of all check if we have something to do here */
style = GetWindowLongW(hWnd, GWL_STYLE);
return 0;
/* Get theme data for this window */
- pWndContext = ThemeGetWndContext(hWnd);
- if (pWndContext == NULL)
+ pwndData = ThemeGetWndData(hWnd);
+ if (pwndData == NULL)
return 0;
ThemeInitDrawContext(&context, hWnd, 0);
- if (context.wi.dwStyle & WS_SYSMENU && HT_ISBUTTON(pWndContext->lastHitTest))
+ if (context.wi.dwStyle & WS_SYSMENU && HT_ISBUTTON(pwndData->lastHitTest))
ThemeDrawCaptionButtons(&context, 0, 0);
- if (context.wi.dwStyle & WS_HSCROLL && pWndContext->lastHitTest == HTHSCROLL)
+ if (context.wi.dwStyle & WS_HSCROLL && pwndData->lastHitTest == HTHSCROLL)
ThemeDrawScrollBar(&context, SB_HORZ, NULL);
- if (context.wi.dwStyle & WS_VSCROLL && pWndContext->lastHitTest == HTVSCROLL)
+ if (context.wi.dwStyle & WS_VSCROLL && pwndData->lastHitTest == HTVSCROLL)
ThemeDrawScrollBar(&context, SB_VERT, NULL);
ThemeCleanupDrawContext(&context);
- pWndContext->lastHitTest = HTNOWHERE;
+ pwndData->lastHitTest = HTNOWHERE;
return 0;
}
WPARAM SCMsg, ht;
ULONG Style;
DRAW_CONTEXT context;
- PWND_CONTEXT pWndContext;
+ PWND_DATA pwndData;
Style = GetWindowLongW(hWnd, GWL_STYLE);
if (!((Style & WS_CAPTION) && (Style & WS_SYSMENU)))
}
/* Get theme data for this window */
- pWndContext = ThemeGetWndContext(hWnd);
- if (pWndContext == NULL)
+ pwndData = ThemeGetWndData(hWnd);
+ if (pwndData == NULL)
return;
ThemeInitDrawContext(&context, hWnd, 0);
ThemeDrawCaptionButtons(&context, 0, wParam);
- pWndContext->lastHitTest = wParam;
+ pwndData->lastHitTest = wParam;
SetCapture(hWnd);
Pressed = (ht == wParam);
/* Only draw the buttons if the hit test changed */
- if (ht != pWndContext->lastHitTest &&
- (HT_ISBUTTON(ht) || HT_ISBUTTON(pWndContext->lastHitTest)))
+ if (ht != pwndData->lastHitTest &&
+ (HT_ISBUTTON(ht) || HT_ISBUTTON(pwndData->lastHitTest)))
{
ThemeDrawCaptionButtons(&context, 0, Pressed ? wParam: 0);
- pWndContext->lastHitTest = ht;
+ pwndData->lastHitTest = ht;
}
}
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.dwExStyle & WS_EX_TOOLWINDOW)
- {
- WindowRect.right -= ButtonWidth;
- }
- else
+ PWND_DATA pwndData = ThemeGetWndData(hWnd);
+
+ if (!(wi.dwExStyle & WS_EX_TOOLWINDOW))
{
// if(!(wi.dwExStyle & WS_EX_DLGMODALFRAME))
// FIXME: The real test should check whether there is
// See win32ss/user/user32/windows/nonclient.c!DefWndNCHitTest
// and win32ss/user/ntuser/nonclient.c!GetNCHitEx which does
// the test better.
- WindowRect.left += ButtonWidth;
- WindowRect.right -= ButtonWidth;
+ WindowRect.left += GetSystemMetrics(SM_CXSMICON);
+ }
+
+ 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)
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;
}
}
/* Paint the window on the preview hDC */
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);
+ SetViewportOrgEx(hDC, 0, 0, NULL);
+
context.hDC = NULL;
+ CloseThemeData (context.theme);
+ CloseThemeData (context.scrolltheme);
ThemeCleanupDrawContext(&context);
/* Cleanup */