654 lines
15 KiB
C++
654 lines
15 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 1996 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
faxcomponent.h
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file contains my implementation of IComponent.
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
WIN32 User Mode
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Darwin Ouyang (t-darouy) 30-Sept-1997
|
||
|
|
||
|
--*/
|
||
|
|
||
|
// faxcomponent.cpp : Implementation of CFaxComponent
|
||
|
#include "stdafx.h"
|
||
|
#include "faxadmin.h"
|
||
|
#include "faxhelper.h"
|
||
|
#include "faxcomp.h"
|
||
|
#include "faxcompd.h"
|
||
|
#include "faxdataobj.h"
|
||
|
|
||
|
#include "inode.h"
|
||
|
#include "iroot.h"
|
||
|
#include "ilogging.h"
|
||
|
#include "ilogcat.h"
|
||
|
#include "idevices.h"
|
||
|
#include "idevice.h"
|
||
|
|
||
|
#include "adminhlp.h"
|
||
|
|
||
|
#pragma hdrstop
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
// Constructor and Destructor
|
||
|
//
|
||
|
//
|
||
|
|
||
|
CFaxComponent::CFaxComponent()
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Constructor
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
m_pUnknown = NULL;
|
||
|
m_pConsole = NULL;
|
||
|
m_pConsoleNameSpace = NULL;
|
||
|
m_pConsoleVerb = NULL;
|
||
|
m_pHeaderCtrl = NULL;
|
||
|
m_pImageList = NULL;
|
||
|
m_pResultData = NULL;
|
||
|
m_pControlbar = NULL;
|
||
|
|
||
|
m_dwPropSheetCount = 0;
|
||
|
|
||
|
CFaxComponentExtendContextMenu::m_pFaxComponent = this;
|
||
|
CFaxComponentExtendPropertySheet::m_pFaxComponent = this;
|
||
|
CFaxComponentExtendControlbar::m_pFaxComponent = this;
|
||
|
|
||
|
// initialize CInternalDevices instance data
|
||
|
pDeviceArray = NULL;
|
||
|
numDevices = 0;
|
||
|
|
||
|
// initialize CInternalLogging instance data
|
||
|
pLogPArray = NULL;
|
||
|
pCategories = NULL;
|
||
|
numCategories = 0;
|
||
|
|
||
|
DebugPrint(( TEXT("FaxComponent Created") ));
|
||
|
}
|
||
|
|
||
|
CFaxComponent::~CFaxComponent()
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Destructor.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DebugPrint(( TEXT("FaxComponent Destroyed") ));
|
||
|
|
||
|
DWORD count;
|
||
|
|
||
|
// release CInternalDevices instance data
|
||
|
if(pDeviceArray != NULL ) {
|
||
|
for( count = 0; count < numDevices; count ++ ) {
|
||
|
if( pDeviceArray[count] != NULL ) {
|
||
|
delete pDeviceArray[count];
|
||
|
pDeviceArray[count] = NULL;
|
||
|
}
|
||
|
}
|
||
|
delete pDeviceArray;
|
||
|
pDeviceArray = NULL;
|
||
|
}
|
||
|
|
||
|
// release CInternalLogging instance data
|
||
|
if( pLogPArray != NULL ) {
|
||
|
for( count = 0; count < numCategories; count++ ) {
|
||
|
if( pLogPArray[count] != NULL ) {
|
||
|
delete pLogPArray[count];
|
||
|
pLogPArray[count] = NULL;
|
||
|
}
|
||
|
}
|
||
|
delete pLogPArray;
|
||
|
pLogPArray = NULL;
|
||
|
}
|
||
|
if( pCategories != NULL ) {
|
||
|
FaxFreeBuffer( (PVOID) pCategories );
|
||
|
pCategories = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
// CFaxComponent implementation
|
||
|
//
|
||
|
//
|
||
|
|
||
|
HRESULT
|
||
|
STDMETHODCALLTYPE
|
||
|
CFaxComponent::Initialize(
|
||
|
IN LPCONSOLE lpUnknown)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine initializes IComponent by querying
|
||
|
for needed interfaces.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
lpUnknown - the console's IUnknown/IConsole interface.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT indicating SUCCEEDED() or FAILED()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
assert( lpUnknown != NULL );
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
do {
|
||
|
m_pUnknown = lpUnknown;
|
||
|
// increment reference on the console
|
||
|
m_pUnknown->AddRef();
|
||
|
|
||
|
hr = m_pUnknown->QueryInterface( IID_IConsole, (void **)&m_pConsole );
|
||
|
assert( SUCCEEDED( hr ));
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
hr = m_pConsole->QueryResultImageList( &m_pImageList );
|
||
|
assert( SUCCEEDED( hr ));
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
hr = m_pUnknown->QueryInterface( IID_IResultData, (void **)&m_pResultData );
|
||
|
assert( SUCCEEDED( hr ));
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
hr = m_pUnknown->QueryInterface( IID_IConsoleNameSpace, (void **)&m_pConsoleNameSpace );
|
||
|
assert( SUCCEEDED( hr ));
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
hr = m_pConsole->QueryConsoleVerb( &m_pConsoleVerb );
|
||
|
assert( SUCCEEDED( hr ));
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
hr = m_pUnknown->QueryInterface( IID_IHeaderCtrl, (void **)&m_pHeaderCtrl );
|
||
|
assert( SUCCEEDED( hr ));
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// set the header object
|
||
|
hr = m_pConsole->SetHeader( m_pHeaderCtrl );
|
||
|
assert( SUCCEEDED( hr ));
|
||
|
if( FAILED( hr ) ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} while( 0 );
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
STDMETHODCALLTYPE
|
||
|
CFaxComponent::Notify(
|
||
|
IN LPDATAOBJECT lpDataObject,
|
||
|
IN MMC_NOTIFY_TYPE event,
|
||
|
IN LPARAM arg,
|
||
|
IN LPARAM param)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine dispatches events sent to the IComponent
|
||
|
interface using the cookie extracted from the DataObject.
|
||
|
|
||
|
The cookie stored is a pointer to the class that implements behavior for
|
||
|
that subfolder. So we delegate all the messages by taking the cookie
|
||
|
casting it to a pointer to a folder, and invoking the notify method.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
lpDataobject - the data object
|
||
|
event - the event type
|
||
|
arg, param - event arguments
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT indicating SUCCEEDED() or FAILED()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
CFaxDataObject * dataObject = NULL;
|
||
|
LONG_PTR cookie;
|
||
|
|
||
|
// DebugPrint(( TEXT("Trace: CFaxComponent::Notify") ));
|
||
|
|
||
|
if( event == MMCN_CONTEXTHELP ) {
|
||
|
MMCPropertyHelp(FAXMMC_HTMLHELP_TOPIC);
|
||
|
}
|
||
|
else if( lpDataObject != NULL) {
|
||
|
dataObject = ExtractOwnDataObject( lpDataObject );
|
||
|
if( dataObject == NULL ) {
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
cookie = dataObject->GetCookie();
|
||
|
|
||
|
if( cookie == NULL) {
|
||
|
// my static node
|
||
|
assert( pOwner );
|
||
|
hr = pOwner->globalRoot->ResultNotify( this, dataObject, event, arg, param );
|
||
|
} else {
|
||
|
// cast the cookie to a pointer
|
||
|
try {
|
||
|
hr = ((CInternalNode *)cookie)->ResultNotify( this, dataObject, event, arg, param );
|
||
|
} catch ( ... ) {
|
||
|
DebugPrint(( TEXT("Invalid Cookie: 0x%08x"), cookie ));
|
||
|
assert( FALSE ); // got passed an INVALID COOKIE!?!?!?!?
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
// some events do not pass a lpDataObject into Notify.
|
||
|
// we need to handle those events here, if you want
|
||
|
// to handle them at all!!
|
||
|
if( event == MMCN_PROPERTY_CHANGE ) {
|
||
|
if( param != NULL ) {
|
||
|
try {
|
||
|
hr = ((CInternalNode *)param)->ResultNotify( this, NULL, event, arg, param );
|
||
|
} catch ( ... ) {
|
||
|
DebugPrint(( TEXT("Invalid Cookie") ));
|
||
|
assert( FALSE ); // got passed an INVALID COOKIE!?!?!?!?
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
STDMETHODCALLTYPE
|
||
|
CFaxComponent::Destroy(
|
||
|
IN MMC_COOKIE cookie)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This method releases all the aquired console interface in preperation
|
||
|
for the IComponent being destroyed.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT indicating SUCCEEDED() or FAILED()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DebugPrint(( TEXT("Trace: CFaxComponent::Notify") ));
|
||
|
|
||
|
// the prop sheet count should never be negative
|
||
|
assert( QueryPropSheetCount() >= 0 );
|
||
|
|
||
|
// check to see if any property sheets are up
|
||
|
while( QueryPropSheetCount() > 0 ) {
|
||
|
DebugPrint(( TEXT("Trace: QueryPropSheetCount() %d "), QueryPropSheetCount() ));
|
||
|
// don't allow deletion
|
||
|
GlobalStringTable->PopUpMsg( NULL, IDS_PROP_SHEET_STILL_UP, TRUE, NULL );
|
||
|
}
|
||
|
|
||
|
// release the header object
|
||
|
HRESULT hr = m_pConsole->SetHeader( NULL );
|
||
|
assert( SUCCEEDED( hr ));
|
||
|
|
||
|
if( m_pUnknown != NULL ) {
|
||
|
m_pUnknown->Release();
|
||
|
m_pUnknown = NULL;
|
||
|
}
|
||
|
|
||
|
if( m_pConsole != NULL ) {
|
||
|
m_pConsole->Release();
|
||
|
m_pConsole = NULL;
|
||
|
}
|
||
|
|
||
|
if( m_pConsoleNameSpace != NULL ) {
|
||
|
m_pConsoleNameSpace->Release();
|
||
|
m_pConsoleNameSpace = NULL;
|
||
|
}
|
||
|
|
||
|
if( m_pConsoleVerb != NULL ) {
|
||
|
m_pConsoleVerb->Release();
|
||
|
m_pConsoleVerb = NULL;
|
||
|
}
|
||
|
|
||
|
if( m_pHeaderCtrl != NULL ) {
|
||
|
m_pHeaderCtrl->Release();
|
||
|
m_pHeaderCtrl = NULL;
|
||
|
}
|
||
|
|
||
|
if( m_pImageList != NULL ) {
|
||
|
m_pImageList->Release();
|
||
|
m_pImageList = NULL;
|
||
|
}
|
||
|
|
||
|
if( m_pResultData != NULL ) {
|
||
|
m_pResultData->Release();
|
||
|
m_pResultData = NULL;
|
||
|
}
|
||
|
|
||
|
if( m_pControlbar != NULL ) {
|
||
|
m_pControlbar->Release();
|
||
|
m_pControlbar = NULL;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
STDMETHODCALLTYPE
|
||
|
CFaxComponent::QueryDataObject(
|
||
|
IN MMC_COOKIE cookie,
|
||
|
IN DATA_OBJECT_TYPES type,
|
||
|
OUT LPDATAOBJECT __RPC_FAR *ppDataObject)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This method dispatches DataObjects requests to the appropriate
|
||
|
nodes using the cookie.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
cookie - the cookie for the associated node
|
||
|
type - the type of the cookie
|
||
|
ppDataobject - a pointer to the new data object is stored here
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT indicating SUCCEEDED() or FAILED()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
// DebugPrint(( TEXT("Trace: CFaxComponent::QueryDataObject") ));
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if( ppDataObject != NULL ) {
|
||
|
if( cookie == NULL ) {
|
||
|
assert( pOwner );
|
||
|
hr = pOwner->globalRoot->ResultQueryDataObject( this, cookie, type, ppDataObject );
|
||
|
} else {
|
||
|
try {
|
||
|
hr = ((CInternalNode *)cookie)->ResultQueryDataObject( this, cookie, type, ppDataObject );
|
||
|
} catch ( ... ) {
|
||
|
DebugPrint(( TEXT("Invalid Cookie: 0x%08x"), cookie ));
|
||
|
assert( FALSE ); // got passed an INVALID COOKIE!?!?!?!?
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
// bad pointer
|
||
|
assert( FALSE );
|
||
|
hr = E_POINTER;
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
STDMETHODCALLTYPE
|
||
|
CFaxComponent::GetResultViewType(
|
||
|
IN MMC_COOKIE cookie,
|
||
|
OUT LPOLESTR __RPC_FAR *ppViewType,
|
||
|
OUT long __RPC_FAR *pViewOptions)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This method dispatches GetResultViewType requests to the appropriate
|
||
|
nodes using the cookie.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
cookie - the cookie for the associated node
|
||
|
ppViewType - the viewtype
|
||
|
ppViewOptions - view options
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT indicating SUCCEEDED() or FAILED()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
assert ( ppViewType != NULL );
|
||
|
if( ppViewType == NULL ) {
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
assert ( pViewOptions != NULL );
|
||
|
if( pViewOptions == NULL ) {
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
|
||
|
if( cookie == NULL ) {
|
||
|
assert( pOwner );
|
||
|
hr = pOwner->globalRoot->ResultGetResultViewType( this, cookie, ppViewType, pViewOptions );
|
||
|
} else {
|
||
|
try {
|
||
|
hr = ((CInternalNode *)cookie)->ResultGetResultViewType( this, cookie, ppViewType, pViewOptions );
|
||
|
} catch ( ... ) {
|
||
|
DebugPrint(( TEXT("Invalid Cookie: 0x%08x"), cookie ));
|
||
|
assert( FALSE ); // got passed an INVALID COOKIE!?!?!?!?
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
STDMETHODCALLTYPE
|
||
|
CFaxComponent::GetDisplayInfo(
|
||
|
IN OUT RESULTDATAITEM __RPC_FAR *pResultDataItem)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This method dispatches DisplayInfo requests to the appropriate
|
||
|
nodes using the cookie in pResultDataItem.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pResultDataItem - struct containing information about the scope item.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT indicating SUCCEEDED() or FAILED()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
|
||
|
// DebugPrint(( TEXT("Trace: CFaxComponent::GetDisplayInfo") ));
|
||
|
|
||
|
LONG_PTR cookie;
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
assert( pResultDataItem != NULL );
|
||
|
|
||
|
if( pResultDataItem == NULL ) {
|
||
|
// oops bad pointer
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
|
||
|
cookie = pResultDataItem->lParam;
|
||
|
|
||
|
if( cookie == NULL ) {
|
||
|
// our top node
|
||
|
assert( pOwner );
|
||
|
hr = pOwner->globalRoot->ResultGetDisplayInfo(this, pResultDataItem);
|
||
|
} else {
|
||
|
// another node
|
||
|
try {
|
||
|
hr = ((CInternalNode *)cookie)->ResultGetDisplayInfo(this, pResultDataItem);
|
||
|
} catch ( ... ) {
|
||
|
DebugPrint(( TEXT("Invalid Cookie: 0x%08x"), cookie ));
|
||
|
//assert( FALSE ); // got passed an INVALID COOKIE!?!?!?!?
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
STDMETHODCALLTYPE
|
||
|
CFaxComponent::CompareObjects(
|
||
|
IN LPDATAOBJECT lpDataObjectA,
|
||
|
IN LPDATAOBJECT lpDataObjectB)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This method compares two data object to see if they correspond to
|
||
|
the same object by comparing the cookies.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
lpDataObjectA - object A
|
||
|
lpDataObjectB - object B
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT indicating S_OK or S_FALSE. E_UNEXPECTED for an error.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
CFaxDataObject * aOBJ = ExtractOwnDataObject( lpDataObjectA );
|
||
|
CFaxDataObject * bOBJ = ExtractOwnDataObject( lpDataObjectB );
|
||
|
|
||
|
if( aOBJ == NULL || bOBJ == NULL ) {
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
if( aOBJ->GetCookie() == bOBJ->GetCookie() ) {
|
||
|
return S_OK;
|
||
|
} else {
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
// Internal Methods
|
||
|
//
|
||
|
//
|
||
|
|
||
|
void
|
||
|
CFaxComponent::SetOwner(
|
||
|
CFaxComponentData * myOwner )
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Sets the Component's owner - needed for internal stuff
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
myOwner - the owner of the IComponent instance.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
assert( myOwner != NULL );
|
||
|
pOwner = myOwner;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CFaxComponent::InsertIconsIntoImageList()
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
oads the component's result pane icons into an image list
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
HRESULT indicating SUCCEEDED() or FAILED()
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
HRESULT hr = E_UNEXPECTED;
|
||
|
|
||
|
assert( pOwner != NULL );
|
||
|
assert( m_pImageList != NULL );
|
||
|
|
||
|
if( m_pImageList != NULL ) {
|
||
|
if( pOwner != NULL ) {
|
||
|
hr = pOwner->InsertIconsIntoImageList( m_pImageList );
|
||
|
}
|
||
|
}
|
||
|
return hr;
|
||
|
}
|