PRPLSTCB.H

// ----------------------------------------------------------------------------- 
// PrpLstCb.h : header file
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
// -----------------------------------------------------------------------------

#ifndef _PRPLSTCB_H_
#define _PRPLSTCB_H_

#include "ErrCpp.h"
#include "Property.h"
#include "prplstcb.chk"

// -----------------------------------------------------------------------------

#define ADMINOP_HIDDEN 0x01L
#define ADMINOP_DEFER 0x02L
#define ADMINOP_DELETE 0x04L
#define ADMINOP_NDR 0x08L

// -----------------------------------------------------------------------------
// Used to contain properties such as entry id and flags.
// -----------------------------------------------------------------------------

class CProps
{
public:
CProps( ULONG cbEID, BYTE* pEID, DWORD dwFlags);
~CProps();

// Get the entry id and byte count for a specific index.
ULONG GetByteCnt() {return( m_cbEID);}
LPENTRYID GetEID() {return( (LPENTRYID) m_pEID);}

// Functions to return the state of a flag.
BOOL bTestFlags( DWORD dwBits) {return( (m_dwFlags & dwBits) == dwBits);}
BOOL bIsHidden() {return( bTestFlags(ADMINOP_HIDDEN));}
BOOL bIsDefer() {return( bTestFlags(ADMINOP_DEFER));}
BOOL bIsDelete() {return( bTestFlags(ADMINOP_DELETE));}
BOOL bIsNDR() {return( bTestFlags(ADMINOP_NDR));}
DWORD dwGetFlags() {return( m_dwFlags);} // Returns all of the flags.

// Set one of the flags (pass in TRUE or FALSE).
void SetHidden( BOOL bState) { m_dwFlags = (m_dwFlags & ~ADMINOP_HIDDEN) | bState;}
void SetDefer( BOOL bState) { m_dwFlags = (m_dwFlags & ~ADMINOP_DEFER ) | bState << 1;}
void SetDelete( BOOL bState) { m_dwFlags = (m_dwFlags & ~ADMINOP_DELETE) | bState << 2;}
void SetNDR( BOOL bState) { m_dwFlags = (m_dwFlags & ~ADMINOP_NDR ) | bState << 3;}

protected:
ULONG m_cbEID;
BYTE* m_pEID;
DWORD m_dwFlags;
};

// Helper function.
inline BOOL bIsHidden( DWORD dwFlags) {return( (dwFlags & 0x01) == 0x01);}

// Used to replace a null CProps*.
extern CProps NullCProps;

// -----------------------------------------------------------------------------
// Definition of a class that keeps a list of entry ids using struct _EID to
// contain them. This is a template class which is to be derived from either
// CListBox or CComboBox.
// -----------------------------------------------------------------------------

template< class BASE_CLASS>
class CPropsListComboBox : public BASE_CLASS
{
public:
CPropsListComboBox() { m_pProps = NULL;}
~CPropsListComboBox() { Destruct();}

// Fills the list or combo box with data from the table, uses HrAddItem to prepare the data.
HRESULT HrFillBox( LPMAPITABLE pTable);

// Clears all data from the box.
void ResetContent();

// Use this to remove an item from the list.
int DeleteString( int ii);

// Get the entry id and byte count for a specific index.
CProps* GetProps( int ii); // Always returns valid pointer, GUARENTEED!
ULONG GetByteCnt( int ii) {return( GetProps( ii)->GetByteCnt());}
LPENTRYID GetEID( int ii) {return( GetProps( ii)->GetEID());}
DWORD dwGetFlags( int ii) {return( GetProps( ii)->dwGetFlags());}

protected:
LPSPropTagArray m_psPropColumns; // Set this in your derived class.
LPSSortOrderSet m_psSortPrioSet; // Set this in your derived class.
CProps* m_pProps; // Used by AddString() and HrFillBox()

// Pure virtual function called by HrFillBox.
virtual HRESULT HrAddItem( CProperty& Properties) = 0;

// Used to add a string and its properties.
int AddString( const LPCTSTR lpszItem);

// Use this because we can't use a message map in a template class.
virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam);

// Clean up when the window has been destroyed.
virtual void Destruct();

// These functions may not be used unless they are implemented properly.
int InsertString( UINT nIndex, LPCTSTR lpszItem)
{
ASSERTERROR( FALSE, "NOT IMPLEMENTED");
return( LB_ERR);
}
};

// $--CPropsListComboBox< BASE_CLASS>::HrFillBox()------------------------------
// Fill the list or combo box with data from a table. This function reads the
// data from the caller specified table and validates it.
//
// A pure virtual function named HrAddItem() supplies the method for formating
// and placing the data into the list or combo box. HrAddItem() could also
// decide to throw it away or use it.
// -----------------------------------------------------------------------------

template< class BASE_CLASS>
HRESULT CPropsListComboBox< BASE_CLASS>::HrFillBox(
LPMAPITABLE pTable)
{
DEBUGPUBLIC( "CPropsListComboBox< BASE_CLASS>::HrFillBox()\n");
CHRESULT hr = CHK_CPropsListComboBox_HrFillBox( pTable);
if(FAILED(hr))
RETURN( hr);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Setup the table's columns and sort order.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// Set the columns to return.
hr = pTable->SetColumns( m_psPropColumns, 0L);
if( FAILED( hr))
RETURN( hr);

// Sort the table.
hr = pTable->SortTable( m_psSortPrioSet, 0L);
if(FAILED(hr))
RETURN( hr);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Contents table has been initialize so lets display it.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// Clear the list/combo box of all entries.
ResetContent();

// Fill list/combo box with info from folder until end of table reached.
while( TRUE)
{ // Read the first 10 message headers from the contents table.
CPropertyRows PropRowSet;
CHRESULT hr = PropRowSet.HrGetTblRows( pTable);
if( hr == EDK_E_END_OF_FILE )
return( NOERROR); // All done.

if( FAILED( hr))
RETURN( hr);

// Process all messages in the current table.
for( PropRowSet.FirstRow(); !PropRowSet.bAtEndOfRows(); PropRowSet.NextRow())
{ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Validate that the property array has the correct number of values
// and that it has the correct properties in the expected order.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//#ifdef DEBUG
PropRowSet.First();
unsigned cProps = m_psPropColumns->cValues;
if( PropRowSet.GetCount() < cProps)
{
RETURN( E_FAIL);
}

if( PropRowSet.ulGetPrID() != PROP_ID( PR_GW_ADMIN_OPERATIONS))
{
RETURN( E_FAIL);
}

PropRowSet.Next();
if( PropRowSet.ulGetPrID() != PROP_ID( PR_ENTRYID))
{
RETURN( E_FAIL);
}

unsigned ii;
for( ii = 2; ii < cProps; ii ++)
{
PropRowSet.Next();
if( PropRowSet.ulGetPrID() != PROP_ID( m_psPropColumns->aulPropTag[ ii]))
{
RETURN( E_FAIL);
}
}
//#endif

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Extract the properties from pRowSet into useable objects.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropRowSet.First();

// PR_GW_ADMIN_OPERATIONS
DWORD dwFlags;
if( PropRowSet.ulGetPrType() != PT_LONG)
dwFlags = 0;
else
dwFlags = PropRowSet.upvGetPrValue().ul;
if( bIsHidden( dwFlags))
continue; // No need to go any further, this one is hidden.

// PR_ENTRYID
// Create a CProps object which will be added to list in AddString().
PropRowSet.Next();
if( m_pProps)
delete m_pProps;
if( PropRowSet.ulGetPrType() != PT_BINARY)
m_pProps = new CProps( 0, NULL, dwFlags);
else
m_pProps = new CProps( PropRowSet.upvGetPrValue().bin.cb, PropRowSet.upvGetPrValue().bin.lpb, dwFlags);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Add the item to the list.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropRowSet.Next();
hr = HrAddItem( PropRowSet);
if( FAILED( hr))
RETURN( hr);
} // End For Loop
}
}

// $--CPropsListComboBox< BASE_CLASS>::ResetContent()---------------------------
// Frees all entry ids associated with the list box items and clears the list box.
// -----------------------------------------------------------------------------

template< class BASE_CLASS>
void CPropsListComboBox< BASE_CLASS>::ResetContent()
{
// Are we still connected to the windows control?
if( !::IsWindow(m_hWnd))
return; // NO, we are not connected.

// Free all property info objects.
int ii = GetCount();
while( ii)
{
ii --;
CProps* pProps = (CProps*) GetItemDataPtr( ii);
delete pProps;
}
BASE_CLASS::ResetContent();
}

// $--CPropsListComboBox< BASE_CLASS>::DeleteString()---------------------------
// Use this to remove an item from the list.
// -----------------------------------------------------------------------------

template< class BASE_CLASS>
int CPropsListComboBox< BASE_CLASS>::DeleteString( int ii) // Index of list item.
{
// Are we still connected to the windows control?
if( !::IsWindow(m_hWnd))
{ // NO, we are not connected.
HR_LOG( E_FAIL);
return(0);
}

// NOTE: This parameter test MUST be done after the above test since
// the GetCount() function depends upon being connected to the
// windows control.
if( ii < 0 || ii >= GetCount())
{
HR_LOG( E_FAIL);
return( 0);
}

CProps* pProps = (CProps*) GetItemDataPtr( ii);
delete pProps;
return( BASE_CLASS::DeleteString( (UINT) ii));
}

// $--CPropsListComboBox< BASE_CLASS>::GetProps()-------------------------------
// Returns CProps object and GUARENTEES it to be valid. This does error
// checking and if it can't get the pointer requested it returns a pointer to
// NullCProps which has NULL for all values and always exists.
// -----------------------------------------------------------------------------

template< class BASE_CLASS>
CProps* CPropsListComboBox< BASE_CLASS>::GetProps( int ii) // Index of entry id.
{
// Are we still connected to the windows control?
if( !::IsWindow(m_hWnd))
{
HR_LOG( E_FAIL);
return(0); // NO we are not connected.
}

// NOTE: This parameter test MUST be done after the above test since
// the GetCount() function depends upon being connected to the
// windows control.
if( ii < 0 || ii >= GetCount())
{
HR_LOG( E_FAIL);
return( &NullCProps);
}

CProps* pProps = (CProps*) GetItemDataPtr( ii);
if( !pProps || pProps == (CProps*) -1l)
{
HR_LOG( E_FAIL);
return( &NullCProps);
}

return( pProps);
}

// $--CPropsListComboBox< BASE_CLASS>::AddString()------------------------------
// Add a string to the list box and an entry id to associate with it.
// -----------------------------------------------------------------------------

template< class BASE_CLASS>
int CPropsListComboBox< BASE_CLASS>::AddString( // Return index of list box item.
const LPCTSTR lpszItem) // Ptr to string to add to list.
{
DEBUGPUBLIC( "CPropsListComboBox< BASE_CLASS>::AddString()\n");
if( FAILED( CHK_CPropsListComboBox_AddString( lpszItem)))
return( LB_ERR);

// Add the displayable row to the list box.
int ii = BASE_CLASS::AddString( lpszItem);
if( ii == LB_ERR)
{
HR_LOG( E_FAIL);
return( ii);
}
else if( ii == LB_ERRSPACE)
{
HR_LOG( E_FAIL);
return( ii);
}

// Add a pointer to the properties as additional data.
// Do we have properties to add?
if( m_pProps)
{ // YES, so associate it with the box's row.
SetItemDataPtr( ii, (void*) m_pProps);
m_pProps = NULL; // So it does not get deleted before it should.
}

return( ii);
}

// $--CPropsListComboBox< BASE_CLASS>::WindowProc()-----------------------------
// Clean up when list box is being destroyed.
// Use this because we can't use a message map in a template class therefore
// we can't capture ON_WM_DESTROY in the usual MFC manor.
// -----------------------------------------------------------------------------

template< class BASE_CLASS>
LRESULT CPropsListComboBox< BASE_CLASS>::WindowProc( UINT message, WPARAM wParam, LPARAM lParam)
{
if( message == WM_DESTROY)
Destruct();
return( CWnd::WindowProc( message, wParam, lParam)); // Dispatch message anyway.
}

// $--CPropsListComboBox< BASE_CLASS>::Destruct()-------------------------------
// Clean up when the window has been destroyed. This virtual function is
// supplied so that derived classes do not have to implement a message map or
// a WindowProc(). Plus we must delete all CProps objects.
// -----------------------------------------------------------------------------

template< class BASE_CLASS>
void CPropsListComboBox< BASE_CLASS>::Destruct()
{
ResetContent();
if( m_pProps)
{
delete m_pProps;
m_pProps = NULL;
}
}

// -----------------------------------------------------------------------------
// Derived class to support the list box in the QueViewer.
// -----------------------------------------------------------------------------

class CPropsListBox : public CPropsListComboBox< CListBox>
{
public:
CPropsListBox();

protected:
// Virtual function called by HrFillBox.
virtual HRESULT HrAddItem( CProperty& Properties);
};

// -----------------------------------------------------------------------------
// Derived class to support the combo box in the QueViewer.
// -----------------------------------------------------------------------------

class CPropsComboBox : public CPropsListComboBox< CComboBox>
{
public:
CPropsComboBox();

// Find all folders, and open default folder.
HRESULT HrInitialize(
LPMDB pMDB); // Ptr to MDB that contain gateway folders.

// Returns TRUE if a folder selection has changed.
BOOL bSelectionChanged() { return( m_iFolder != GetCurSel());}

// Returns the folder that is selected.
LPMAPIFOLDER GetFolder() {return( m_pFolder);}
BOOL bIsDefer() { return( GetProps( m_iFolder)->bIsDefer());}
BOOL bIsDelete() { return( GetProps( m_iFolder)->bIsDelete());}
BOOL bIsNDR() { return( GetProps( m_iFolder)->bIsNDR());}

protected:
int m_iFolder; // Index of folder being viewed.
LPMAPIFOLDER m_pFolder; // Ptr to folder being viewed.
LPMDB m_pMDB; // Ptr to MSD of gateway.
CString m_sCurFolderName; // Contains name of selected folder.

// Open the selected folder.
BOOL HrOpenFolder();

// Virtual function called by HrFillBox.
virtual HRESULT HrAddItem( CProperty& Properties);

// Clean up when the window has been destroyed.
virtual void Destruct();
};

// -----------------------------------------------------------------------------
#ifdef _GLOBAL_OBJECTS_
#pragma message("Declaration of global objects for: " __FILE__)

// Used to replace a null CProps*.
CProps NullCProps( 0, NULL, 0);

#endif //_GLOBAL_OBJECTS_
// -----------------------------------------------------------------------------

#endif //_PRPLSTCB_H_