ADMINUI.CPP

/////////////////////////////////////////////////////////////////////////////// 
//
// File Name
// ADMINUI.CPP
//
// Description
//
// Author
// Irving De la Cruz
//
// Revision: 1.7
//
// Written for Microsoft Windows Developer Support
// Copyright (c) 1995-1996 Microsoft Corporation. All rights reserved.
//
#include "ADMIN.H"

#define MAXCOLUMNS 7

extern "C"
{
void WINAPI InitListViewColumns
();
BOOL WINAPI CalcStringEllipsis
(HDC hdc,
LPTSTR szString,
int cchMax,
UINT uColWidth);
void WINAPI DrawItemColumn
(HDC hdc,
LPTSTR szText,
LPRECT prcClip);
};

UINT g_uColumns[MAXCOLUMNS] =
{
100,
125,
175,
75,
175,
80,
80
};

void WINAPI InitListViewColumns()
{
TCHAR achTemp[256];
LV_COLUMN lvc;

// Initialize the LV_COLUMN structure
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
lvc.pszText = achTemp;

// Add the columns
for (int iCol = 0; iCol < MAXCOLUMNS; iCol++)
{
lvc.iSubItem = iCol;
lvc.cx = g_uColumns[iCol];
LoadString (ghInstance, IDS_COLUMN1 + iCol, achTemp, sizeof(achTemp));
ListView_InsertColumn (ghListView, iCol, &lvc);
}
}

#define TOP_CLEAR 30
#define V_BORDER_SIZE 5
#define H_BORDER_SIZE 3
#define CONTROL_HEIGHT 403
#define TREEVIEW_WIDTH 215
#define TREEVIEW_HEIGHT CONTROL_HEIGHT
#define LISTVIEW_WIDTH 560
#define LISTVIEW_HEIGHT CONTROL_HEIGHT

///////////////////////////////////////////////////////////////////////////////
// CreateListView()
//
// Parameters
//
// Purpose
//
// Return Value
//
BOOL WINAPI CreateListView (HWND hOwnerWnd, HIMAGELIST hImages)
{
RECT rc;
GetClientRect (hOwnerWnd, &rc);
ghListView = CreateWindowEx (0,
WC_LISTVIEW,
TEXT(""),
WS_VISIBLE | WS_CHILD | WS_BORDER |
LVS_REPORT | LVS_OWNERDRAWFIXED |
LVS_SHOWSELALWAYS | LVS_SINGLESEL |
LVS_SORTASCENDING,
V_BORDER_SIZE + TREEVIEW_WIDTH + V_BORDER_SIZE,
TOP_CLEAR,
LISTVIEW_WIDTH,
LISTVIEW_HEIGHT,
hOwnerWnd,
(HMENU)IDC_LISTVIEW,
ghInstance,
NULL);
if (ghListView == NULL)
{
return FALSE;
}
ListView_SetImageList (ghListView, hImages, LVSIL_SMALL);
InitListViewColumns();
return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// CreateTreeView()
//
// Parameters
//
// Purpose
//
// Return Value
//
BOOL WINAPI CreateTreeView (HWND hOwnerWnd, HIMAGELIST hImages)
{
ghTreeView = CreateWindowEx (0,
WC_TREEVIEW,
TEXT(""),
WS_BORDER | WS_CHILD | WS_VISIBLE |
TVS_HASLINES | TVS_HASBUTTONS |
TVS_LINESATROOT | TVS_SHOWSELALWAYS |
TVS_DISABLEDRAGDROP,
V_BORDER_SIZE,
TOP_CLEAR,
TREEVIEW_WIDTH,
TREEVIEW_HEIGHT,
hOwnerWnd,
(HMENU)IDC_TREEVIEW,
ghInstance,
NULL);
if (ghTreeView == NULL)
{
return FALSE;
}
TreeView_SetImageList (ghTreeView, hImages, TVSIL_NORMAL);
return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// CreateStatusBar()
//
// Parameters
//
// Purpose
//
// Return Value
//
BOOL WINAPI CreateStatusBar (HWND hOwnerWnd)
{
ghStatusBar = CreateStatusWindow (WS_BORDER | WS_CHILD | WS_VISIBLE,
TEXT("Ready"),
hOwnerWnd,
IDC_STATUSBAR);
if (ghStatusBar == NULL)
{
return FALSE;
}
return TRUE;
}

// Define this enumaration for easier array indexing
enum
{
SPACE_1,
ADD_USER,
ADD_DL,
SPACE_2,
SPACE_3,
DELETE_OBJ,
SPACE_4,
SPACE_5,
STOP_HAND,
NUMBER_OF_TB_BUTTONS,
NUMBER_OF_SEPARATORS = 5
};

///////////////////////////////////////////////////////////////////////////////
// CreateToolBar()
//
// Parameters
//
// Purpose
//
// Return Value
//
BOOL WINAPI CreateToolBar (HWND hOwnerWnd)
{
// Initialize each of the buttons with the appropiate values
TBBUTTON tbButton[NUMBER_OF_TB_BUTTONS] = { 0 };

tbButton[SPACE_1].fsStyle = TBSTYLE_SEP;
tbButton[SPACE_2].fsStyle = TBSTYLE_SEP;
tbButton[SPACE_3].fsStyle = TBSTYLE_SEP;
tbButton[SPACE_4].fsStyle = TBSTYLE_SEP;
tbButton[SPACE_5].fsStyle = TBSTYLE_SEP;

tbButton[ADD_USER].iBitmap = 0;
tbButton[ADD_USER].idCommand = IDM_FILE_NEW_MAILBOX;
tbButton[ADD_USER].fsState = TBSTATE_ENABLED;
tbButton[ADD_USER].fsStyle = TBSTYLE_BUTTON;

tbButton[ADD_DL].iBitmap = 1;
tbButton[ADD_DL].idCommand = IDM_FILE_NEW_DISTRIBUTIONLIST;
tbButton[ADD_DL].fsState = TBSTATE_ENABLED;
tbButton[ADD_DL].fsStyle = TBSTYLE_BUTTON;

tbButton[DELETE_OBJ].iBitmap = 2;
tbButton[DELETE_OBJ].idCommand= IDM_FILE_DELETE;
tbButton[DELETE_OBJ].fsState = TBSTATE_ENABLED;
tbButton[DELETE_OBJ].fsStyle = TBSTYLE_BUTTON;

tbButton[STOP_HAND].iBitmap = 3;
tbButton[STOP_HAND].idCommand= IDC_CANCEL_REMOTE_CALL;
tbButton[STOP_HAND].fsState = TBSTATE_INDETERMINATE;
tbButton[STOP_HAND].fsStyle = TBSTYLE_BUTTON;

// Create the toolbar with the most commonly used functions
ghToolBar = CreateToolbarEx (hOwnerWnd,
WS_VISIBLE | WS_CHILD | WS_BORDER | TBSTYLE_TOOLTIPS,
IDC_TOOLBAR,
// The number of images is the number of
// buttons minus the separators
NUMBER_OF_TB_BUTTONS - NUMBER_OF_SEPARATORS,
ghInstance,
IDB_TOOLBAR,
tbButton,
NUMBER_OF_TB_BUTTONS,
16, 16, 16, 32,
sizeof(TBBUTTON));
if (NULL == ghToolBar)
{
return FALSE;
}
return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// UpdateHeaderWidth()
//
// Parameters
//
// Purpose
//
// Return Value
//
void WINAPI UpdateHeaderWidth (HWND hWndHeader, int iItem)
{
HD_ITEM hdi;
// Get the column width from the control
hdi.mask = HDI_WIDTH;
if (Header_GetItem (hWndHeader, iItem, &hdi))
{
g_uColumns[iItem] = hdi.cxy;
}
// Force the ListView control to repaint
InvalidateRect (ghListView, NULL, TRUE);
}

///////////////////////////////////////////////////////////////////////////////
// DrawListViewItem()
//
// Parameters
//
// Purpose
//
// Return Value
//
void WINAPI DrawListViewItem (LPDRAWITEMSTRUCT pDIS)
{
TCHAR szBuffer[512];
LV_ITEM lvi;
int cxImage = 0, cyImage = 0;
UINT uFirstColWidth;
RECT rcClip;
int iColumn = 1;
UINT uiFlags = ILD_TRANSPARENT;

// Get the item image to be displayed
lvi.mask = LVIF_IMAGE | LVIF_STATE | LVIF_TEXT;
lvi.iItem = pDIS->itemID;
lvi.iSubItem = 0;
lvi.pszText = szBuffer;
lvi.cchTextMax = 512;
ListView_GetItem (pDIS->hwndItem, &lvi);

// Check to see if this item is selected
if (pDIS->itemState & ODS_SELECTED)
{
// Set the text background and foreground colors
SetTextColor (pDIS->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
SetBkColor (pDIS->hDC, GetSysColor(COLOR_HIGHLIGHT));

// Also add the ILD_BLEND50 so the images come out selected
uiFlags |= ILD_BLEND50;
}
else
{
// Set the text background and foreground colors to the standard window colors
SetTextColor (pDIS->hDC, GetSysColor(COLOR_WINDOWTEXT));
SetBkColor (pDIS->hDC, GetSysColor(COLOR_WINDOW));
}

// Get the image list and draw the image
ImageList_Draw (g_hImages,
lvi.iImage,
pDIS->hDC,
pDIS->rcItem.left,
pDIS->rcItem.top,
uiFlags);
// Find out how big the image we just drew was
ImageList_GetIconSize (g_hImages, &cxImage, &cyImage);

// Calculate the width of the first column after the image width. If
// There was no image, then cxImage will be zero.
uFirstColWidth = g_uColumns[0] - cxImage;

// Set up the new clipping rect for the first column text and draw it
rcClip.left = pDIS->rcItem.left + cxImage;
rcClip.right = pDIS->rcItem.left + g_uColumns[0];
rcClip.top = pDIS->rcItem.top;
rcClip.bottom = pDIS->rcItem.bottom;

DrawItemColumn (pDIS->hDC, szBuffer, &rcClip);
szBuffer[0] = 0;

lvi.mask = LVIF_TEXT;
lvi.iSubItem++;
ListView_GetItem (pDIS->hwndItem, &lvi);
rcClip.left = rcClip.right;
rcClip.right = rcClip.left + g_uColumns[1];
DrawItemColumn(pDIS->hDC, szBuffer, &rcClip);
szBuffer[0] = 0;

rcClip.left = rcClip.right;
rcClip.right = rcClip.left + g_uColumns[2];
lvi.iSubItem++;
ListView_GetItem (pDIS->hwndItem, &lvi);
DrawItemColumn(pDIS->hDC, szBuffer, &rcClip);
szBuffer[0] = 0;

rcClip.left = rcClip.right;
rcClip.right = rcClip.left + g_uColumns[3];
lvi.iSubItem++;
ListView_GetItem (pDIS->hwndItem, &lvi);
DrawItemColumn(pDIS->hDC, szBuffer, &rcClip);
szBuffer[0] = 0;

rcClip.left = rcClip.right;
rcClip.right = rcClip.left + g_uColumns[4];
lvi.iSubItem++;
ListView_GetItem (pDIS->hwndItem, &lvi);
DrawItemColumn(pDIS->hDC, szBuffer, &rcClip);
szBuffer[0] = 0;

rcClip.left = rcClip.right;
rcClip.right = rcClip.left + g_uColumns[5];
lvi.iSubItem++;
ListView_GetItem (pDIS->hwndItem, &lvi);
DrawItemColumn(pDIS->hDC, szBuffer, &rcClip);
szBuffer[0] = 0;

rcClip.left = rcClip.right;
rcClip.right = rcClip.left + g_uColumns[6];
lvi.iSubItem++;
ListView_GetItem (pDIS->hwndItem, &lvi);
DrawItemColumn(pDIS->hDC, szBuffer, &rcClip);
szBuffer[0] = 0;

// If we changed the colors for the selected item, undo it
if (pDIS->itemState & ODS_SELECTED)
{
// Set the text background and foreground colors
SetTextColor (pDIS->hDC, GetSysColor(COLOR_WINDOWTEXT));
SetBkColor (pDIS->hDC, GetSysColor(COLOR_WINDOW));
}

// If the item is focused, now draw a focus rect around the entire row
if (pDIS->itemState & ODS_FOCUS)
{
// Adjust the left edge to exclude the image
rcClip = pDIS->rcItem;
rcClip.left += cxImage;

// Draw the focus rect
DrawFocusRect (pDIS->hDC, &rcClip);
}
}

///////////////////////////////////////////////////////////////////////////////
// DrawItemColumn()
//
// Parameters
//
// Purpose
//
// Return Value
//
void WINAPI DrawItemColumn (HDC hdc, LPTSTR szText, LPRECT prcClip)
{
TCHAR szString[256];
// Check to see if the string fits in the clip rect. If not, truncate
// the string and add "...".
lstrcpy(szString, szText);
CalcStringEllipsis (hdc, szString, 256, prcClip->right - prcClip->left);
ExtTextOut (hdc,
prcClip->left + 2,
prcClip->top + 1,
ETO_CLIPPED | ETO_OPAQUE,
prcClip,
szString,
lstrlen(szString),
NULL);
}

///////////////////////////////////////////////////////////////////////////////
// CalcStringEllipsis()
//
// Parameters
//
// Purpose
//
// Return Value
//
BOOL WINAPI CalcStringEllipsis (HDC hdc,
LPTSTR szString,
int cchMax,
UINT uColWidth)
{
const TCHAR szEllipsis[] = TEXT("...");
SIZE sizeString;
SIZE sizeEllipsis;
int cbString;
LPTSTR lpszTemp;
BOOL fSuccess = FALSE;

// Adjust the column width to take into account the edges
uColWidth -= 4;
__try
{
// Allocate a string for us to work with. This way we can mangle the
// string and still preserve the return value
lpszTemp = (LPTSTR)HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, cchMax);
if (!lpszTemp)
{
__leave;
}
lstrcpy (lpszTemp, szString);

// Get the width of the string in pixels
cbString = lstrlen(lpszTemp);
if (!GetTextExtentPoint32 (hdc, lpszTemp, cbString, &sizeString))
{
__leave;
}

// If the width of the string is greater than the column width shave
// the string and add the ellipsis
if ((ULONG)sizeString.cx > uColWidth)
{
if (!GetTextExtentPoint32 (hdc,
szEllipsis,
lstrlen(szEllipsis),
&sizeEllipsis))
{
__leave;
}

while (cbString > 0)
{
lpszTemp[--cbString] = 0;
if (!GetTextExtentPoint32 (hdc, lpszTemp, cbString, &sizeString))
{
__leave;
}

if ((ULONG)(sizeString.cx + sizeEllipsis.cx) <= uColWidth)
{
// The string with the ellipsis finally fits, now make sure
// there is enough room in the string for the ellipsis
if (cchMax >= (cbString + lstrlen(szEllipsis)))
{
// Concatenate the two strings and break out of the loop
lstrcat (lpszTemp, szEllipsis);
lstrcpy (szString, lpszTemp);
fSuccess = TRUE;
__leave;
}
}
}
}
else
{
// No need to do anything, everything fits great.
fSuccess = TRUE;
}
}
__finally
{
// Free the memory
HeapFree (GetProcessHeap(), 0, (LPVOID)lpszTemp);
return fSuccess;
}
}

///////////////////////////////////////////////////////////////////////////////
// ErrorHandler()
//
// Parameters
//
// Purpose
//
// Return Value
//
void WINAPI ErrorHandler (HWND hOwnerWnd, HRESULT hError)
{
LPTSTR szSystemMessage = NULL;
TCHAR achBuffer[1024];
DWORD dwSystemError;
// If the facility is RPC remove it before calling FormatMessage(). That
// Win32 API does not recognizes the facility.
if (HRESULT_FACILITY(hError) == FACILITY_RPC)
{
dwSystemError = LOWORD(hError);
}
else
{
dwSystemError = hError;
}
// Get an error description from the system
DWORD dwChars = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwSystemError,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPTSTR)&szSystemMessage,
0,
NULL);
// Check to see if FormatMessage() returned us an error
if (0 == dwChars)
{
szSystemMessage = TEXT("Generic Error");
}
else
{
LPTSTR pStr = &szSystemMessage[lstrlen (szSystemMessage)];
while ('\r' != *pStr)
{
pStr--;
}
*pStr = 0;
}
ASSERT (dwChars < 1024);
// Add the error code to the string returned and then show it.
switch (HRESULT_FACILITY(hError))
{
case FACILITY_WIN32 :
wsprintf (achBuffer,
TEXT("%s (Win32 Error %d)"),
szSystemMessage,
LOWORD(hError));
break;
case FACILITY_STORAGE :
wsprintf (achBuffer,
TEXT("%s (IStorage Error %08X)"),
szSystemMessage,
hError);
break;
case FACILITY_ITF :
wsprintf (achBuffer,
TEXT("%s (Interface Error %08X)"),
szSystemMessage,
hError);
break;
case FACILITY_RPC :
wsprintf (achBuffer,
TEXT("%s (RPC Error %d - %08X)"),
szSystemMessage,
LOWORD(hError),
hError);
break;
default :
wsprintf (achBuffer,
TEXT("%s (Unknown Facility(%d) Error %d - %08X)"),
szSystemMessage,
HRESULT_FACILITY(hError),
hError,
hError);
break;
}
if (dwChars)
{
LocalFree ((HLOCAL)szSystemMessage);
}
MessageBox (hOwnerWnd, achBuffer, TEXT("WINDS Administrator - Error"), MB_ICONSTOP | MB_OK);
}

// End of file for ADMINUI.CPP