⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 checklist.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * 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 21596 2006-04-15 10:41:58Z greatlrd $
 *
 * 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 UINT 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 + -