initial (not yet complete) implementation of the checklist control for the permissions editor

svn path=/trunk/; revision=16374
This commit is contained in:
Thomas Bluemel 2005-07-01 23:33:34 +00:00
parent 46903e60ea
commit 15436e184a
9 changed files with 994 additions and 62 deletions

View file

@ -30,32 +30,6 @@
HINSTANCE hDllInstance;
static LPARAM
ListViewGetSelectedItemData(IN HWND hwnd)
{
int Index;
Index = ListView_GetNextItem(hwnd,
-1,
LVNI_SELECTED);
if (Index != -1)
{
LVITEM li;
li.mask = LVIF_PARAM;
li.iItem = Index;
li.iSubItem = 0;
if (ListView_GetItem(hwnd,
&li))
{
return li.lParam;
}
}
return 0;
}
static VOID
DestroySecurityPage(IN PSECURITY_PAGE sp)
{
@ -363,6 +337,38 @@ ReloadUsersGroupsList(IN PSECURITY_PAGE sp)
}
}
static INT
AddAceListEntry(IN PSECURITY_PAGE sp,
IN PACE_LISTITEM AceListItem,
IN INT Index,
IN BOOL Selected)
{
LVITEM li;
li.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_STATE | LVIF_TEXT;
li.iItem = Index;
li.iSubItem = 0;
li.state = (Selected ? LVIS_SELECTED : 0);
li.stateMask = LVIS_SELECTED;
li.pszText = (AceListItem->DisplayString != NULL ? AceListItem->DisplayString : AceListItem->AccountName);
switch (AceListItem->SidNameUse)
{
case SidTypeUser:
li.iImage = 0;
break;
case SidTypeGroup:
li.iImage = 1;
break;
default:
li.iImage = -1;
break;
}
li.lParam = (LPARAM)AceListItem;
return ListView_InsertItem(sp->hWndAceList,
&li);
}
static VOID
FillUsersGroupsList(IN PSECURITY_PAGE sp)
{
@ -382,30 +388,10 @@ FillUsersGroupsList(IN PSECURITY_PAGE sp)
CurItem != NULL;
CurItem = CurItem->Next)
{
LVITEM li;
li.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_STATE | LVIF_TEXT;
li.iItem = -1;
li.iSubItem = 0;
li.state = (CurItem == (PACE_LISTITEM)SelLParam ? LVIS_SELECTED : 0);
li.stateMask = LVIS_SELECTED;
li.pszText = (CurItem->DisplayString != NULL ? CurItem->DisplayString : CurItem->AccountName);
switch (CurItem->SidNameUse)
{
case SidTypeUser:
li.iImage = 0;
break;
case SidTypeGroup:
li.iImage = 1;
break;
default:
li.iImage = -1;
break;
}
li.lParam = (LPARAM)CurItem;
ListView_InsertItem(sp->hWndAceList,
&li);
AddAceListEntry(sp,
CurItem,
-1,
(SelLParam == (LPARAM)CurItem));
}
EnableRedrawWindow(sp->hWndAceList);
@ -417,6 +403,15 @@ FillUsersGroupsList(IN PSECURITY_PAGE sp)
rcLvClient.right);
}
static VOID
UpdateControlStates(IN PSECURITY_PAGE sp)
{
BOOL UserOrGroupSelected;
UserOrGroupSelected = (ListViewGetSelectedItemData(sp->hWndAceList) != 0);
EnableWindow(sp->hBtnRemove, UserOrGroupSelected);
}
static UINT CALLBACK
SecurityPageCallback(IN HWND hwnd,
@ -434,6 +429,7 @@ SecurityPageCallback(IN HWND hwnd,
case PSPCB_RELEASE:
{
DestroySecurityPage(sp);
UnregisterCheckListControl();
return FALSE;
}
}
@ -441,6 +437,29 @@ SecurityPageCallback(IN HWND hwnd,
return FALSE;
}
static VOID
SetAceCheckListColumns(IN HWND hAceCheckList,
IN UINT Button,
IN HWND hLabel)
{
POINT pt;
RECT rcLabel;
GetWindowRect(hLabel,
&rcLabel);
pt.y = 0;
pt.x = (rcLabel.right - rcLabel.left) / 2;
MapWindowPoints(hLabel,
hAceCheckList,
&pt,
1);
SendMessage(hAceCheckList,
CLM_SETCHECKBOXCOLUMN,
Button,
pt.x);
}
static INT_PTR CALLBACK
SecurityPageProc(IN HWND hwndDlg,
@ -452,6 +471,28 @@ SecurityPageProc(IN HWND hwndDlg,
switch(uMsg)
{
case WM_NOTIFY:
{
NMHDR *pnmh = (NMHDR*)lParam;
if (pnmh->idFrom == IDC_ACELIST)
{
sp = (PSECURITY_PAGE)GetWindowLongPtr(hwndDlg,
DWL_USER);
if (sp != NULL)
{
switch(pnmh->code)
{
case LVN_ITEMCHANGED:
{
UpdateControlStates(sp);
break;
}
}
}
}
break;
}
case WM_INITDIALOG:
{
sp = (PSECURITY_PAGE)((LPPROPSHEETPAGE)lParam)->lParam;
@ -462,6 +503,8 @@ SecurityPageProc(IN HWND hwndDlg,
sp->hWnd = hwndDlg;
sp->hWndAceList = GetDlgItem(hwndDlg, IDC_ACELIST);
sp->hBtnRemove = GetDlgItem(hwndDlg, IDC_ACELIST_REMOVE);
sp->hAceCheckList = GetDlgItem(hwndDlg, IDC_ACE_CHECKLIST);
/* save the pointer to the structure */
SetWindowLongPtr(hwndDlg,
@ -491,6 +534,17 @@ SecurityPageProc(IN HWND hwndDlg,
ListView_InsertColumn(sp->hWndAceList, 0, &lvc);
FillUsersGroupsList(sp);
ListViewSelectItem(sp->hWndAceList,
0);
/* calculate the columns of the allow/deny checkboxes */
SetAceCheckListColumns(sp->hAceCheckList,
CLB_ALLOW,
GetDlgItem(hwndDlg, IDC_LABEL_ALLOW));
SetAceCheckListColumns(sp->hAceCheckList,
CLB_DENY,
GetDlgItem(hwndDlg, IDC_LABEL_DENY));
/* FIXME - hide controls in case the flags aren't present */
}
@ -530,7 +584,13 @@ CreateSecurityPage(IN LPSECURITYINFO psi)
{
SetLastError(hRet);
DPRINT("CreateSecurityPage() failed!\n");
DPRINT("CreateSecurityPage() failed! Failed to query the object information!\n");
return NULL;
}
if (!RegisterCheckListControl(hDllInstance))
{
DPRINT("Registering the CHECKLIST_ACLUI class failed!\n");
return NULL;
}
@ -555,7 +615,7 @@ CreateSecurityPage(IN LPSECURITYINFO psi)
psp.lParam = (LPARAM)sPage;
psp.pfnCallback = SecurityPageCallback;
if((ObjectInfo.dwFlags & SI_PAGE_TITLE) != 0 &&
if((ObjectInfo.dwFlags & SI_PAGE_TITLE) &&
ObjectInfo.pszPageTitle != NULL && ObjectInfo.pszPageTitle[0] != L'\0')
{
/* Set the page title if the flag is present and the string isn't empty */
@ -618,7 +678,7 @@ EditSecurity(IN HWND hwndOwner,
psh.dwFlags = PSH_DEFAULT;
psh.hwndParent = hwndOwner;
psh.hInstance = hDllInstance;
if((ObjectInfo.dwFlags & SI_PAGE_TITLE) != 0 &&
if((ObjectInfo.dwFlags & SI_PAGE_TITLE) &&
ObjectInfo.pszPageTitle != NULL && ObjectInfo.pszPageTitle[0] != L'\0')
{
/* Set the page title if the flag is present and the string isn't empty */

View file

@ -10,8 +10,10 @@
<library>ntdll</library>
<library>kernel32</library>
<library>user32</library>
<library>gdi32</library>
<library>comctl32</library>
<file>aclui.c</file>
<file>checklist.c</file>
<file>misc.c</file>
<file>aclui.rc</file>
<pch>acluilib.h</pch>

View file

@ -1,7 +1,7 @@
LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT
IDD_SECPAGE DIALOGEX 0, 0, 227, 215
STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
STYLE DS_NOFAILCREATE | DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_CAPTION
CAPTION "Sicherheit"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
@ -9,8 +9,9 @@ BEGIN
CONTROL "", IDC_ACELIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 7, 17, 213, 66, WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
PUSHBUTTON "&Hinzufügen...", IDC_ACELIST_ADD, 116, 87, 50, 14
PUSHBUTTON "&Entfernen", IDC_ACELIST_REMOVE, 170, 87, 50, 14
LTEXT "Erlauben", -1, 135, 107, 32, 8, SS_CENTER
LTEXT "Verbieten", -1, 176, 107, 32, 8, SS_CENTER
LTEXT "Erlauben", IDC_LABEL_ALLOW, 135, 107, 32, 8, SS_CENTER
LTEXT "Verbieten", IDC_LABEL_DENY, 176, 107, 32, 8, SS_CENTER
CONTROL "", IDC_ACE_CHECKLIST, "CHECKLIST_ACLUI", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 7, 117, 213, 72, WS_EX_CLIENTEDGE
END
STRINGTABLE DISCARDABLE

View file

@ -1,7 +1,7 @@
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
IDD_SECPAGE DIALOGEX 0, 0, 227, 215
STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
STYLE DS_NOFAILCREATE | DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_CAPTION
CAPTION "Security"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
@ -9,8 +9,9 @@ BEGIN
CONTROL "", IDC_ACELIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 7, 17, 213, 66, WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
PUSHBUTTON "A&dd...", IDC_ACELIST_ADD, 116, 87, 50, 14
PUSHBUTTON "&Remove", IDC_ACELIST_REMOVE, 170, 87, 50, 14
LTEXT "Allow", -1, 135, 107, 32, 8, SS_CENTER
LTEXT "Deny", -1, 176, 107, 32, 8, SS_CENTER
LTEXT "Allow", IDC_LABEL_ALLOW, 135, 107, 32, 8, SS_CENTER
LTEXT "Deny", IDC_LABEL_DENY, 176, 107, 32, 8, SS_CENTER
CONTROL "", IDC_ACE_CHECKLIST, "CHECKLIST_ACLUI", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 7, 117, 213, 72, WS_EX_CLIENTEDGE
END
STRINGTABLE DISCARDABLE

View file

@ -19,7 +19,7 @@
LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT
IDD_SECPAGE DIALOGEX 0, 0, 227, 215
STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
STYLE DS_NOFAILCREATE | DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_CAPTION
CAPTION "Säkerhet"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
@ -27,8 +27,9 @@ BEGIN
CONTROL "", IDC_ACELIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 7, 17, 213, 66, WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
PUSHBUTTON "&Lägg till...", IDC_ACELIST_ADD, 116, 87, 50, 14
PUSHBUTTON "&Ta bort", IDC_ACELIST_REMOVE, 170, 87, 50, 14
LTEXT "Tillåt", -1, 135, 107, 32, 8, SS_CENTER
LTEXT "Neka", -1, 176, 107, 32, 8, SS_CENTER
LTEXT "Tillåt", IDC_LABEL_ALLOW, 135, 107, 32, 8, SS_CENTER
LTEXT "Neka", IDC_LABEL_DENY, 176, 107, 32, 8, SS_CENTER
CONTROL "", IDC_ACE_CHECKLIST, "CHECKLIST_ACLUI", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 7, 117, 213, 72, WS_EX_CLIENTEDGE
END
STRINGTABLE DISCARDABLE

View file

@ -33,6 +33,8 @@ typedef struct _ACE_LISTITEM
typedef struct _SECURITY_PAGE
{
HWND hWnd;
HWND hBtnRemove;
HWND hAceCheckList;
/* Main ACE List */
HWND hWndAceList;
@ -44,6 +46,8 @@ typedef struct _SECURITY_PAGE
SI_OBJECT_INFO ObjectInfo;
} SECURITY_PAGE, *PSECURITY_PAGE;
/* MISC ***********************************************************************/
BOOL
OpenLSAPolicyHandle(IN WCHAR *SystemName,
IN ACCESS_MASK DesiredAccess,
@ -55,4 +59,36 @@ LoadAndFormatString(IN HINSTANCE hInstance,
OUT LPWSTR *lpTarget,
...);
LPARAM
ListViewGetSelectedItemData(IN HWND hwnd);
BOOL
ListViewSelectItem(IN HWND hwnd,
IN INT Index);
/* CHECKLIST CONTROL **********************************************************/
#define CIS_DISABLED (0x2)
#define CIS_ENABLED (0x0)
#define CIS_ALLOW (0x1)
#define CIS_DENY (0x0)
#define CLB_ALLOW (0x1)
#define CLB_DENY (0x0)
#define CIS_MASK (CIS_DISABLED | CIS_ALLOW | CIS_DENY)
#define CLM_ADDITEM (WM_USER + 1)
#define CLM_DELITEM (WM_USER + 2)
#define CLM_GETITEMCOUNT (WM_USER + 3)
#define CLM_CLEAR (WM_USER + 4)
#define CLM_SETCHECKBOXCOLUMN (WM_USER + 5)
#define CLM_GETCHECKBOXCOLUMN (WM_USER + 6)
BOOL
RegisterCheckListControl(HINSTANCE hInstance);
VOID
UnregisterCheckListControl(VOID);
/* EOF */

View file

@ -0,0 +1,785 @@
/*
* ReactOS Access Control List Editor
* Copyright (C) 2004 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$
*
* PROJECT: ReactOS Access Control List Editor
* FILE: lib/aclui/checklist.c
* PURPOSE: Access Control List Editor
* PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
*
* UPDATE HISTORY:
* 08/10/2004 Created
*/
#include "acluilib.h"
typedef struct _CHECKITEM
{
struct _CHECKITEM *Next;
DWORD State;
WCHAR Name[1];
} CHECKITEM, *PCHECKITEM;
typedef struct _CHECKLISTWND
{
HWND hSelf;
HWND hNotify;
DWORD Style;
HFONT hFont;
PCHECKITEM CheckItemListHead;
UINT CheckItemCount;
INT ItemHeight;
BOOL HasFocus;
COLORREF TextColor[2];
UINT CheckBoxLeft[2];
} CHECKLISTWND, *PCHECKLISTWND;
static PCHECKITEM
FindCheckItemByIndex(IN PCHECKLISTWND infoPtr,
IN UINT Index)
{
PCHECKITEM Item, Found = NULL;
for (Item = infoPtr->CheckItemListHead;
Item != NULL;
Item = Item->Next)
{
if (Index == 0)
{
Found = Item;
break;
}
Index--;
}
return Found;
}
static VOID
ClearCheckItems(IN PCHECKLISTWND infoPtr)
{
PCHECKITEM CurItem, NextItem;
CurItem = infoPtr->CheckItemListHead;
while (CurItem != NULL)
{
NextItem = CurItem->Next;
HeapFree(GetProcessHeap(),
0,
CurItem);
CurItem = NextItem;
}
infoPtr->CheckItemListHead = NULL;
infoPtr->CheckItemCount = 0;
}
static BOOL
DeleteCheckItem(IN PCHECKLISTWND infoPtr,
IN PCHECKITEM Item)
{
PCHECKITEM CurItem;
PCHECKITEM *PrevPtr = &infoPtr->CheckItemListHead;
for (CurItem = infoPtr->CheckItemListHead;
CurItem != NULL;
CurItem = CurItem->Next)
{
if (CurItem == Item)
{
*PrevPtr = CurItem->Next;
HeapFree(GetProcessHeap(),
0,
CurItem);
infoPtr->CheckItemCount--;
return TRUE;
}
PrevPtr = &CurItem->Next;
}
return FALSE;
}
static PCHECKITEM
AddCheckItem(IN PCHECKLISTWND infoPtr,
IN LPWSTR Name,
IN DWORD State)
{
PCHECKITEM CurItem;
PCHECKITEM *PrevPtr = &infoPtr->CheckItemListHead;
PCHECKITEM Item = HeapAlloc(GetProcessHeap(),
0,
sizeof(CHECKITEM) + (wcslen(Name) * sizeof(WCHAR)));
if (Item != NULL)
{
for (CurItem = infoPtr->CheckItemListHead;
CurItem != NULL;
CurItem = CurItem->Next)
{
PrevPtr = &CurItem->Next;
}
Item->Next = NULL;
Item->State = State & CIS_MASK;
wcscpy(Item->Name,
Name);
*PrevPtr = Item;
infoPtr->CheckItemCount++;
}
return Item;
}
static VOID
UpdateControl(IN PCHECKLISTWND infoPtr,
IN BOOL AllowChangeStyle)
{
RECT rcClient;
SCROLLINFO ScrollInfo;
GetClientRect(infoPtr->hSelf,
&rcClient);
ScrollInfo.cbSize = sizeof(ScrollInfo);
ScrollInfo.fMask = SIF_PAGE | SIF_RANGE;
ScrollInfo.nMin = 0;
ScrollInfo.nMax = infoPtr->CheckItemCount;
ScrollInfo.nPage = ((rcClient.bottom - rcClient.top) + infoPtr->ItemHeight - 1) / infoPtr->ItemHeight;
ScrollInfo.nPos = 0;
ScrollInfo.nTrackPos = 0;
if (AllowChangeStyle)
{
/* determine whether the vertical scrollbar has to be visible or not */
if (ScrollInfo.nMax > ScrollInfo.nPage &&
!(infoPtr->Style & WS_VSCROLL))
{
SetWindowLong(infoPtr->hSelf,
GWL_STYLE,
infoPtr->Style | WS_VSCROLL);
}
else if (ScrollInfo.nMax < ScrollInfo.nPage &&
infoPtr->Style & WS_VSCROLL)
{
SetWindowLong(infoPtr->hSelf,
GWL_STYLE,
infoPtr->Style & ~WS_VSCROLL);
}
}
SetScrollInfo(infoPtr->hSelf,
SB_VERT,
&ScrollInfo,
TRUE);
RedrawWindow(infoPtr->hSelf,
NULL,
NULL,
RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN);
}
static UINT
GetIdealItemHeight(IN PCHECKLISTWND infoPtr)
{
HDC hdc = GetDC(infoPtr->hSelf);
if(hdc != NULL)
{
UINT height;
TEXTMETRIC tm;
HGDIOBJ hOldFont = SelectObject(hdc,
infoPtr->hFont);
if(GetTextMetrics(hdc,
&tm))
{
height = tm.tmHeight;
}
else
{
height = 0;
}
SelectObject(hdc,
hOldFont);
ReleaseDC(infoPtr->hSelf,
hdc);
return height;
}
return 0;
}
static HFONT
RetChangeControlFont(IN PCHECKLISTWND infoPtr,
IN HFONT hFont,
IN BOOL Redraw)
{
HFONT hOldFont = infoPtr->hFont;
infoPtr->hFont = hFont;
if (hOldFont != hFont)
{
infoPtr->ItemHeight = 4 + GetIdealItemHeight(infoPtr);
}
UpdateControl(infoPtr,
TRUE);
return hOldFont;
}
static VOID
PaintControl(IN PCHECKLISTWND infoPtr,
IN HDC hDC,
IN PRECT rcUpdate)
{
INT ScrollPos;
PCHECKITEM FirstItem, Item;
RECT rcClient;
UINT VisibleFirstIndex = rcUpdate->top / infoPtr->ItemHeight;
UINT LastTouchedIndex = rcUpdate->bottom / infoPtr->ItemHeight;
FillRect(hDC,
rcUpdate,
(HBRUSH)(COLOR_WINDOW + 1));
GetClientRect(infoPtr->hSelf, &rcClient);
if (infoPtr->Style & WS_VSCROLL)
{
ScrollPos = GetScrollPos(infoPtr->hSelf,
SB_VERT);
}
else
{
ScrollPos = 0;
}
FirstItem = FindCheckItemByIndex(infoPtr,
ScrollPos + VisibleFirstIndex);
if (FirstItem != NULL)
{
RECT TextRect, ItemRect;
HFONT hOldFont;
DWORD CurrentIndex;
COLORREF OldTextColor;
BOOL Enabled, PrevEnabled;
POINT ptOld;
Enabled = IsWindowEnabled(infoPtr->hSelf);
PrevEnabled = Enabled;
ItemRect.left = 0;
ItemRect.right = rcClient.right;
ItemRect.top = VisibleFirstIndex * infoPtr->ItemHeight;
TextRect.left = ItemRect.left + 6;
TextRect.right = ItemRect.right - 6;
TextRect.top = ItemRect.top + 2;
MoveToEx(hDC,
infoPtr->CheckBoxLeft[CLB_ALLOW],
ItemRect.top,
&ptOld);
OldTextColor = SetTextColor(hDC,
infoPtr->TextColor[Enabled]);
hOldFont = SelectObject(hDC,
infoPtr->hFont);
for (Item = FirstItem, CurrentIndex = VisibleFirstIndex;
Item != NULL && CurrentIndex <= LastTouchedIndex;
Item = Item->Next, CurrentIndex++)
{
TextRect.bottom = TextRect.top + infoPtr->ItemHeight;
if (Enabled && PrevEnabled != ((Item->State & CIS_DISABLED) == 0))
{
PrevEnabled = ((Item->State & CIS_DISABLED) == 0);
SetTextColor(hDC,
infoPtr->TextColor[PrevEnabled]);
}
DrawText(hDC,
Item->Name,
-1,
&TextRect,
DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER);
MoveToEx(hDC,
infoPtr->CheckBoxLeft[CLB_ALLOW],
TextRect.top - 6,
NULL);
LineTo(hDC,
infoPtr->CheckBoxLeft[CLB_ALLOW],
TextRect.bottom - 6);
MoveToEx(hDC,
infoPtr->CheckBoxLeft[CLB_DENY],
TextRect.top - 6,
NULL);
LineTo(hDC,
infoPtr->CheckBoxLeft[CLB_DENY],
TextRect.bottom - 6);
TextRect.top += infoPtr->ItemHeight;
}
SelectObject(hDC,
hOldFont);
SetTextColor(hDC,
OldTextColor);
MoveToEx(hDC,
ptOld.x,
ptOld.y,
NULL);
}
}
LRESULT CALLBACK
CheckListWndProc(IN HWND hwnd,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
PCHECKLISTWND infoPtr;
LRESULT Ret;
infoPtr = (PCHECKLISTWND)GetWindowLongPtr(hwnd,
0);
if (infoPtr == NULL && uMsg != WM_CREATE)
{
return DefWindowProc(hwnd,
uMsg,
wParam,
lParam);
}
Ret = 0;
switch (uMsg)
{
case WM_PAINT:
{
HDC hdc;
RECT rcUpdate;
PAINTSTRUCT ps;
if (GetUpdateRect(hwnd,
&rcUpdate,
FALSE))
{
hdc = (wParam != 0 ? (HDC)wParam : BeginPaint(hwnd, &ps));
PaintControl(infoPtr,
hdc,
&rcUpdate);
if (wParam == 0)
{
EndPaint(hwnd,
&ps);
}
}
break;
}
case WM_VSCROLL:
{
SCROLLINFO ScrollInfo;
ScrollInfo.cbSize = sizeof(ScrollInfo);
ScrollInfo.fMask = SIF_PAGE | SIF_RANGE | SIF_POS | SIF_TRACKPOS;
if (GetScrollInfo(hwnd,
SB_VERT,
&ScrollInfo))
{
INT OldPos = ScrollInfo.nPos;
switch (LOWORD(wParam))
{
case SB_BOTTOM:
ScrollInfo.nPos = ScrollInfo.nMax;
break;
case SB_LINEDOWN:
if (ScrollInfo.nPos < ScrollInfo.nMax)
{
ScrollInfo.nPos++;
}
break;
case SB_LINEUP:
if (ScrollInfo.nPos > 0)
{
ScrollInfo.nPos--;
}
break;
case SB_PAGEDOWN:
if (ScrollInfo.nPos + ScrollInfo.nPage <= ScrollInfo.nMax)
{
ScrollInfo.nPos += ScrollInfo.nPage;
}
else
{
ScrollInfo.nPos = ScrollInfo.nMax;
}
break;
case SB_PAGEUP:
if (ScrollInfo.nPos >= ScrollInfo.nPage)
{
ScrollInfo.nPos -= ScrollInfo.nPage;
}
else
{
ScrollInfo.nPos = 0;
}
break;
case SB_THUMBPOSITION:
{
ScrollInfo.nPos = HIWORD(wParam);
break;
}
case SB_THUMBTRACK:
{
ScrollInfo.nPos = ScrollInfo.nTrackPos;
break;
}
case SB_TOP:
ScrollInfo.nPos = 0;
break;
}
if (OldPos != ScrollInfo.nPos)
{
ScrollInfo.fMask = SIF_POS;
ScrollInfo.nPos = SetScrollInfo(hwnd,
SB_VERT,
&ScrollInfo,
TRUE);
if (OldPos != ScrollInfo.nPos)
{
ScrollWindowEx(hwnd,
0,
(OldPos - ScrollInfo.nPos) * infoPtr->ItemHeight,
NULL,
NULL,
NULL,
NULL,
SW_INVALIDATE);
RedrawWindow(hwnd,
NULL,
NULL,
RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN);
}
}
}
break;
}
case CLM_ADDITEM:
{
Ret = (AddCheckItem(infoPtr,
(LPWSTR)lParam,
(DWORD)wParam) != NULL);
if (Ret)
{
UpdateControl(infoPtr,
TRUE);
}
break;
}
case CLM_DELITEM:
{
PCHECKITEM Item = FindCheckItemByIndex(infoPtr,
wParam);
if (Item != NULL)
{
Ret = DeleteCheckItem(infoPtr,
Item);
if (Ret)
{
UpdateControl(infoPtr,
TRUE);
}
}
else
{
Ret = FALSE;
}
break;
}
case CLM_GETITEMCOUNT:
{
Ret = infoPtr->CheckItemCount;
break;
}
case CLM_CLEAR:
{
ClearCheckItems(infoPtr);
UpdateControl(infoPtr,
TRUE);
break;
}
case CLM_SETCHECKBOXCOLUMN:
{
infoPtr->CheckBoxLeft[wParam != CLB_DENY] = (UINT)lParam;
Ret = 1;
break;
}
case CLM_GETCHECKBOXCOLUMN:
{
Ret = (LRESULT)infoPtr->CheckBoxLeft[wParam != CLB_DENY];
break;
}
case WM_SETFONT:
{
Ret = (LRESULT)RetChangeControlFont(infoPtr,
(HFONT)wParam,
(BOOL)lParam);
break;
}
case WM_GETFONT:
{
Ret = (LRESULT)infoPtr->hFont;
break;
}
case WM_STYLECHANGED:
{
LPSTYLESTRUCT Style = (LPSTYLESTRUCT)lParam;
if (wParam == GWL_STYLE)
{
infoPtr->Style = Style->styleNew;
UpdateControl(infoPtr,
FALSE);
}
break;
}
case WM_MOUSEWHEEL:
{
SHORT ScrollDelta;
UINT ScrollLines = 3;
SystemParametersInfo(SPI_GETWHEELSCROLLLINES,
0,
&ScrollLines,
0);
ScrollDelta = 0 - (SHORT)HIWORD(wParam);
if (ScrollLines != 0 &&
abs(ScrollDelta) >= WHEEL_DELTA)
{
SCROLLINFO ScrollInfo;
ScrollInfo.cbSize = sizeof(ScrollInfo);
ScrollInfo.fMask = SIF_RANGE | SIF_POS;
if (GetScrollInfo(hwnd,
SB_VERT,
&ScrollInfo))
{
INT OldPos = ScrollInfo.nPos;
ScrollInfo.nPos += (ScrollDelta / WHEEL_DELTA) * ScrollLines;
if (ScrollInfo.nPos < 0)
ScrollInfo.nPos = 0;
else if (ScrollInfo.nPos > ScrollInfo.nMax)
ScrollInfo.nPos = ScrollInfo.nMax;
if (OldPos != ScrollInfo.nPos)
{
ScrollInfo.fMask = SIF_POS;
ScrollInfo.nPos = SetScrollInfo(hwnd,
SB_VERT,
&ScrollInfo,
TRUE);
if (OldPos != ScrollInfo.nPos)
{
ScrollWindowEx(hwnd,
0,
(OldPos - ScrollInfo.nPos) * infoPtr->ItemHeight,
NULL,
NULL,
NULL,
NULL,
SW_INVALIDATE);
RedrawWindow(hwnd,
NULL,
NULL,
RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN);
}
}
}
}
break;
}
case WM_SETFOCUS:
{
infoPtr->HasFocus = TRUE;
break;
}
case WM_KILLFOCUS:
{
infoPtr->HasFocus = FALSE;
break;
}
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_XBUTTONDOWN:
{
if (!infoPtr->HasFocus && IsWindowEnabled(hwnd))
{
SetFocus(hwnd);
}
break;
}
case WM_SYSCOLORCHANGE:
{
infoPtr->TextColor[0] = GetSysColor(COLOR_GRAYTEXT);
infoPtr->TextColor[1] = GetSysColor(COLOR_WINDOWTEXT);
break;
}
case WM_CREATE:
{
infoPtr = HeapAlloc(GetProcessHeap(),
0,
sizeof(CHECKLISTWND));
if (infoPtr != NULL)
{
RECT rcClient;
infoPtr->hSelf = hwnd;
infoPtr->hNotify = ((LPCREATESTRUCTW)lParam)->hwndParent;
infoPtr->Style = ((LPCREATESTRUCTW)lParam)->style;
SetWindowLongPtr(hwnd,
0,
(DWORD_PTR)infoPtr);
infoPtr->CheckItemListHead = NULL;
infoPtr->CheckItemCount = 0;
infoPtr->ItemHeight = 10;
infoPtr->HasFocus = FALSE;
infoPtr->TextColor[0] = GetSysColor(COLOR_GRAYTEXT);
infoPtr->TextColor[1] = GetSysColor(COLOR_WINDOWTEXT);
GetClientRect(hwnd, &rcClient);
infoPtr->CheckBoxLeft[0] = rcClient.right - 30;
infoPtr->CheckBoxLeft[1] = rcClient.right - 15;
}
else
{
Ret = -1;
}
break;
}
case WM_DESTROY:
{
ClearCheckItems(infoPtr);
HeapFree(GetProcessHeap(),
0,
infoPtr);
SetWindowLongPtr(hwnd,
0,
(DWORD_PTR)NULL);
break;
}
default:
{
Ret = DefWindowProc(hwnd,
uMsg,
wParam,
lParam);
break;
}
}
return Ret;
}
BOOL
RegisterCheckListControl(HINSTANCE hInstance)
{
WNDCLASS wc;
ZeroMemory(&wc, sizeof(WNDCLASS));
wc.style = 0;
wc.lpfnWndProc = CheckListWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(PCHECKLISTWND);
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(0, (LPWSTR)IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = L"CHECKLIST_ACLUI";
return RegisterClass(&wc) != 0;
}
VOID
UnregisterCheckListControl(VOID)
{
UnregisterClass(L"CHECKLIST_ACLUI",
NULL);
}

View file

@ -161,3 +161,46 @@ OpenLSAPolicyHandle(IN WCHAR *SystemName,
return TRUE;
}
LPARAM
ListViewGetSelectedItemData(IN HWND hwnd)
{
int Index;
Index = ListView_GetNextItem(hwnd,
-1,
LVNI_SELECTED);
if (Index != -1)
{
LVITEM li;
li.mask = LVIF_PARAM;
li.iItem = Index;
li.iSubItem = 0;
if (ListView_GetItem(hwnd,
&li))
{
return li.lParam;
}
}
return 0;
}
BOOL
ListViewSelectItem(IN HWND hwnd,
IN INT Index)
{
LVITEM li;
li.mask = LVIF_STATE;
li.iItem = Index;
li.iSubItem = 0;
li.state = LVIS_SELECTED;
li.stateMask = LVIS_SELECTED;
return ListView_SetItem(hwnd,
&li);
}

View file

@ -6,6 +6,9 @@
#define IDC_ACELIST 1001
#define IDC_ACELIST_ADD 1002
#define IDC_ACELIST_REMOVE 1003
#define IDC_ACE_CHECKLIST 1004
#define IDC_LABEL_ALLOW 1005
#define IDC_LABEL_DENY 1006
#define IDI_DEVMGR 100