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);