https://git.reactos.org/?p=reactos.git;a=commitdiff;h=118869f69cf8fec59a38097a96a0338c02524a28
commit 118869f69cf8fec59a38097a96a0338c02524a28 Author: Ethan Rodensky <splitwi...@gmail.com> AuthorDate: Sat Oct 21 21:13:18 2023 -0400 Commit: Mark Jansen <mark.jan...@reactos.org> CommitDate: Tue Feb 13 21:20:49 2024 +0100 [UXTHEME] Implement the rest of DrawNCPreview --- dll/cpl/desk/theme.c | 3 +- dll/win32/uxtheme/ncscrollbar.c | 41 ++++--- dll/win32/uxtheme/nonclient.c | 254 ++++++++++++++++++++++++++++++++++------ dll/win32/uxtheme/uxthemep.h | 4 +- 4 files changed, 246 insertions(+), 56 deletions(-) diff --git a/dll/cpl/desk/theme.c b/dll/cpl/desk/theme.c index e4d9690fe94..8c9f9faa8e4 100644 --- a/dll/cpl/desk/theme.c +++ b/dll/cpl/desk/theme.c @@ -997,7 +997,8 @@ DrawThemePreview(IN HDC hdcMem, IN PCOLOR_SCHEME scheme, IN PTHEME_SELECTION pSe FillRect(hdcMem, prcWindow, hbrBack); DeleteObject(hbrBack); - InflateRect(prcWindow, -10, -10); + InflateRect(prcWindow, -8, -8); + prcWindow->bottom -= 12; hres = DrawNCPreview(hdcMem, DNCP_DRAW_ALL, diff --git a/dll/win32/uxtheme/ncscrollbar.c b/dll/win32/uxtheme/ncscrollbar.c index a44edb00246..0adb4826cfa 100644 --- a/dll/win32/uxtheme/ncscrollbar.c +++ b/dll/win32/uxtheme/ncscrollbar.c @@ -35,7 +35,7 @@ static BOOL SCROLL_IsVertical(HWND hwnd, INT nBar) } } -static LONG SCROLL_getObjectId(INT nBar) +LONG SCROLL_getObjectId(INT nBar) { switch(nBar) { @@ -273,17 +273,13 @@ static void SCROLL_DrawMovingThumb(PWND_DATA pwndData, PDRAW_CONTEXT pcontext, S void -ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT nBar, POINT* pt) +ThemeDrawScrollBarEx(PDRAW_CONTEXT pcontext, INT nBar, PSCROLLBARINFO psbi, POINT* pt) { SCROLLINFO si; - SCROLLBARINFO sbi; BOOL vertical; enum SCROLL_HITTEST htHot = SCROLL_NOWHERE; PWND_DATA pwndData; - if (((nBar == SB_VERT) && !(pcontext->wi.dwStyle & WS_VSCROLL)) || - ((nBar == SB_HORZ) && !(pcontext->wi.dwStyle & WS_HSCROLL))) return; - if (!(pwndData = ThemeGetWndData(pcontext->hWnd))) return; @@ -291,35 +287,48 @@ ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT nBar, POINT* pt) return; /* Retrieve scrollbar info */ - sbi.cbSize = sizeof(sbi); si.cbSize = sizeof(si); si.fMask = SIF_ALL ; GetScrollInfo(pcontext->hWnd, nBar, &si); - GetScrollBarInfo(pcontext->hWnd, SCROLL_getObjectId(nBar), &sbi); vertical = SCROLL_IsVertical(pcontext->hWnd, nBar); - if(sbi.rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE && - sbi.rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_UNAVAILABLE ) + if(psbi->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE && + psbi->rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_UNAVAILABLE ) { - sbi.xyThumbTop = 0; + psbi->xyThumbTop = 0; } /* The scrollbar rect is in screen coordinates */ - OffsetRect(&sbi.rcScrollBar, -pcontext->wi.rcWindow.left, -pcontext->wi.rcWindow.top); + OffsetRect(&psbi->rcScrollBar, -pcontext->wi.rcWindow.left, -pcontext->wi.rcWindow.top); if(pt) { ScreenToWindow(pcontext->hWnd, pt); - htHot = SCROLL_HitTest(pcontext->hWnd, &sbi, vertical, *pt, FALSE); + htHot = SCROLL_HitTest(pcontext->hWnd, psbi, vertical, *pt, FALSE); } /* do not draw if the scrollbar rectangle is empty */ - if(IsRectEmpty(&sbi.rcScrollBar)) return; + if(IsRectEmpty(&psbi->rcScrollBar)) return; /* Draw the scrollbar */ - SCROLL_DrawArrows( pcontext, &sbi, vertical, 0, htHot ); - SCROLL_DrawInterior( pcontext, &sbi, sbi.xyThumbTop, vertical, 0, htHot ); + SCROLL_DrawArrows( pcontext, psbi, vertical, 0, htHot ); + SCROLL_DrawInterior( pcontext, psbi, psbi->xyThumbTop, vertical, 0, htHot ); } +void +ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT nBar, POINT* pt) +{ + SCROLLBARINFO sbi; + + if (((nBar == SB_VERT) && !(pcontext->wi.dwStyle & WS_VSCROLL)) || + ((nBar == SB_HORZ) && !(pcontext->wi.dwStyle & WS_HSCROLL))) + { + return; + } + + sbi.cbSize = sizeof(sbi); + GetScrollBarInfo(pcontext->hWnd, SCROLL_getObjectId(nBar), &sbi); + ThemeDrawScrollBarEx(pcontext, nBar, &sbi, pt); +} /*********************************************************************** diff --git a/dll/win32/uxtheme/nonclient.c b/dll/win32/uxtheme/nonclient.c index e48b5ac693a..7ff8f46acfa 100644 --- a/dll/win32/uxtheme/nonclient.c +++ b/dll/win32/uxtheme/nonclient.c @@ -8,6 +8,10 @@ #include "uxthemep.h" +#define NC_PREVIEW_MSGBOX_HALF_WIDTH 75 +#define NC_PREVIEW_MSGBOX_OFFSET_X -29 +#define NC_PREVIEW_MSGBOX_OFFSET_Y 71 + static BOOL IsWindowActive(HWND hWnd, DWORD ExStyle) { @@ -110,17 +114,14 @@ HRESULT WINAPI ThemeDrawCaptionText(PDRAW_CONTEXT pcontext, RECT* pRect, int iPa InternalGetWindowText(pcontext->hWnd, pszText, len); - hr = GetThemeSysFont(0,TMT_CAPTIONFONT,&logfont); + hr = GetThemeSysFont(pcontext->theme, TMT_CAPTIONFONT, &logfont); if(SUCCEEDED(hr)) hFont = CreateFontIndirectW(&logfont); if(hFont) oldFont = SelectObject(pcontext->hDC, hFont); - if (!pcontext->Active) - textColor = GetSysColor(COLOR_INACTIVECAPTIONTEXT); - else - textColor = GetSysColor(COLOR_CAPTIONTEXT); + textColor = GetThemeSysColor(pcontext->theme, pcontext->Active ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT); GetThemeEnumValue(pcontext->theme, iPartId, iStateId, TMT_CONTENTALIGNMENT, &align); if (align == CA_CENTER) @@ -210,12 +211,11 @@ ThemeEndBufferedPaint(PDRAW_CONTEXT pcontext, int x, int y, int cx, int cy) pcontext->hDC = pcontext->hDCScreen; } -void ThemeCalculateCaptionButtonsPos(HWND hWnd, HTHEME htheme) +static void ThemeCalculateCaptionButtonsPosEx(WINDOWINFO* wi, HWND hWnd, HTHEME htheme, INT buttonHeight) { PWND_DATA pwndData; DWORD style; - INT ButtonWidth, ButtonHeight, iPartId, i; - WINDOWINFO wi = {sizeof(wi)}; + INT captionBtnWidth, captionBtnHeight, iPartId, i; RECT rcCurrent; SIZE ButtonSize; @@ -236,40 +236,47 @@ void ThemeCalculateCaptionButtonsPos(HWND hWnd, HTHEME htheme) return; } - 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; + 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); + InflateRect(&rcCurrent, -(int)wi->cyWindowBorders-BUTTON_GAP_SIZE, + -(int)wi->cyWindowBorders-BUTTON_GAP_SIZE); - iPartId = wi.dwExStyle & WS_EX_TOOLWINDOW ? WP_SMALLCLOSEBUTTON : WP_CLOSEBUTTON; + iPartId = wi->dwExStyle & WS_EX_TOOLWINDOW ? WP_SMALLCLOSEBUTTON : WP_CLOSEBUTTON; 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); + captionBtnWidth = MulDiv(ButtonSize.cx, buttonHeight, ButtonSize.cy); - ButtonHeight -= 4; - ButtonWidth -= 4; + captionBtnHeight = buttonHeight - 4; + captionBtnWidth -= 4; for (i = CLOSEBUTTON; i <= HELPBUTTON; i++) { SetRect(&pwndData->rcCaptionButtons[i], - rcCurrent.right - ButtonWidth, + rcCurrent.right - captionBtnWidth, rcCurrent.top, rcCurrent.right, - rcCurrent.top + ButtonHeight); + rcCurrent.top + captionBtnHeight); - rcCurrent.right -= ButtonWidth + BUTTON_GAP_SIZE; + rcCurrent.right -= captionBtnWidth + BUTTON_GAP_SIZE; } } +void ThemeCalculateCaptionButtonsPos(HWND hWnd, HTHEME htheme) +{ + INT btnHeight; + WINDOWINFO wi = {sizeof(wi)}; + if(!GetWindowInfo(hWnd, &wi)) + return; + btnHeight = GetSystemMetrics(wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMSIZE : SM_CYSIZE); + + ThemeCalculateCaptionButtonsPosEx(&wi, hWnd, htheme, btnHeight); +} + static void ThemeDrawCaptionButton(PDRAW_CONTEXT pcontext, RECT* prcCurrent, @@ -1075,6 +1082,117 @@ ThemeWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, WNDPROC DefWndPr } } +static +void +DrawWindowForNCPreview( + _In_ HDC hDC, + _In_ PDRAW_CONTEXT pcontext, + _In_ INT left, + _In_ INT top, + _In_ INT right, + _In_ INT bottom, + _In_ BOOL drawClientAreaColor, + _Out_opt_ LPRECT prcClient) +{ + if (!hDC) + return; + + if (!pcontext) + return; + + DWORD dwStyle = pcontext->wi.dwStyle; + DWORD dwExStyle = pcontext->wi.dwExStyle; + pcontext->CaptionHeight = pcontext->wi.cyWindowBorders + GetThemeSysSize(pcontext->theme, dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMSIZE : SM_CYSIZE); + /* FIXME: still need to use ncmetrics from parameters for window border width */ + + RECT rcWindowPrev = { pcontext->wi.rcWindow.left, pcontext->wi.rcWindow.top, pcontext->wi.rcWindow.right, pcontext->wi.rcWindow.bottom }; + RECT rcClientPrev = { pcontext->wi.rcClient.left, pcontext->wi.rcClient.top, pcontext->wi.rcClient.right, pcontext->wi.rcClient.bottom }; + SetWindowPos(pcontext->hWnd, NULL, left, top, right - left, bottom - top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_DRAWFRAME | SWP_NOCOPYBITS); + RECT rcWindowNew = { left, top, right, bottom }; + pcontext->wi.rcWindow = rcWindowNew; + + BOOL hasVScrollBar = dwStyle & WS_VSCROLL; + if (hasVScrollBar) + { + SCROLLINFO dummyScrollInfo; + EnableScrollBar(pcontext->hWnd, SB_VERT, ESB_ENABLE_BOTH); + + dummyScrollInfo.cbSize = sizeof(dummyScrollInfo); + dummyScrollInfo.fMask = SIF_DISABLENOSCROLL | SIF_POS | SIF_RANGE; + dummyScrollInfo.nMin = 0; + dummyScrollInfo.nMax = rcWindowNew.bottom - rcWindowNew.top; + dummyScrollInfo.nPos = 0; + SetScrollInfo(pcontext->hWnd, SB_VERT, &dummyScrollInfo, TRUE); + } + + SetViewportOrgEx(hDC, rcWindowNew.left, rcWindowNew.top, NULL); + + INT offsetX = -rcWindowNew.left; + INT offsetY = -rcWindowNew.top; + OffsetRect(&rcWindowNew, offsetX, offsetY); + ThemeCalculateCaptionButtonsPosEx(&pcontext->wi, pcontext->hWnd, pcontext->theme, pcontext->CaptionHeight - pcontext->wi.cyWindowBorders); + + + INT leftBorderInset = pcontext->wi.cxWindowBorders; + INT titleBarInset = pcontext->CaptionHeight; // + pcontext->wi.cyWindowBorders; + INT rightBorderInset = pcontext->wi.cxWindowBorders; + INT bottomBorderInset = pcontext->wi.cyWindowBorders; + + RECT rcClientNew; + if (GetWindowRect(pcontext->hWnd, &rcClientNew)) + { + rcClientNew.left += leftBorderInset; + rcClientNew.top += titleBarInset; + rcClientNew.right -= rightBorderInset; + rcClientNew.bottom -= bottomBorderInset; + } + pcontext->wi.rcClient = rcClientNew; + + pcontext->wi.dwStyle &= ~(WS_HSCROLL | WS_VSCROLL); + ThemePaintWindow(pcontext, &rcWindowNew, FALSE); + pcontext->wi.dwStyle = dwStyle; + + if (hasVScrollBar && IsScrollBarVisible(pcontext->hWnd, OBJID_VSCROLL)) + { + SCROLLBARINFO sbi; + sbi.cbSize = sizeof(sbi); + GetScrollBarInfo(pcontext->hWnd, OBJID_VSCROLL, &sbi); + INT scWidth = sbi.rcScrollBar.right - sbi.rcScrollBar.left; + + sbi.rcScrollBar.right = rcClientNew.right; + rcClientNew.right -= scWidth; + sbi.rcScrollBar.left = rcClientNew.right; + + sbi.rcScrollBar.top = rcClientNew.top; + sbi.rcScrollBar.bottom = rcClientNew.bottom; + + ThemeDrawScrollBarEx(pcontext, SB_VERT, &sbi, NULL); + } + pcontext->wi.rcClient = rcClientNew; + + OffsetRect(&rcClientNew, -pcontext->wi.rcWindow.left, -pcontext->wi.rcWindow.top); + + if (drawClientAreaColor) + { + HBRUSH hbrWindow = GetThemeSysColorBrush(pcontext->theme, COLOR_WINDOW); + FillRect(hDC, &rcClientNew, hbrWindow); + DeleteObject(hbrWindow); + } + + pcontext->wi.rcWindow = rcWindowPrev; + pcontext->wi.rcClient = rcClientPrev; + + SetViewportOrgEx(hDC, 0, 0, NULL); + if (prcClient != NULL) + { + prcClient->left = rcClientNew.left; + prcClient->top = rcClientNew.top; + prcClient->right = rcClientNew.right; + prcClient->bottom = rcClientNew.bottom; + OffsetRect(prcClient, -offsetX, -offsetY); + } +} + HRESULT WINAPI DrawNCPreview(HDC hDC, DWORD DNCP_Flag, LPRECT prcPreview, @@ -1089,10 +1207,6 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, HRESULT hres; HTHEMEFILE hThemeFile; DRAW_CONTEXT context; - RECT rcCurrent; - - /* FIXME: We also need to implement drawing the rest of the preview windows - * and make use of the ncmetrics and colors passed as parameters */ /* Create a dummy window that will be used to trick the paint funtions */ memset(&DummyPreviewWindowClass, 0, sizeof(DummyPreviewWindowClass)); @@ -1104,7 +1218,7 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, if (!RegisterClassExW(&DummyPreviewWindowClass)) return E_FAIL; - hwndDummy = CreateWindowExW(0, L"DummyPreviewWindowClass", L"Active window", WS_OVERLAPPEDWINDOW,30,30,300,150,0,0,hDllInst,NULL); + hwndDummy = CreateWindowExW(0, L"DummyPreviewWindowClass", L"Active window", WS_OVERLAPPEDWINDOW | WS_VSCROLL, 30, 30, 300, 150, 0, 0, hDllInst, NULL); if (!hwndDummy) return E_FAIL; @@ -1121,22 +1235,86 @@ HRESULT WINAPI DrawNCPreview(HDC hDC, context.scrolltheme = OpenThemeDataFromFile(hThemeFile, hwndDummy, L"SCROLLBAR", 0); if (!context.scrolltheme) return E_FAIL; - context.Active = TRUE; context.wi.cbSize = sizeof(context.wi); if (!GetWindowInfo(hwndDummy, &context.wi)) return E_FAIL; context.wi.dwStyle |= WS_VISIBLE; - context.CaptionHeight = context.wi.cyWindowBorders; - context.CaptionHeight += GetSystemMetrics(context.wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION ); + context.hRgn = CreateRectRgnIndirect(&context.wi.rcWindow); + RECT rcAdjPreview = { prcPreview->left, prcPreview->top, prcPreview->right, prcPreview->bottom }; + INT previewWidth = rcAdjPreview.right - rcAdjPreview.left; + INT previewHeight = rcAdjPreview.bottom - rcAdjPreview.top; - /* 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); + /* Draw inactive preview window */ + context.Active = FALSE; + SetWindowTextW(hwndDummy, L"Inactive Window"); + DrawWindowForNCPreview(hDC, &context, rcAdjPreview.left, rcAdjPreview.top, rcAdjPreview.right - 17, rcAdjPreview.bottom - 20, TRUE, NULL); + + /* Draw active preview window */ + context.Active = TRUE; + SetWindowTextW(hwndDummy, L"Active Window"); + + DWORD textDrawFlags = DT_NOPREFIX | DT_SINGLELINE | DT_WORDBREAK; + RECT rcWindowClient; + DrawWindowForNCPreview(hDC, &context, rcAdjPreview.left + 10, rcAdjPreview.top + 22, rcAdjPreview.right, rcAdjPreview.bottom, TRUE, &rcWindowClient); + LOGFONTW lfText; + HFONT textFont = NULL; + if (SUCCEEDED(GetThemeSysFont(context.theme, TMT_MSGBOXFONT, &lfText))) + textFont = CreateFontIndirectW(&lfText); + + if (textFont) + SelectFont(hDC, textFont); + + + SetTextColor(hDC, GetThemeSysColor(context.theme, TMT_WINDOWTEXT)); + DrawThemeText(context.theme, hDC, WP_DIALOG, 0, L"Window Text", -1, DT_LEFT | DT_TOP | textDrawFlags, 0, &rcWindowClient); + + /* Draw preview dialog window */ + SetWindowTextW(hwndDummy, L"Message Box"); + DWORD dwStyleNew = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_DLGFRAME; + SetWindowLongPtr(hwndDummy, GWL_STYLE, dwStyleNew); + DWORD dwExStyleNew = WS_EX_DLGMODALFRAME; + SetWindowLongPtr(hwndDummy, GWL_EXSTYLE, dwExStyleNew); + + if (!GetWindowInfo(hwndDummy, &context.wi)) + return E_FAIL; + + context.wi.dwStyle = WS_VISIBLE | dwStyleNew; + context.wi.dwExStyle = dwExStyleNew; + + INT msgBoxHCenter = rcAdjPreview.left + (previewWidth / 2); + INT msgBoxVCenter = rcAdjPreview.top + (previewHeight / 2); + + DrawWindowForNCPreview(hDC, &context, msgBoxHCenter - NC_PREVIEW_MSGBOX_HALF_WIDTH, msgBoxVCenter + NC_PREVIEW_MSGBOX_OFFSET_X, msgBoxHCenter + NC_PREVIEW_MSGBOX_HALF_WIDTH, msgBoxVCenter + NC_PREVIEW_MSGBOX_OFFSET_Y, FALSE, &rcWindowClient); + DrawThemeBackground(context.theme, hDC, WP_DIALOG, 0, &rcWindowClient, NULL); + + /* Draw preview dialog button */ + HTHEME hBtnTheme = OpenThemeDataFromFile(hThemeFile, hwndDummy, L"BUTTON", OTD_NONCLIENT); + if (hBtnTheme) + { + INT btnCenterH = rcWindowClient.left + ((rcWindowClient.right - rcWindowClient.left) / 2); + INT btnCenterV = rcWindowClient.top + ((rcWindowClient.bottom - rcWindowClient.top) / 2); + RECT rcBtn = {btnCenterH - 40, btnCenterV - 15, btnCenterH + 40, btnCenterV + 15}; + int btnPart = BP_PUSHBUTTON; + int btnState = PBS_DEFAULTED; + DrawThemeBackground(hBtnTheme, hDC, btnPart, btnState, &rcBtn, NULL); + MARGINS btnContentMargins; + if (GetThemeMargins(hBtnTheme, hDC, btnPart, btnState, TMT_CONTENTMARGINS, NULL, &btnContentMargins) == S_OK) + { + rcBtn.left += btnContentMargins.cxLeftWidth; + rcBtn.top += btnContentMargins.cyTopHeight; + rcBtn.right -= btnContentMargins.cxRightWidth; + rcBtn.bottom -= btnContentMargins.cyBottomHeight; + } + + LPCWSTR btnText = L"OK"; + LOGFONTW lfBtn; + if ((GetThemeFont(hBtnTheme, hDC, btnPart, btnState, TMT_FONT, &lfBtn) != S_OK) && textFont) + SelectFont(hDC, textFont); + + DrawThemeText(hBtnTheme, hDC, btnPart, btnState, btnText, -1, DT_CENTER | DT_VCENTER | textDrawFlags, 0, &rcBtn); + CloseThemeData(hBtnTheme); + } context.hDC = NULL; CloseThemeData (context.theme); diff --git a/dll/win32/uxtheme/uxthemep.h b/dll/win32/uxtheme/uxthemep.h index af1ffd31a3d..6c8e62b8135 100644 --- a/dll/win32/uxtheme/uxthemep.h +++ b/dll/win32/uxtheme/uxthemep.h @@ -258,7 +258,9 @@ typedef enum { 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); +LONG SCROLL_getObjectId(INT nBar); +void ThemeDrawScrollBarEx(PDRAW_CONTEXT pcontext, INT nBar, PSCROLLBARINFO psbi, POINT* pt); +void ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT Bar, POINT* pt); VOID NC_TrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt); void ThemeInitDrawContext(PDRAW_CONTEXT pcontext, HWND hWnd, HRGN hRgn); void ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext);