📄 checklist.c
字号:
/*
* ReactOS Access Control List Editor
* Copyright (C) 2004-2005 ReactOS Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id: checklist.c 25638 2007-01-26 19:44:42Z janderwald $
*
* PROJECT: ReactOS Access Control List Editor
* FILE: lib/aclui/checklist.c
* PURPOSE: Access Control List Editor
* PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
*
* UPDATE HISTORY:
* 07/01/2005 Created
*/
#include <precomp.h>
#define NDEBUG
#include <debug.h>
static const WCHAR szCheckListWndClass[] = L"CHECKLIST_ACLUI";
#define CI_TEXT_MARGIN_WIDTH (8)
#define CI_TEXT_MARGIN_HEIGHT (3)
#define CI_TEXT_SELECTIONMARGIN (1)
#define TIMER_ID_SETHITFOCUS (1)
#define TIMER_ID_RESETQUICKSEARCH (2)
#define DEFAULT_QUICKSEARCH_SETFOCUS_DELAY (2000)
#define DEFAULT_QUICKSEARCH_RESET_DELAY (3000)
typedef struct _CHECKITEM
{
struct _CHECKITEM *Next;
ACCESS_MASK AccessMask;
DWORD State;
WCHAR Name[1];
} CHECKITEM, *PCHECKITEM;
typedef struct _CHECKLISTWND
{
HWND hSelf;
HWND hNotify;
HFONT hFont;
PCHECKITEM CheckItemListHead;
UINT CheckItemCount;
INT ItemHeight;
PCHECKITEM FocusedCheckItem;
UINT FocusedCheckItemBox;
COLORREF TextColor[2];
INT CheckBoxLeft[2];
PCHECKITEM QuickSearchHitItem;
WCHAR QuickSearchText[65];
UINT QuickSearchSetFocusDelay;
UINT QuickSearchResetDelay;
DWORD CaretWidth;
DWORD UIState;
#if SUPPORT_UXTHEME
PCHECKITEM HoveredCheckItem;
UINT HoveredCheckItemBox;
UINT HoverTime;
HTHEME ThemeHandle;
#endif
UINT HasFocus : 1;
UINT FocusedPushed : 1;
UINT QuickSearchEnabled : 1;
UINT ShowingCaret : 1;
} CHECKLISTWND, *PCHECKLISTWND;
static VOID EscapeQuickSearch(IN PCHECKLISTWND infoPtr);
#if SUPPORT_UXTHEME
static VOID ChangeCheckItemHotTrack(IN PCHECKLISTWND infoPtr,
IN PCHECKITEM NewHotTrack,
IN UINT NewHotTrackBox);
#endif
static VOID ChangeCheckItemFocus(IN PCHECKLISTWND infoPtr,
IN PCHECKITEM NewFocus,
IN UINT NewFocusBox);
/******************************************************************************/
static LRESULT
NotifyControlParent(IN PCHECKLISTWND infoPtr,
IN UINT code,
IN OUT PVOID data)
{
LRESULT Ret = 0;
if (infoPtr->hNotify != NULL)
{
LPNMHDR pnmh = (LPNMHDR)data;
pnmh->hwndFrom = infoPtr->hSelf;
pnmh->idFrom = GetWindowLongPtr(infoPtr->hSelf,
GWLP_ID);
pnmh->code = code;
Ret = SendMessage(infoPtr->hNotify,
WM_NOTIFY,
(WPARAM)pnmh->idFrom,
(LPARAM)pnmh);
}
return Ret;
}
static PCHECKITEM
FindCheckItemByIndex(IN PCHECKLISTWND infoPtr,
IN INT Index)
{
PCHECKITEM Item, Found = NULL;
if (Index >= 0)
{
for (Item = infoPtr->CheckItemListHead;
Item != NULL;
Item = Item->Next)
{
if (Index == 0)
{
Found = Item;
break;
}
Index--;
}
}
return Found;
}
static UINT
FindCheckItemIndexByAccessMask(IN PCHECKLISTWND infoPtr,
IN ACCESS_MASK AccessMask)
{
PCHECKITEM Item;
UINT Index = 0, Found = -1;
for (Item = infoPtr->CheckItemListHead;
Item != NULL;
Item = Item->Next)
{
if (Item->AccessMask == AccessMask)
{
Found = Index;
break;
}
Index++;
}
return Found;
}
static INT
CheckItemToIndex(IN PCHECKLISTWND infoPtr,
IN PCHECKITEM Item)
{
PCHECKITEM CurItem;
INT Index;
for (CurItem = infoPtr->CheckItemListHead, Index = 0;
CurItem != NULL;
CurItem = CurItem->Next, Index++)
{
if (CurItem == Item)
{
return Index;
}
}
return -1;
}
static PCHECKITEM
FindCheckItem(IN PCHECKLISTWND infoPtr,
IN LPWSTR SearchText)
{
PCHECKITEM CurItem;
SIZE_T Count = wcslen(SearchText);
for (CurItem = infoPtr->CheckItemListHead;
CurItem != NULL;
CurItem = CurItem->Next)
{
if ((CurItem->State & CIS_DISABLED) != CIS_DISABLED &&
!wcsnicmp(CurItem->Name,
SearchText, Count))
{
break;
}
}
return CurItem;
}
static PCHECKITEM
FindFirstEnabledCheckBox(IN PCHECKLISTWND infoPtr,
OUT UINT *CheckBox)
{
PCHECKITEM CurItem;
for (CurItem = infoPtr->CheckItemListHead;
CurItem != NULL;
CurItem = CurItem->Next)
{
if ((CurItem->State & CIS_DISABLED) != CIS_DISABLED)
{
/* return the Allow checkbox in case both check boxes are enabled! */
*CheckBox = ((!(CurItem->State & CIS_ALLOWDISABLED)) ? CLB_ALLOW : CLB_DENY);
break;
}
}
return CurItem;
}
static PCHECKITEM
FindLastEnabledCheckBox(IN PCHECKLISTWND infoPtr,
OUT UINT *CheckBox)
{
PCHECKITEM CurItem;
PCHECKITEM LastEnabledItem = NULL;
for (CurItem = infoPtr->CheckItemListHead;
CurItem != NULL;
CurItem = CurItem->Next)
{
if ((CurItem->State & CIS_DISABLED) != CIS_DISABLED)
{
LastEnabledItem = CurItem;
}
}
if (LastEnabledItem != NULL)
{
/* return the Deny checkbox in case both check boxes are enabled! */
*CheckBox = ((!(LastEnabledItem->State & CIS_DENYDISABLED)) ? CLB_DENY : CLB_ALLOW);
}
return LastEnabledItem;
}
static PCHECKITEM
FindPreviousEnabledCheckBox(IN PCHECKLISTWND infoPtr,
OUT UINT *CheckBox)
{
PCHECKITEM Item;
if (infoPtr->FocusedCheckItem != NULL)
{
Item = infoPtr->FocusedCheckItem;
if (infoPtr->FocusedCheckItemBox == CLB_DENY &&
!(Item->State & CIS_ALLOWDISABLED))
{
/* currently an Deny checkbox is focused. return the Allow checkbox
if it's enabled */
*CheckBox = CLB_ALLOW;
}
else
{
PCHECKITEM CurItem;
Item = NULL;
for (CurItem = infoPtr->CheckItemListHead;
CurItem != infoPtr->FocusedCheckItem;
CurItem = CurItem->Next)
{
if ((CurItem->State & CIS_DISABLED) != CIS_DISABLED)
{
Item = CurItem;
}
}
if (Item != NULL)
{
/* return the Deny checkbox in case both check boxes are enabled! */
*CheckBox = ((!(Item->State & CIS_DENYDISABLED)) ? CLB_DENY : CLB_ALLOW);
}
}
}
else
{
Item = FindLastEnabledCheckBox(infoPtr,
CheckBox);
}
return Item;
}
static PCHECKITEM
FindNextEnabledCheckBox(IN PCHECKLISTWND infoPtr,
OUT UINT *CheckBox)
{
PCHECKITEM Item;
if (infoPtr->FocusedCheckItem != NULL)
{
Item = infoPtr->FocusedCheckItem;
if (infoPtr->FocusedCheckItemBox != CLB_DENY &&
!(Item->State & CIS_DENYDISABLED))
{
/* currently an Allow checkbox is focused. return the Deny checkbox
if it's enabled */
*CheckBox = CLB_DENY;
}
else
{
Item = Item->Next;
while (Item != NULL)
{
if ((Item->State & CIS_DISABLED) != CIS_DISABLED)
{
/* return the Allow checkbox in case both check boxes are enabled! */
*CheckBox = ((!(Item->State & CIS_ALLOWDISABLED)) ? CLB_ALLOW : CLB_DENY);
break;
}
Item = Item->Next;
}
}
}
else
{
Item = FindFirstEnabledCheckBox(infoPtr,
CheckBox);
}
return Item;
}
static PCHECKITEM
FindEnabledCheckBox(IN PCHECKLISTWND infoPtr,
IN BOOL ReverseSearch,
OUT UINT *CheckBox)
{
PCHECKITEM Item;
if (ReverseSearch)
{
Item = FindPreviousEnabledCheckBox(infoPtr,
CheckBox);
}
else
{
Item = FindNextEnabledCheckBox(infoPtr,
CheckBox);
}
return Item;
}
static PCHECKITEM
PtToCheckItemBox(IN PCHECKLISTWND infoPtr,
IN PPOINT ppt,
OUT UINT *CheckBox,
OUT BOOL *DirectlyInCheckBox)
{
INT FirstVisible, Index;
PCHECKITEM Item;
FirstVisible = GetScrollPos(infoPtr->hSelf,
SB_VERT);
Index = FirstVisible + (ppt->y / infoPtr->ItemHeight);
Item = FindCheckItemByIndex(infoPtr,
Index);
if (Item != NULL)
{
INT cx;
cx = infoPtr->CheckBoxLeft[CLB_ALLOW] +
((infoPtr->CheckBoxLeft[CLB_DENY] - infoPtr->CheckBoxLeft[CLB_ALLOW]) / 2);
*CheckBox = ((ppt->x <= cx) ? CLB_ALLOW : CLB_DENY);
if (DirectlyInCheckBox != NULL)
{
INT y = ppt->y % infoPtr->ItemHeight;
INT cxBox = infoPtr->ItemHeight - (2 * CI_TEXT_MARGIN_HEIGHT);
if ((y >= CI_TEXT_MARGIN_HEIGHT &&
y < infoPtr->ItemHeight - CI_TEXT_MARGIN_HEIGHT) &&
(((ppt->x >= (infoPtr->CheckBoxLeft[CLB_ALLOW] - (cxBox / 2))) &&
(ppt->x < (infoPtr->CheckBoxLeft[CLB_ALLOW] - (cxBox / 2) + cxBox)))
||
((ppt->x >= (infoPtr->CheckBoxLeft[CLB_DENY] - (cxBox / 2))) &&
(ppt->x < (infoPtr->CheckBoxLeft[CLB_DENY] - (cxBox / 2) + cxBox)))))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -