///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
#pragma unmanaged
#include "eattach.h"
#include "StringStream.h"
#include "CharBuffer.h"
#include "CharsStorage.h"
#include "guard.h"
#include "Richedit.h"
#include "Richole.h"
#include "RCPtrDef.h"
template RCPtr;
EAttach::EAttach( LPATTACH lpAttach ) : MAPIProp( lpAttach )
{
if ( lpAttach == NULL )
{
Guard::ThrowArgumentNullException( "lpAttach" );
}
_lpAttach = lpAttach;
}
EAttach::~EAttach()
{
_lpAttach = NULL;
}
CharBufferSPtr EAttach::ReadToEnd() const
{
LPSTREAM pStream = NULL;
HRESULT hr =
_lpAttach->OpenProperty( (int)PR_ATTACH_DATA_BIN, (LPIID)&IID_IStream, 0, 0, (LPUNKNOWN *)&pStream );
if ( hr == S_OK )
{
StringStream stream( pStream );
stream.ReadToEnd();
CharBufferSPtr buffer = stream.GetBuffer();
if ( !buffer.IsNull() && buffer->Length() != 0 )
{
return buffer;
}
}
return CharBufferSPtr( NULL );
}
LPMESSAGE EAttach::OpenMessage() const
{
LPMESSAGE pmsgAttach = NULL;
HRESULT hr = _lpAttach->OpenProperty ( (int)PR_ATTACH_DATA_OBJ, &IID_IMessage, 0L, 0, (LPUNKNOWN*)&pmsgAttach );
if ( hr == S_OK )
{
return pmsgAttach;
}
return NULL;
}
template class ComPtr
{
public:
ComPtr()
{
pointee = NULL;
}
~ComPtr()
{
if ( pointee != NULL )
{
pointee->Release();
}
}
T operator->() const
{
return pointee;
}
T getI() const
{
return pointee;
}
T* get()
{
return &pointee;
}
bool IsNull() const
{
return pointee == NULL;
}
private:
T pointee;
};
void EAttach::InsertOLEIntoRTF( HWND hwnd, int pos ) const
{
ComPtr pRichEditOle;
::SendMessage( hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)pRichEditOle.get() );
if ( pRichEditOle.IsNull() )
{
Guard::ThrowArgumentNullException( "Cannot get IRichEditOle interface for Rich edit control" );
}
ComPtr pStorage;
HRESULT hr = _lpAttach->OpenProperty ( (int)PR_ATTACH_DATA_OBJ, &IID_IStorage, 0L, 0, (LPUNKNOWN*)pStorage.get() );
Guard::CheckHR( hr );
if ( pStorage.IsNull() )
{
Guard::ThrowArgumentNullException( "Cannot open property PR_ATTACH_DATA_OBJ to get IStorage" );
}
ComPtr clientSite;
hr = pRichEditOle->GetClientSite( clientSite.get() );
Guard::CheckHR( hr );
if ( clientSite.IsNull() )
{
Guard::ThrowArgumentNullException( "Cannot get IOleClientSite from rich edit control" );
}
ComPtr ppvObj;
hr = OleLoad( pStorage.getI(), IID_IOleObject, clientSite.getI(), (LPVOID*)ppvObj.get() );
Guard::CheckHR( hr );
if ( ppvObj.IsNull() )
{
Guard::ThrowArgumentNullException( "Cannot get IOleObject" );
}
CLSID clsid;
hr = ppvObj->GetUserClassID(&clsid);
Guard::CheckHR( hr );
REOBJECT reobject;
ZeroMemory(&reobject, sizeof(REOBJECT));
reobject.cbStruct = sizeof(REOBJECT);
reobject.clsid = clsid;
reobject.cp = pos;
reobject.dvaspect = DVASPECT_CONTENT;
reobject.dwFlags = REO_STATIC | REO_GETMETAFILE;
reobject.dwUser = 0;
reobject.poleobj = ppvObj.getI();
reobject.polesite = clientSite.getI();
reobject.pstg = pStorage.getI();
SIZEL sizel;
sizel.cx = sizel.cy = 0;
reobject.sizel = sizel;
hr = pRichEditOle->InsertObject( &reobject );
Guard::CheckHR( hr );
}