windows-nt/Source/XPSP1/NT/printscan/fax/admin/faxadmin/faxdataobj.cpp
2020-09-26 16:20:57 +08:00

371 lines
8 KiB
C++

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
faxdataobj.cpp
Abstract:
This file contains my implementation of IDataObject.
Environment:
WIN32 User Mode
Author:
Darwin Ouyang (t-darouy) 30-Sept-1997
--*/
// FaxDataObj.cpp : Implementation of CFaxDataObject
#include "stdafx.h"
#include "faxadmin.h"
#include "faxdataobj.h"
#include "faxstrt.h"
#include "inode.h"
#pragma hdrstop
//
// This is the minimum set of clipboard formats we must implement.
// MMC uses these to get necessary information from our snapin about
// our nodes.
//
UINT CFaxDataObject::s_cfInternal = 0;
UINT CFaxDataObject::s_cfDisplayName = 0;
UINT CFaxDataObject::s_cfNodeType = 0;
UINT CFaxDataObject::s_cfSnapinClsid = 0;
#ifdef DEBUG
// DataObject Count
long CFaxDataObject::DataObjectCount = 0;
#endif
#define CF_SNAPIN_INTERNAL L"MMC_SNAPIN_INTERNAL"
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Constructor and destructor
//
//
CFaxDataObject::CFaxDataObject()
/*++
Routine Description:
Constructor.
Arguments:
None.
Return Value:
None.
--*/
{
// DebugPrint(( TEXT("Trace: CFaxDataObject::CFaxDataObject") ));
m_ulCookie = 0;
m_Context = CCT_UNINITIALIZED;
pOwner = NULL;
#ifdef DEBUG
InterlockedIncrement( &DataObjectCount );
// DebugPrint(( TEXT("FaxDataObject %d created."), DataObjectCount ));
#endif
// These are the clipboard formats that we must supply at a minimum.
// mmc.h actually defined these. We can make up our own to use for
// other reasons. We don't need any others at this time.
s_cfInternal = RegisterClipboardFormat(CF_SNAPIN_INTERNAL);
s_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
s_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
s_cfSnapinClsid = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
}
CFaxDataObject::~CFaxDataObject()
/*++
Routine Description:
Destructor.
Arguments:
None.
Return Value:
None.
--*/
{
// DebugPrint(( TEXT("Trace: CFaxDataObject::~CFaxDataObject") ));
#ifdef DEBUG
if( DataObjectCount <= 1 ) {
// DebugPrint(( TEXT(" ** All FaxDataObjects destroyed"), DataObjectCount ));
}
InterlockedDecrement( &DataObjectCount );
#endif
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// CFaxDataObject - IDataObject implementation
//
//
HRESULT
STDMETHODCALLTYPE
CFaxDataObject::GetDataHere(
/* [unique] */ IN FORMATETC __RPC_FAR *pFormatEtc,
IN OUT STGMEDIUM __RPC_FAR *pMedium)
/*++
Routine Description:
Writes the requested data to the specified medium, also dispatches
the data request to the owning node's getdatahere for custom formats.
Arguments:
pFormatEtc - the format
pMedium - the medium
Return Value:
HRESULT indicating SUCCEEDED() or FAILED()
--*/
{
// DebugPrint(( TEXT("Trace: CFaxDataObject::GetDataHere") ));
HRESULT hr = S_OK;
const CLIPFORMAT cf = pFormatEtc->cfFormat;
IStream *pstm = NULL;
assert(pOwner != NULL );
pMedium->pUnkForRelease = NULL; // by OLE spec
do {
hr = CreateStreamOnHGlobal(pMedium->hGlobal, FALSE, &pstm);
if( FAILED( hr ) ) {
break;
}
if(cf == s_cfDisplayName) {
//DebugPrint(( TEXT("Trace: CFaxDataObject Format DisplayName") ));
hr = _WriteDisplayName(pstm);
} else if(cf == s_cfInternal) {
//DebugPrint(( TEXT("Trace: CFaxDataObject Format Internal") ));
hr = _WriteInternal(pstm);
} else if(cf == s_cfNodeType) {
//DebugPrint(( TEXT("Trace: CFaxDataObject Format Node Type UUID") ));
hr = _WriteNodeType(pstm);
} else if(cf == s_cfSnapinClsid) {
//DebugPrint(( TEXT("Trace: CFaxDataObject Format Snapin CLSID") ));
hr = _WriteClsid(pstm);
} else {
// if we're attached to a node
if(pOwner != NULL ) {
// this is a node specific dataobject - handle node specific data formats
hr = pOwner->DataObjectGetDataHere( pFormatEtc, pstm );
// not a known data type!
if( FAILED(hr) ) {
assert( FALSE );
break;
}
} else {
// this is a snapin data object
// we don't support this clipboard format
assert( FALSE );
hr = DV_E_FORMATETC;
}
}
} while(0);
if(pstm) {
pstm->Release();
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Member Functions
//
//
void
CFaxDataObject::SetOwner(
CInternalNode* pO )
/*++
Routine Description:
Initialization function to set the owner of the dataobject and
register additional clipboard formats
Arguments:
pO - owner node
Return Value:
None.
--*/
{
assert( pO != NULL );
pOwner = pO;
// register node specific data types now
if( pOwner != NULL ) {
pOwner->DataObjectRegisterFormats();
}
}
HRESULT
CFaxDataObject::_WriteNodeType(
IStream *pstm)
/*++
Routine Description:
Write this node's GUID type to the stream [pstm].
Arguments:
pstm - the target stream
Return Value:
None.
--*/
{
HRESULT hr;
const GUID *pguid = NULL;
assert( pOwner != NULL );
if( pOwner == NULL ) {
return E_UNEXPECTED;
}
pguid = pOwner->GetNodeGUID();
hr = pstm->Write((PVOID) pguid, sizeof(GUID), NULL);
return hr;
}
HRESULT
CFaxDataObject::_WriteDisplayName(
IStream *pstm)
/*++
Routine Description:
Write this node's display name to the stream [pstm].
Arguments:
pstm - the target stream
Return Value:
None.
--*/
{
HRESULT hr = S_OK;
LPWSTR pwszName;
assert( pOwner != NULL );
if( pOwner == NULL ) {
return E_UNEXPECTED;
}
pwszName = pOwner->GetNodeDisplayName();
ULONG ulSizeofName = lstrlen(pwszName);
ulSizeofName++; // count null
ulSizeofName *= sizeof(WCHAR);
hr = pstm->Write(pwszName, ulSizeofName, NULL);
return hr;
}
HRESULT
CFaxDataObject::_WriteInternal(
IStream *pstm)
/*++
Routine Description:
Write this object's data in the private clipboard format
to the stream [pstm].
Arguments:
pstm - the target stream
Return Value:
None.
--*/
{
HRESULT hr;
CFaxDataObject *pThis = this;
hr = pstm->Write(&pThis, sizeof (CFaxDataObject *), NULL);
return hr;
}
HRESULT
CFaxDataObject::_WriteClsid(
IStream *pstm)
/*++
Routine Description:
Write the snapin's CLSID
to the stream [pstm].
Arguments:
pstm - the target stream
Return Value:
None.
--*/
{
HRESULT hr;
hr = pstm->Write(&CLSID_FaxSnapin, sizeof CLSID_FaxSnapin, NULL);
return hr;
}