|
|
///////////////////////////////////////////////////////////////////////////////
//
// 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()
|