add support for XP themes (disabled by default) Modified: trunk/reactos/lib/aclui/aclui.xml Modified: trunk/reactos/lib/aclui/acluilib.h Modified: trunk/reactos/lib/aclui/checklist.c _____
Modified: trunk/reactos/lib/aclui/aclui.xml --- trunk/reactos/lib/aclui/aclui.xml 2005-07-03 18:32:22 UTC (rev 16394) +++ trunk/reactos/lib/aclui/aclui.xml 2005-07-03 19:32:30 UTC (rev 16395) @@ -7,11 +7,13 @@
<define name="_WIN32_IE">0x0500</define> <define name="_WIN32_WINNT">0x501</define> <define name="WINVER">0x0600</define> + <define name="SUPPORT_UXTHEME" /> <library>ntdll</library> <library>kernel32</library> <library>user32</library> <library>gdi32</library> <library>comctl32</library> + <library>uxtheme</library> <file>aclui.c</file> <file>checklist.c</file> <file>misc.c</file> _____
Modified: trunk/reactos/lib/aclui/acluilib.h --- trunk/reactos/lib/aclui/acluilib.h 2005-07-03 18:32:22 UTC (rev 16394) +++ trunk/reactos/lib/aclui/acluilib.h 2005-07-03 19:32:30 UTC (rev 16395) @@ -4,6 +4,10 @@
#include <aclui.h> #include <sddl.h> #include <ntsecapi.h> +#if SUPPORT_UXTHEME +#include <uxtheme.h> +#include <tmschema.h> +#endif #include "resource.h"
ULONG DbgPrint(PCH Format,...); _____
Modified: trunk/reactos/lib/aclui/checklist.c --- trunk/reactos/lib/aclui/checklist.c 2005-07-03 18:32:22 UTC (rev 16394) +++ trunk/reactos/lib/aclui/checklist.c 2005-07-03 19:32:30 UTC (rev 16395) @@ -52,6 +52,14 @@
COLORREF TextColor[2]; UINT CheckBoxLeft[2]; + +#if SUPPORT_UXTHEME + PCHECKITEM HoveredCheckItem; + UINT HoveredCheckItemBox; + UINT HoverTime; + + HTHEME ThemeHandle; +#endif } CHECKLISTWND, *PCHECKLISTWND;
#define CI_TEXT_MARGIN_WIDTH (6) @@ -512,7 +520,7 @@
VisibleItems = ((rcClient.bottom - rcClient.top) + infoPtr->ItemHeight - 1) / infoPtr->ItemHeight;
- if (Index < VisibleFirst + VisibleItems) + if (Index <= VisibleFirst + VisibleItems) { RECT rcUpdate;
@@ -653,6 +661,27 @@ return hOldFont; }
+#if SUPPORT_UXTHEME +static INT +CalculateChkBoxStyle(IN BOOL Checked, + IN BOOL Enabled, + IN BOOL HotTrack) +{ + INT BtnState; + + if (Checked) + { + BtnState = (Enabled ? (HotTrack ? CBS_CHECKEDHOT : CBS_CHECKEDNORMAL) : CBS_CHECKEDDISABLED); + } + else + { + BtnState = (Enabled ? (HotTrack ? CBS_UNCHECKEDHOT : CBS_UNCHECKEDNORMAL) : CBS_UNCHECKEDDISABLED); + } + + return BtnState; +} +#endif + static VOID PaintControl(IN PCHECKLISTWND infoPtr, IN HDC hDC, @@ -694,6 +723,10 @@ COLORREF OldTextColor; BOOL Enabled, PrevEnabled; POINT hOldBrushOrg; +#if SUPPORT_UXTHEME + HRESULT hDrawResult; + BOOL ItemHovered; +#endif
Enabled = IsWindowEnabled(infoPtr->hSelf); PrevEnabled = Enabled; @@ -736,6 +769,10 @@ SetTextColor(hDC, infoPtr->TextColor[PrevEnabled]); } + +#if SUPPORT_UXTHEME + ItemHovered = (Enabled && infoPtr->HoveredCheckItem == Item); +#endif
/* draw the text */ DrawText(hDC, @@ -749,12 +786,39 @@ CheckBox.right = CheckBox.left + (TextRect.bottom - TextRect.top) - (2 * CI_TEXT_MARGIN_HEIGHT); CheckBox.top = TextRect.top; CheckBox.bottom = CheckBox.top + (TextRect.bottom - TextRect.top) - (2 * CI_TEXT_MARGIN_HEIGHT); - DrawFrameControl(hDC, - &CheckBox, - DFC_BUTTON, - DFCS_BUTTONCHECK | DFCS_FLAT | - ((Item->State & CIS_ALLOWDISABLED) || !Enabled ? DFCS_INACTIVE : 0) | - ((Item->State & CIS_ALLOW) ? DFCS_CHECKED : 0)); +#if SUPPORT_UXTHEME + if (infoPtr->ThemeHandle != NULL) + { + INT BtnState = CalculateChkBoxStyle(Item->State & CIS_ALLOW, + Enabled && !(Item->State & CIS_ALLOWDISABLED), + (ItemHovered && infoPtr->HoveredCheckItemBox != CLB_DENY)); + + + hDrawResult = DrawThemeBackground(infoPtr->ThemeHandle, + hDC, + BP_CHECKBOX, + BtnState, + &CheckBox, + NULL); + + } + else + { + hDrawResult = E_FAIL; + } + + /* draw the standard checkbox if no themes are enabled or drawing the + themeed control failed */ + if (FAILED(hDrawResult)) +#endif + { + DrawFrameControl(hDC, + &CheckBox, + DFC_BUTTON, + DFCS_BUTTONCHECK | DFCS_FLAT | + ((Item->State & CIS_ALLOWDISABLED) || !Enabled ? DFCS_INACTIVE : 0) | + ((Item->State & CIS_ALLOW) ? DFCS_CHECKED : 0)); + } if (infoPtr->HasFocus && Item == infoPtr->FocusedCheckItem && infoPtr->FocusedCheckItemBox != CLB_DENY) @@ -772,12 +836,38 @@ /* draw the Deny checkbox */ CheckBox.left = infoPtr->CheckBoxLeft[CLB_DENY] - ((TextRect.bottom - TextRect.top) / 2); CheckBox.right = CheckBox.left + (TextRect.bottom - TextRect.top) - (2 * CI_TEXT_MARGIN_HEIGHT); - DrawFrameControl(hDC, - &CheckBox, - DFC_BUTTON, - DFCS_BUTTONCHECK | DFCS_FLAT | - ((Item->State & CIS_DENYDISABLED) || !Enabled ? DFCS_INACTIVE : 0) | - ((Item->State & CIS_DENY) ? DFCS_CHECKED : 0)); +#if SUPPORT_UXTHEME + if (infoPtr->ThemeHandle != NULL) + { + INT BtnState = CalculateChkBoxStyle(Item->State & CIS_DENY, + Enabled && !(Item->State & CIS_DENYDISABLED), + (ItemHovered && infoPtr->HoveredCheckItemBox == CLB_DENY)); + + hDrawResult = DrawThemeBackground(infoPtr->ThemeHandle, + hDC, + BP_CHECKBOX, + BtnState, + &CheckBox, + NULL); + + } + else + { + hDrawResult = E_FAIL; + } + + /* draw the standard checkbox if no themes are enabled or drawing the + themeed control failed */ + if (FAILED(hDrawResult)) +#endif + { + DrawFrameControl(hDC, + &CheckBox, + DFC_BUTTON, + DFCS_BUTTONCHECK | DFCS_FLAT | + ((Item->State & CIS_DENYDISABLED) || !Enabled ? DFCS_INACTIVE : 0) | + ((Item->State & CIS_DENY) ? DFCS_CHECKED : 0)); + } if (infoPtr->HasFocus && Item == infoPtr->FocusedCheckItem && infoPtr->FocusedCheckItemBox == CLB_DENY) @@ -812,7 +902,7 @@ static VOID ChangeCheckItemFocus(IN PCHECKLISTWND infoPtr, IN PCHECKITEM NewFocus, - IN INT NewFocusBox) + IN UINT NewFocusBox) { if (NewFocus != infoPtr->FocusedCheckItem) { @@ -840,6 +930,92 @@ } }
+#if SUPPORT_UXTHEME +static VOID +UpdateCheckItemBox(IN PCHECKLISTWND infoPtr, + IN PCHECKITEM Item, + IN UINT ItemBox) +{ + LONG Style; + RECT rcClient; + INT VisibleFirst, VisibleItems; + INT Index = CheckItemToIndex(infoPtr, + Item); + if (Index != -1) + { + Style = GetWindowLong(infoPtr->hSelf, + GWL_STYLE); + + if (Style & WS_VSCROLL) + { + VisibleFirst = GetScrollPos(infoPtr->hSelf, + SB_VERT); + } + else + { + VisibleFirst = 0; + } + + if (Index >= VisibleFirst) + { + GetClientRect(infoPtr->hSelf, + &rcClient); + + VisibleItems = ((rcClient.bottom - rcClient.top) + infoPtr->ItemHeight - 1) / infoPtr->ItemHeight; + + if (Index <= VisibleFirst + VisibleItems) + { + RECT rcUpdate; + + rcUpdate.left = rcClient.left + infoPtr->CheckBoxLeft[ItemBox] - (infoPtr->ItemHeight / 2); + rcUpdate.right = rcUpdate.left + infoPtr->ItemHeight; + rcUpdate.top = ((Index - VisibleFirst) * infoPtr->ItemHeight) + CI_TEXT_MARGIN_HEIGHT; + rcUpdate.bottom = rcUpdate.top + infoPtr->ItemHeight - (2 * CI_TEXT_MARGIN_HEIGHT); + DbgPrint("Repaint hot item\n"); + + RedrawWindow(infoPtr->hSelf, + &rcUpdate, + NULL, + RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN); + } + } + } +} + +static VOID +ChangeCheckItemHotTrack(IN PCHECKLISTWND infoPtr, + IN PCHECKITEM NewHotTrack, + IN UINT NewHotTrackBox) +{ + if (NewHotTrack != infoPtr->HoveredCheckItem) + { + PCHECKITEM OldHotTrack = infoPtr->HoveredCheckItem; + UINT OldHotTrackBox = infoPtr->HoveredCheckItemBox; + + infoPtr->HoveredCheckItem = NewHotTrack; + infoPtr->HoveredCheckItemBox = NewHotTrackBox; + + if (OldHotTrack != NULL) + { + UpdateCheckItemBox(infoPtr, + OldHotTrack, + OldHotTrackBox); + } + } + else + { + infoPtr->HoveredCheckItemBox = NewHotTrackBox; + } + + if (NewHotTrack != NULL) + { + UpdateCheckItemBox(infoPtr, + NewHotTrack, + NewHotTrackBox); + } +} +#endif + static LRESULT CALLBACK CheckListWndProc(IN HWND hwnd, IN UINT uMsg, @@ -889,6 +1065,55 @@ break; }
+ case WM_MOUSEMOVE: + { +#if SUPPORT_UXTHEME + HWND hWndCapture = GetCapture(); + + /* handle hovering checkboxes */ + if (hWndCapture == NULL) + { + TRACKMOUSEEVENT tme; + PCHECKITEM HotTrackItem; + UINT HotTrackItemBox; + BOOL InCheckBox; + POINT pt; + + pt.x = (LONG)LOWORD(lParam); + pt.y = (LONG)HIWORD(lParam); + + HotTrackItem = PtToCheckItemBox(infoPtr, + &pt, + &HotTrackItemBox, + &InCheckBox); + if (HotTrackItem != NULL && InCheckBox) + { + if (infoPtr->HoveredCheckItem != HotTrackItem || + infoPtr->HoveredCheckItemBox != HotTrackItemBox) + { + ChangeCheckItemHotTrack(infoPtr, + HotTrackItem, + HotTrackItemBox); + } + } + else + { + ChangeCheckItemHotTrack(infoPtr, + NULL, + 0); + } + + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hwnd; + tme.dwHoverTime = infoPtr->HoverTime; + + TrackMouseEvent(&tme); + } +#endif + break; + } + case WM_VSCROLL: { SCROLLINFO ScrollInfo; @@ -1403,6 +1628,51 @@ break; }
+#if SUPPORT_UXTHEME + case WM_MOUSELEAVE: + { + DbgPrint("WM_MOUSELEAVE\n"); + if (infoPtr->HoveredCheckItem != NULL) + { + /* reset and repaint the hovered check item box */ + ChangeCheckItemHotTrack(infoPtr, + NULL, + 0); + } + break; + } + + case WM_THEMECHANGED: + { + if (infoPtr->ThemeHandle != NULL) + { + CloseThemeData(infoPtr->ThemeHandle); + infoPtr->ThemeHandle = NULL; + } + if (IsThemeActive()) + { + infoPtr->ThemeHandle = OpenThemeData(infoPtr->hSelf, + L"BUTTON"); + } + break; + } +#endif + + case WM_SETTINGCHANGE: + { +#if SUPPORT_UXTHEME + /* update the hover time */ + if (!SystemParametersInfo(SPI_GETMOUSEHOVERTIME, + 0, + &infoPtr->HoverTime, + 0)) + { + infoPtr->HoverTime = HOVER_DEFAULT; + } +#endif + break; + } + case WM_CREATE: { infoPtr = HeapAlloc(GetProcessHeap(), @@ -1435,6 +1705,28 @@
infoPtr->CheckBoxLeft[0] = rcClient.right - 30; infoPtr->CheckBoxLeft[1] = rcClient.right - 15; + +#if SUPPORT_UXTHEME + infoPtr->HoveredCheckItem = NULL; + infoPtr->HoveredCheckItemBox = 0; + if (!SystemParametersInfo(SPI_GETMOUSEHOVERTIME, + 0, + &infoPtr->HoverTime, + 0)) + { + infoPtr->HoverTime = HOVER_DEFAULT; + } + + if (IsThemeActive()) + { + infoPtr->ThemeHandle = OpenThemeData(infoPtr->hSelf, + L"BUTTON"); + } + else + { + infoPtr->ThemeHandle = NULL; + } +#endif } else { @@ -1447,6 +1739,13 @@ { ClearCheckItems(infoPtr);
+#if SUPPORT_UXTHEME + if (infoPtr->ThemeHandle != NULL) + { + CloseThemeData(infoPtr->ThemeHandle); + } +#endif + HeapFree(GetProcessHeap(), 0, infoPtr);