371 lines
8 KiB
C++
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;
|
||
|
}
|
||
|
|