windows-nt/Source/XPSP1/NT/net/ias/mmc/proxy/grouppage.cpp
2020-09-26 16:20:57 +08:00

574 lines
13 KiB
C++

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000, Microsoft Corp. All rights reserved.
//
// FILE
//
// grouppage.cpp
//
// SYNOPSIS
//
// Defines the class ServerGroupPage.
//
// MODIFICATION HISTORY
//
// 02/20/2000 Original version.
// 04/19/2000 Marshall SDOs across apartments.
//
///////////////////////////////////////////////////////////////////////////////
#include <proxypch.h>
#include <grouppage.h>
#include <serverprop.h>
CSysColorImageList::CSysColorImageList(
HINSTANCE hInst,
UINT nID
)
: m_hInst(hInst),
m_hRsrc(::FindResource(m_hInst, MAKEINTRESOURCE(nID), RT_BITMAP))
{
CreateSysColorImageList();
}
void CSysColorImageList::OnSysColorChange()
{
DeleteImageList();
CreateSysColorImageList();
}
void CSysColorImageList::CreateSysColorImageList()
{
CBitmap bmp;
bmp.Attach(AfxLoadSysColorBitmap(m_hInst, m_hRsrc));
// Get the dimensions of the bitmap.
BITMAP bm;
bmp.GetBitmap(&bm);
// Assume square images (cx == cy).
Create(bm.bmHeight, bm.bmHeight, ILC_COLORDDB, bm.bmWidth / bm.bmHeight, 2);
Add(&bmp, CLR_NONE);
}
///////////////////////////////////////////////////////////////////////////////
//
// Functions for sorting each column.
//
///////////////////////////////////////////////////////////////////////////////
int compareAddress(Sdo& s1, Sdo& s2)
{
CComBSTR v1, v2;
s1.getValue(PROPERTY_RADIUSSERVER_ADDRESS, v1, L"");
s2.getValue(PROPERTY_RADIUSSERVER_ADDRESS, v2, L"");
return wcscmp(v1, v2);
}
int comparePriority(Sdo& s1, Sdo& s2)
{
LONG v1, v2;
s1.getValue(PROPERTY_RADIUSSERVER_PRIORITY, v1, 1);
s2.getValue(PROPERTY_RADIUSSERVER_PRIORITY, v2, 1);
return (int)(v1 - v2);
}
int compareWeight(Sdo& s1, Sdo& s2)
{
LONG v1, v2;
s1.getValue(PROPERTY_RADIUSSERVER_WEIGHT, v1, 50);
s2.getValue(PROPERTY_RADIUSSERVER_WEIGHT, v2, 50);
return (int)(v1 - v2);
}
//////////
// CompareProc for sorting the ListCtrl.
//////////
int
CALLBACK
CompareProc(
LPARAM lParam1,
LPARAM lParam2,
LPARAM lParamSort
)
{
Sdo s1((ISdo*)lParam1), s2((ISdo*)lParam2);
switch (lParamSort)
{
case 0:
return compareAddress(s1, s2);
case 1:
return comparePriority(s1, s2);
case 2:
return compareWeight(s1, s2);
case 3:
return -compareAddress(s1, s2);
case 4:
return -comparePriority(s1, s2);
case 5:
return -compareWeight(s1, s2);
}
return 0;
}
ServerList::ServerList()
: removeButton(NULL),
editButton(NULL),
sortIcons(AfxGetResourceHandle(), IDB_PROXY_SORT),
sortColumn(0)
{
// All columns are initially in ascending order.
descending[0] = descending[1] = descending[2] = false;
}
void ServerList::onInitDialog(HWND dialog, Sdo& serverGroup)
{
/////////
// Get the servers collection.
/////////
serverGroup.getValue(
PROPERTY_RADIUSSERVERGROUP_SERVERS_COLLECTION,
servers
);
/////////
// Subclass the list control and save the button handles.
/////////
if (!serverList.SubclassWindow(::GetDlgItem(dialog, IDC_LIST_SERVERS)))
{
AfxThrowNotSupportedException();
}
removeButton = GetDlgItem(dialog, IDC_BUTTON_REMOVE);
editButton = GetDlgItem(dialog, IDC_BUTTON_EDIT);
/////////
// Load the image strip with the server icon.
/////////
serverIcons.Create(IDB_PROXY_SMALL_ICONS, 16, 0, RGB(255, 0, 255));
serverList.SetImageList(&serverIcons, LVSIL_SMALL);
/////////
// Set the column headers.
/////////
RECT rect;
serverList.GetClientRect(&rect);
LONG width = rect.right - rect.left;
ResourceString nameCol(IDS_SERVER_COLUMN_NAME);
serverList.InsertColumn(0, nameCol, LVCFMT_LEFT, width - 150);
ResourceString priorityCol(IDS_SERVER_COLUMN_PRIORITY);
serverList.InsertColumn(1, priorityCol, LVCFMT_LEFT, 75);
ResourceString weightCol(IDS_SERVER_COLUMN_WEIGHT);
serverList.InsertColumn(2, weightCol, LVCFMT_LEFT, 75);
serverList.SetExtendedStyle(
serverList.GetExtendedStyle() | LVS_EX_FULLROWSELECT
);
CHeaderCtrl* hdr = serverList.GetHeaderCtrl();
if (hdr) { hdr->SetImageList(&sortIcons); }
}
void ServerList::onSysColorChange()
{
sortIcons.OnSysColorChange();
CHeaderCtrl* hdr = serverList.GetHeaderCtrl();
if (hdr)
{
hdr->SetImageList(&sortIcons);
}
}
void ServerList::onColumnClick(int column)
{
LVCOLUMN lvcol;
memset(&lvcol, 0, sizeof(lvcol));
lvcol.mask = LVCF_FMT | LVCF_IMAGE;
lvcol.fmt = LVCFMT_IMAGE | LVCFMT_BITMAP_ON_RIGHT;
// Reset the previous column's sort icon with blank icon.
lvcol.iImage = -1;
serverList.SetColumn(sortColumn, &lvcol);
// If the user clicked on a new column, ...
if (column != sortColumn)
{
// ... we use the existing sort order ...
sortColumn = column;
}
else
{
// ... otherwise we flip it.
descending[column] = !descending[column];
}
// Set the sort icon for new column.
lvcol.iImage = (descending[sortColumn]) ? 1 : 0;
serverList.SetColumn(sortColumn, &lvcol);
sort();
}
void ServerList::onServerChanged()
{
// We only enable remove and edit when a server is selected.
BOOL enable = serverList.GetSelectedCount() > 0;
EnableWindow(removeButton, enable);
EnableWindow(editButton, enable);
}
bool ServerList::onAdd()
{
bool modified = false;
// Create a new server ...
Sdo sdo = servers.create();
// ... and a new server property sheet.
ServerProperties props(sdo, IDS_SERVER_CAPTION_ADD);
if (props.DoModal() == IDOK)
{
// Add this to the added list ...
added.push_back(sdo);
// ... and the list control.
updateServer(sdo, 0, true);
// Re-sort the list.
sort();
modified = true;
}
else
{
// User never applied the new server, so remove it.
servers.remove(sdo);
}
return modified;
}
bool ServerList::onEdit()
{
bool modified = false;
LVITEM lvi;
memset(&lvi, 0, sizeof(lvi));
// Get the item selected.
lvi.iItem = serverList.GetNextItem(-1, LVNI_SELECTED);
if (lvi.iItem >= 0)
{
// Get the lParam that contains the ISdo pointer.
lvi.mask = LVIF_PARAM;
if (serverList.GetItem(&lvi) && lvi.lParam)
{
// Create an Sdo ...
Sdo sdo((ISdo*)lvi.lParam);
// ... and a property sheet.
ServerProperties props(sdo);
if (props.DoModal() == IDOK)
{
// Add it to the dirty list if it's not already there.
if (!dirty.contains(sdo) && !added.contains(sdo))
{
dirty.push_back(sdo);
}
// Update the entry in the list control.
updateServer(sdo, lvi.iItem, false);
// Re-sort the list.
sort();
modified = true;
}
}
}
return modified;
}
bool ServerList::onRemove()
{
bool modified = false;
LVITEM lvi;
memset(&lvi, 0, sizeof(lvi));
// Get the selected item ...
lvi.iItem = serverList.GetNextItem(-1, LVNI_SELECTED);
if (lvi.iItem >= 0)
{
// ... and the associated SDO.
lvi.mask = LVIF_PARAM;
if (serverList.GetItem(&lvi) && lvi.lParam)
{
// Add to the removed list ...
removed.push_back((ISdo*)lvi.lParam);
// ... and remove from the list control.
serverList.DeleteItem(lvi.iItem);
modified = true;
}
}
return modified;
}
void ServerList::setData()
{
serverList.DeleteAllItems();
serverList.SetItemCount(servers.count());
original.clear();
original.reserve(servers.count());
Sdo server;
SdoEnum sdoEnum(servers.getNewEnum());
for (UINT nItem = 0; sdoEnum.next(server); ++nItem)
{
updateServer(server, nItem, true);
// We add each server to the 'original' vector solely to hold a reference
// to the COM proxy.
original.push_back(server);
}
sort();
}
void ServerList::saveChanges(bool apply)
{
SdoIterator i;
if (apply)
{
// Persist all the dirty servers.
for (i = dirty.begin(); i != dirty.end(); ++i)
{
Sdo(*i).apply();
}
// Persist all the added servers.
for (i = added.begin(); i != added.end(); ++i)
{
Sdo(*i).apply();
}
}
// Remove all the deleted servers.
for (i = removed.begin(); i != removed.end(); ++i)
{
servers.remove(*i);
}
// Clear the collections.
dirty.clear();
added.clear();
removed.clear();
}
void ServerList::discardChanges()
{
// Restore the dirty servers.
SdoIterator i;
for (i = dirty.begin(); i != dirty.end(); ++i)
{
Sdo(*i).restore();
}
dirty.clear();
// Remove the added servers.
for (i = added.begin(); i != added.end(); ++i)
{
servers.remove(*i);
}
added.clear();
// Clear the deleted servers.
removed.clear();
}
void ServerList::sort()
{
int column = sortColumn;
if (descending[column]) { column += 3; }
serverList.SortItems(CompareProc, column);
}
void ServerList::updateServer(
Sdo& server,
UINT nItem,
bool create
)
{
// Get the server's name.
CComBSTR name;
server.getValue(PROPERTY_RADIUSSERVER_ADDRESS, name);
// Initialize an LVITEM.
LVITEM lvi;
memset(&lvi, 0, sizeof(LVITEM));
lvi.iItem = nItem;
lvi.pszText = name;
if (create)
{
// If we're creating, we have to set everything.
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
lvi.iImage = IMAGE_RADIUS_SERVER;
lvi.lParam = (LPARAM)(ISdo*)server;
lvi.iItem = serverList.InsertItem(&lvi);
}
else
{
// Otherwise we just set the text.
lvi.mask = LVIF_TEXT;
serverList.SetItem(&lvi);
}
LONG value;
WCHAR sz[12];
// Update priority ...
server.getValue(PROPERTY_RADIUSSERVER_PRIORITY, value);
serverList.SetItemText(lvi.iItem, 1, _ltow(value, sz, 10));
// ... and weight.
server.getValue(PROPERTY_RADIUSSERVER_WEIGHT, value);
serverList.SetItemText(lvi.iItem, 2, _ltow(value, sz, 10));
}
ServerGroupPage::ServerGroupPage(
LONG_PTR notifyHandle,
LPARAM notifyParam,
Sdo& groupSdo,
bool useName
)
: SnapInPropertyPage(notifyHandle, notifyParam, true, IDD_SERVER_GROUP),
selfStream(groupSdo)
{
if (useName) { groupSdo.getName(name); }
}
BOOL ServerGroupPage::OnInitDialog()
{
// Unmarshal the server group SDO.
selfStream.get(self);
// Initialize the server list control.
servers.onInitDialog(m_hWnd, self);
// Let our base class initialize.
return SnapInPropertyPage::OnInitDialog();
}
void ServerGroupPage::OnSysColorChange()
{
servers.onSysColorChange();
}
void ServerGroupPage::onAdd()
{
if (servers.onAdd()) { SetModified(); }
}
void ServerGroupPage::onEdit()
{
if (servers.onEdit()) { SetModified(); }
}
void ServerGroupPage::onRemove()
{
if (servers.onRemove()) { SetModified(); }
}
void ServerGroupPage::onColumnClick(
NMLISTVIEW *pNMListView,
LRESULT* pResult
)
{
servers.onColumnClick(pNMListView->iSubItem);
}
void ServerGroupPage::onItemActivate(
NMITEMACTIVATE* pNMItemAct,
LRESULT* pResult
)
{
if (servers.onEdit()) { SetModified(); }
}
void ServerGroupPage::onServerChanged(
NMLISTVIEW* pNMListView,
LRESULT* pResult
)
{
servers.onServerChanged();
}
void ServerGroupPage::getData()
{
// There must be at least one server.
if (servers.isEmpty())
{
fail(IDC_LIST_SERVERS, IDS_GROUP_E_NO_SERVERS, false);
}
getValue(IDC_EDIT_NAME, name);
// The user must specify a name ...
if (name.Length() == 0)
{
fail(IDC_EDIT_NAME, IDS_GROUP_E_NAME_EMPTY);
}
// The name must be unique.
if (!self.setName(name))
{
fail(IDC_EDIT_NAME, IDS_GROUP_E_NOT_UNIQUE);
}
}
void ServerGroupPage::setData()
{
setValue(IDC_EDIT_NAME, name);
servers.setData();
}
void ServerGroupPage::saveChanges()
{
// We have to update ourself first otherwise we won't be able to update
// our children when creating a new group.
self.apply();
servers.saveChanges();
}
void ServerGroupPage::discardChanges()
{
// Restore ourself.
self.restore();
// Restore the servers.
servers.discardChanges();
}
BEGIN_MESSAGE_MAP(ServerGroupPage, SnapInPropertyPage)
ON_BN_CLICKED(IDC_BUTTON_ADD, onAdd)
ON_BN_CLICKED(IDC_BUTTON_EDIT, onEdit)
ON_BN_CLICKED(IDC_BUTTON_REMOVE, onRemove)
ON_EN_CHANGE(IDC_EDIT_NAME, onChange)
ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST_SERVERS, onColumnClick)
ON_NOTIFY(LVN_ITEMACTIVATE, IDC_LIST_SERVERS, onItemActivate)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_SERVERS, onServerChanged)
END_MESSAGE_MAP()