enable editing of the checkboxes and minor bugfixes

svn path=/trunk/; revision=16402
This commit is contained in:
Thomas Bluemel 2005-07-03 23:29:36 +00:00
parent fae2febad9
commit 68a5299cd2

View file

@ -49,6 +49,7 @@ typedef struct _CHECKLISTWND
BOOL HasFocus; BOOL HasFocus;
PCHECKITEM FocusedCheckItem; PCHECKITEM FocusedCheckItem;
UINT FocusedCheckItemBox; UINT FocusedCheckItemBox;
BOOL FocusedPushed;
COLORREF TextColor[2]; COLORREF TextColor[2];
UINT CheckBoxLeft[2]; UINT CheckBoxLeft[2];
@ -124,11 +125,11 @@ FindFirstEnabledCheckBox(IN PCHECKLISTWND infoPtr,
{ {
/* return the Allow checkbox in case both check boxes are enabled! */ /* return the Allow checkbox in case both check boxes are enabled! */
*CheckBox = ((!(CurItem->State & CIS_ALLOWDISABLED)) ? CLB_ALLOW : CLB_DENY); *CheckBox = ((!(CurItem->State & CIS_ALLOWDISABLED)) ? CLB_ALLOW : CLB_DENY);
return CurItem; break;
} }
} }
return NULL; return CurItem;
} }
static PCHECKITEM static PCHECKITEM
@ -312,13 +313,15 @@ PtToCheckItemBox(IN PCHECKLISTWND infoPtr,
INT y = ppt->y % infoPtr->ItemHeight; INT y = ppt->y % infoPtr->ItemHeight;
if ((y >= CI_TEXT_MARGIN_HEIGHT && if ((y >= CI_TEXT_MARGIN_HEIGHT &&
y <= infoPtr->ItemHeight - CI_TEXT_MARGIN_HEIGHT) && y < infoPtr->ItemHeight - CI_TEXT_MARGIN_HEIGHT) &&
(((ppt->x >= (infoPtr->CheckBoxLeft[CLB_ALLOW] - (infoPtr->ItemHeight / 2))) && (((ppt->x >= (infoPtr->CheckBoxLeft[CLB_ALLOW] - (infoPtr->ItemHeight / 2))) &&
(ppt->x <= (infoPtr->CheckBoxLeft[CLB_ALLOW] - (infoPtr->ItemHeight / 2) + infoPtr->ItemHeight))) (ppt->x < (infoPtr->CheckBoxLeft[CLB_ALLOW] - (infoPtr->ItemHeight / 2) +
infoPtr->ItemHeight - (2 * CI_TEXT_MARGIN_HEIGHT))))
|| ||
((ppt->x >= (infoPtr->CheckBoxLeft[CLB_DENY] - (infoPtr->ItemHeight / 2))) && ((ppt->x >= (infoPtr->CheckBoxLeft[CLB_DENY] - (infoPtr->ItemHeight / 2))) &&
(ppt->x <= (infoPtr->CheckBoxLeft[CLB_DENY] - (infoPtr->ItemHeight / 2) + infoPtr->ItemHeight))))) (ppt->x < (infoPtr->CheckBoxLeft[CLB_DENY] - (infoPtr->ItemHeight / 2) +
infoPtr->ItemHeight - (2 * CI_TEXT_MARGIN_HEIGHT))))))
{ {
*DirectlyInCheckBox = TRUE; *DirectlyInCheckBox = TRUE;
} }
@ -663,19 +666,24 @@ RetChangeControlFont(IN PCHECKLISTWND infoPtr,
#if SUPPORT_UXTHEME #if SUPPORT_UXTHEME
static INT static INT
CalculateChkBoxStyle(IN BOOL Checked, CalculateCheckBoxStyle(IN BOOL Checked,
IN BOOL Enabled, IN BOOL Enabled,
IN BOOL HotTrack) IN BOOL HotTrack,
IN BOOL Pushed)
{ {
INT BtnState; INT BtnState;
if (Checked) if (Checked)
{ {
BtnState = (Enabled ? (HotTrack ? CBS_CHECKEDHOT : CBS_CHECKEDNORMAL) : CBS_CHECKEDDISABLED); BtnState = (Enabled ?
(Pushed ? CBS_CHECKEDPRESSED : (HotTrack ? CBS_CHECKEDHOT : CBS_CHECKEDNORMAL)) :
CBS_CHECKEDDISABLED);
} }
else else
{ {
BtnState = (Enabled ? (HotTrack ? CBS_UNCHECKEDHOT : CBS_UNCHECKEDNORMAL) : CBS_UNCHECKEDDISABLED); BtnState = (Enabled ?
(Pushed ? CBS_UNCHECKEDPRESSED : (HotTrack ? CBS_UNCHECKEDHOT : CBS_UNCHECKEDNORMAL)) :
CBS_UNCHECKEDDISABLED);
} }
return BtnState; return BtnState;
@ -721,7 +729,7 @@ PaintControl(IN PCHECKLISTWND infoPtr,
HFONT hOldFont; HFONT hOldFont;
DWORD CurrentIndex; DWORD CurrentIndex;
COLORREF OldTextColor; COLORREF OldTextColor;
BOOL Enabled, PrevEnabled; BOOL Enabled, PrevEnabled, IsPushed;
POINT hOldBrushOrg; POINT hOldBrushOrg;
#if SUPPORT_UXTHEME #if SUPPORT_UXTHEME
HRESULT hDrawResult; HRESULT hDrawResult;
@ -780,8 +788,12 @@ PaintControl(IN PCHECKLISTWND infoPtr,
-1, -1,
&TextRect, &TextRect,
DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER); DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER);
/* draw the Allow checkbox */ /* draw the Allow checkbox */
IsPushed = (Enabled && Item == infoPtr->FocusedCheckItem && infoPtr->HasFocus &&
!(Item->State & CIS_ALLOWDISABLED) && infoPtr->FocusedCheckItemBox != CLB_DENY &&
infoPtr->FocusedPushed);
CheckBox.left = infoPtr->CheckBoxLeft[CLB_ALLOW] - ((TextRect.bottom - TextRect.top) / 2); CheckBox.left = infoPtr->CheckBoxLeft[CLB_ALLOW] - ((TextRect.bottom - TextRect.top) / 2);
CheckBox.right = CheckBox.left + (TextRect.bottom - TextRect.top) - (2 * CI_TEXT_MARGIN_HEIGHT); CheckBox.right = CheckBox.left + (TextRect.bottom - TextRect.top) - (2 * CI_TEXT_MARGIN_HEIGHT);
CheckBox.top = TextRect.top; CheckBox.top = TextRect.top;
@ -789,9 +801,10 @@ PaintControl(IN PCHECKLISTWND infoPtr,
#if SUPPORT_UXTHEME #if SUPPORT_UXTHEME
if (infoPtr->ThemeHandle != NULL) if (infoPtr->ThemeHandle != NULL)
{ {
INT BtnState = CalculateChkBoxStyle(Item->State & CIS_ALLOW, INT BtnState = CalculateCheckBoxStyle(Item->State & CIS_ALLOW,
Enabled && !(Item->State & CIS_ALLOWDISABLED), Enabled && !(Item->State & CIS_ALLOWDISABLED),
(ItemHovered && infoPtr->HoveredCheckItemBox != CLB_DENY)); (ItemHovered && infoPtr->HoveredCheckItemBox != CLB_DENY),
IsPushed);
hDrawResult = DrawThemeBackground(infoPtr->ThemeHandle, hDrawResult = DrawThemeBackground(infoPtr->ThemeHandle,
@ -817,10 +830,11 @@ PaintControl(IN PCHECKLISTWND infoPtr,
DFC_BUTTON, DFC_BUTTON,
DFCS_BUTTONCHECK | DFCS_FLAT | DFCS_BUTTONCHECK | DFCS_FLAT |
((Item->State & CIS_ALLOWDISABLED) || !Enabled ? DFCS_INACTIVE : 0) | ((Item->State & CIS_ALLOWDISABLED) || !Enabled ? DFCS_INACTIVE : 0) |
((Item->State & CIS_ALLOW) ? DFCS_CHECKED : 0)); ((Item->State & CIS_ALLOW) ? DFCS_CHECKED : 0) |
(IsPushed ? DFCS_PUSHED : 0));
} }
if (infoPtr->HasFocus && if (Item == infoPtr->FocusedCheckItem &&
Item == infoPtr->FocusedCheckItem && infoPtr->HasFocus &&
infoPtr->FocusedCheckItemBox != CLB_DENY) infoPtr->FocusedCheckItemBox != CLB_DENY)
{ {
RECT rcFocus = CheckBox; RECT rcFocus = CheckBox;
@ -834,14 +848,19 @@ PaintControl(IN PCHECKLISTWND infoPtr,
} }
/* draw the Deny checkbox */ /* draw the Deny checkbox */
IsPushed = (Enabled && Item == infoPtr->FocusedCheckItem && infoPtr->HasFocus &&
!(Item->State & CIS_DENYDISABLED) && infoPtr->FocusedCheckItemBox == CLB_DENY &&
infoPtr->FocusedPushed);
CheckBox.left = infoPtr->CheckBoxLeft[CLB_DENY] - ((TextRect.bottom - TextRect.top) / 2); CheckBox.left = infoPtr->CheckBoxLeft[CLB_DENY] - ((TextRect.bottom - TextRect.top) / 2);
CheckBox.right = CheckBox.left + (TextRect.bottom - TextRect.top) - (2 * CI_TEXT_MARGIN_HEIGHT); CheckBox.right = CheckBox.left + (TextRect.bottom - TextRect.top) - (2 * CI_TEXT_MARGIN_HEIGHT);
#if SUPPORT_UXTHEME #if SUPPORT_UXTHEME
if (infoPtr->ThemeHandle != NULL) if (infoPtr->ThemeHandle != NULL)
{ {
INT BtnState = CalculateChkBoxStyle(Item->State & CIS_DENY, INT BtnState = CalculateCheckBoxStyle(Item->State & CIS_DENY,
Enabled && !(Item->State & CIS_DENYDISABLED), Enabled && !(Item->State & CIS_DENYDISABLED),
(ItemHovered && infoPtr->HoveredCheckItemBox == CLB_DENY)); (ItemHovered && infoPtr->HoveredCheckItemBox == CLB_DENY),
IsPushed);
hDrawResult = DrawThemeBackground(infoPtr->ThemeHandle, hDrawResult = DrawThemeBackground(infoPtr->ThemeHandle,
hDC, hDC,
@ -866,7 +885,8 @@ PaintControl(IN PCHECKLISTWND infoPtr,
DFC_BUTTON, DFC_BUTTON,
DFCS_BUTTONCHECK | DFCS_FLAT | DFCS_BUTTONCHECK | DFCS_FLAT |
((Item->State & CIS_DENYDISABLED) || !Enabled ? DFCS_INACTIVE : 0) | ((Item->State & CIS_DENYDISABLED) || !Enabled ? DFCS_INACTIVE : 0) |
((Item->State & CIS_DENY) ? DFCS_CHECKED : 0)); ((Item->State & CIS_DENY) ? DFCS_CHECKED : 0) |
(IsPushed ? DFCS_PUSHED : 0));
} }
if (infoPtr->HasFocus && if (infoPtr->HasFocus &&
Item == infoPtr->FocusedCheckItem && Item == infoPtr->FocusedCheckItem &&
@ -930,7 +950,6 @@ ChangeCheckItemFocus(IN PCHECKLISTWND infoPtr,
} }
} }
#if SUPPORT_UXTHEME
static VOID static VOID
UpdateCheckItemBox(IN PCHECKLISTWND infoPtr, UpdateCheckItemBox(IN PCHECKLISTWND infoPtr,
IN PCHECKITEM Item, IN PCHECKITEM Item,
@ -971,7 +990,6 @@ UpdateCheckItemBox(IN PCHECKLISTWND infoPtr,
rcUpdate.right = rcUpdate.left + infoPtr->ItemHeight; rcUpdate.right = rcUpdate.left + infoPtr->ItemHeight;
rcUpdate.top = ((Index - VisibleFirst) * infoPtr->ItemHeight) + CI_TEXT_MARGIN_HEIGHT; rcUpdate.top = ((Index - VisibleFirst) * infoPtr->ItemHeight) + CI_TEXT_MARGIN_HEIGHT;
rcUpdate.bottom = rcUpdate.top + infoPtr->ItemHeight - (2 * CI_TEXT_MARGIN_HEIGHT); rcUpdate.bottom = rcUpdate.top + infoPtr->ItemHeight - (2 * CI_TEXT_MARGIN_HEIGHT);
DbgPrint("Repaint hot item\n");
RedrawWindow(infoPtr->hSelf, RedrawWindow(infoPtr->hSelf,
&rcUpdate, &rcUpdate,
@ -982,6 +1000,7 @@ UpdateCheckItemBox(IN PCHECKLISTWND infoPtr,
} }
} }
#if SUPPORT_UXTHEME
static VOID static VOID
ChangeCheckItemHotTrack(IN PCHECKLISTWND infoPtr, ChangeCheckItemHotTrack(IN PCHECKLISTWND infoPtr,
IN PCHECKITEM NewHotTrack, IN PCHECKITEM NewHotTrack,
@ -1016,6 +1035,22 @@ ChangeCheckItemHotTrack(IN PCHECKLISTWND infoPtr,
} }
#endif #endif
static VOID
ChangeCheckBox(IN PCHECKLISTWND infoPtr,
IN PCHECKITEM CheckItem,
IN UINT CheckItemBox)
{
DWORD NewState, OldState = CheckItem->State;
DWORD CheckedBit = ((infoPtr->FocusedCheckItemBox == CLB_DENY) ? CIS_DENY : CIS_ALLOW);
BOOL Checked = (CheckItem->State & CheckedBit) != 0;
NewState = (Checked ? OldState & ~CheckedBit : OldState | CheckedBit);
/* FIXME - send a notification message */
CheckItem->State = NewState;
}
static LRESULT CALLBACK static LRESULT CALLBACK
CheckListWndProc(IN HWND hwnd, CheckListWndProc(IN HWND hwnd,
IN UINT uMsg, IN UINT uMsg,
@ -1067,20 +1102,20 @@ CheckListWndProc(IN HWND hwnd,
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
{ {
#if SUPPORT_UXTHEME POINT pt;
BOOL InCheckBox;
HWND hWndCapture = GetCapture(); HWND hWndCapture = GetCapture();
pt.x = (LONG)LOWORD(lParam);
pt.y = (LONG)HIWORD(lParam);
#if SUPPORT_UXTHEME
/* handle hovering checkboxes */ /* handle hovering checkboxes */
if (hWndCapture == NULL) if (hWndCapture == NULL)
{ {
TRACKMOUSEEVENT tme; TRACKMOUSEEVENT tme;
PCHECKITEM HotTrackItem; PCHECKITEM HotTrackItem;
UINT HotTrackItemBox; UINT HotTrackItemBox;
BOOL InCheckBox;
POINT pt;
pt.x = (LONG)LOWORD(lParam);
pt.y = (LONG)HIWORD(lParam);
HotTrackItem = PtToCheckItemBox(infoPtr, HotTrackItem = PtToCheckItemBox(infoPtr,
&pt, &pt,
@ -1111,6 +1146,30 @@ CheckListWndProc(IN HWND hwnd,
TrackMouseEvent(&tme); TrackMouseEvent(&tme);
} }
#endif #endif
if (hWndCapture == hwnd && infoPtr->FocusedCheckItem != NULL)
{
PCHECKITEM PtItem;
UINT PtItemBox;
BOOL OldPushed;
PtItem = PtToCheckItemBox(infoPtr,
&pt,
&PtItemBox,
&InCheckBox);
OldPushed = infoPtr->FocusedPushed;
infoPtr->FocusedPushed = InCheckBox && infoPtr->FocusedCheckItem == PtItem &&
infoPtr->FocusedCheckItemBox == PtItemBox;
if (OldPushed != infoPtr->FocusedPushed)
{
UpdateCheckItemBox(infoPtr,
infoPtr->FocusedCheckItem,
infoPtr->FocusedCheckItemBox);
}
}
break; break;
} }
@ -1494,6 +1553,7 @@ CheckListWndProc(IN HWND hwnd,
break; break;
} }
case WM_LBUTTONDBLCLK:
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN: case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN: case WM_RBUTTONDOWN:
@ -1504,7 +1564,7 @@ CheckListWndProc(IN HWND hwnd,
INT NewFocusBox = 0; INT NewFocusBox = 0;
BOOL InCheckBox; BOOL InCheckBox;
POINT pt; POINT pt;
BOOL ChangeFocus; BOOL ChangeFocus, Capture = FALSE;
pt.x = (LONG)LOWORD(lParam); pt.x = (LONG)LOWORD(lParam);
pt.y = (LONG)HIWORD(lParam); pt.y = (LONG)HIWORD(lParam);
@ -1540,6 +1600,14 @@ CheckListWndProc(IN HWND hwnd,
if (ChangeFocus) if (ChangeFocus)
{ {
if (uMsg == WM_LBUTTONDOWN &&
InCheckBox && GetCapture() != hwnd)
{
infoPtr->FocusedPushed = TRUE;
Capture = TRUE;
}
ChangeCheckItemFocus(infoPtr, ChangeCheckItemFocus(infoPtr,
NewFocus, NewFocus,
NewFocusBox); NewFocusBox);
@ -1549,6 +1617,47 @@ CheckListWndProc(IN HWND hwnd,
{ {
SetFocus(hwnd); SetFocus(hwnd);
} }
if (Capture)
{
SetCapture(hwnd);
}
}
break;
}
case WM_LBUTTONUP:
{
if (GetCapture() == hwnd)
{
if (infoPtr->FocusedCheckItem != NULL && infoPtr->FocusedPushed)
{
PCHECKITEM PtItem;
UINT PtItemBox;
BOOL InCheckBox;
POINT pt;
infoPtr->FocusedPushed = FALSE;
PtItem = PtToCheckItemBox(infoPtr,
&pt,
&PtItemBox,
&InCheckBox);
if (InCheckBox && PtItem == infoPtr->FocusedCheckItem &&
PtItemBox == infoPtr->FocusedCheckItemBox)
{
ChangeCheckBox(infoPtr,
PtItem,
PtItemBox);
}
UpdateCheckItemBox(infoPtr,
infoPtr->FocusedCheckItem,
infoPtr->FocusedCheckItemBox);
}
ReleaseCapture();
} }
break; break;
} }
@ -1557,25 +1666,60 @@ CheckListWndProc(IN HWND hwnd,
{ {
switch (wParam) switch (wParam)
{ {
case VK_SPACE:
{
if (infoPtr->FocusedCheckItem != NULL && GetCapture() == NULL)
{
BOOL OldPushed = infoPtr->FocusedPushed;
infoPtr->FocusedPushed = TRUE;
if (infoPtr->FocusedPushed != OldPushed)
{
MakeCheckItemVisible(infoPtr,
infoPtr->FocusedCheckItem);
UpdateCheckItemBox(infoPtr,
infoPtr->FocusedCheckItem,
infoPtr->FocusedCheckItemBox);
}
}
break;
}
case VK_RETURN: case VK_RETURN:
{ {
/* FIXME */ if (infoPtr->FocusedCheckItem != NULL && GetCapture() == NULL)
{
MakeCheckItemVisible(infoPtr,
infoPtr->FocusedCheckItem);
ChangeCheckBox(infoPtr,
infoPtr->FocusedCheckItem,
infoPtr->FocusedCheckItemBox);
UpdateCheckItemBox(infoPtr,
infoPtr->FocusedCheckItem,
infoPtr->FocusedCheckItemBox);
}
break; break;
} }
case VK_TAB: case VK_TAB:
{ {
PCHECKITEM NewFocus; if (GetCapture() == NULL)
UINT NewFocusBox = 0; {
BOOL Shift = GetKeyState(VK_SHIFT) & 0x8000; PCHECKITEM NewFocus;
UINT NewFocusBox = 0;
NewFocus = FindEnabledCheckBox(infoPtr, BOOL Shift = GetKeyState(VK_SHIFT) & 0x8000;
Shift,
&NewFocusBox);
ChangeCheckItemFocus(infoPtr, NewFocus = FindEnabledCheckBox(infoPtr,
NewFocus, Shift,
NewFocusBox); &NewFocusBox);
ChangeCheckItemFocus(infoPtr,
NewFocus,
NewFocusBox);
}
break; break;
} }
@ -1591,6 +1735,25 @@ CheckListWndProc(IN HWND hwnd,
break; break;
} }
case WM_KEYUP:
{
if (wParam == VK_SPACE && IsWindowEnabled(hwnd) &&
infoPtr->FocusedCheckItem != NULL &&
infoPtr->FocusedPushed)
{
infoPtr->FocusedPushed = FALSE;
ChangeCheckBox(infoPtr,
infoPtr->FocusedCheckItem,
infoPtr->FocusedCheckItemBox);
UpdateCheckItemBox(infoPtr,
infoPtr->FocusedCheckItem,
infoPtr->FocusedCheckItemBox);
}
break;
}
case WM_GETDLGCODE: case WM_GETDLGCODE:
{ {
INT virtKey; INT virtKey;
@ -1631,7 +1794,6 @@ CheckListWndProc(IN HWND hwnd,
#if SUPPORT_UXTHEME #if SUPPORT_UXTHEME
case WM_MOUSELEAVE: case WM_MOUSELEAVE:
{ {
DbgPrint("WM_MOUSELEAVE\n");
if (infoPtr->HoveredCheckItem != NULL) if (infoPtr->HoveredCheckItem != NULL)
{ {
/* reset and repaint the hovered check item box */ /* reset and repaint the hovered check item box */
@ -1649,7 +1811,7 @@ CheckListWndProc(IN HWND hwnd,
CloseThemeData(infoPtr->ThemeHandle); CloseThemeData(infoPtr->ThemeHandle);
infoPtr->ThemeHandle = NULL; infoPtr->ThemeHandle = NULL;
} }
if (IsThemeActive()) if (IsAppThemed())
{ {
infoPtr->ThemeHandle = OpenThemeData(infoPtr->hSelf, infoPtr->ThemeHandle = OpenThemeData(infoPtr->hSelf,
L"BUTTON"); L"BUTTON");
@ -1697,6 +1859,7 @@ CheckListWndProc(IN HWND hwnd,
infoPtr->HasFocus = FALSE; infoPtr->HasFocus = FALSE;
infoPtr->FocusedCheckItem = NULL; infoPtr->FocusedCheckItem = NULL;
infoPtr->FocusedCheckItemBox = 0; infoPtr->FocusedCheckItemBox = 0;
infoPtr->FocusedPushed = FALSE;
infoPtr->TextColor[0] = GetSysColor(COLOR_GRAYTEXT); infoPtr->TextColor[0] = GetSysColor(COLOR_GRAYTEXT);
infoPtr->TextColor[1] = GetSysColor(COLOR_WINDOWTEXT); infoPtr->TextColor[1] = GetSysColor(COLOR_WINDOWTEXT);
@ -1717,7 +1880,7 @@ CheckListWndProc(IN HWND hwnd,
infoPtr->HoverTime = HOVER_DEFAULT; infoPtr->HoverTime = HOVER_DEFAULT;
} }
if (IsThemeActive()) if (IsAppThemed())
{ {
infoPtr->ThemeHandle = OpenThemeData(infoPtr->hSelf, infoPtr->ThemeHandle = OpenThemeData(infoPtr->hSelf,
L"BUTTON"); L"BUTTON");