mirror of https://github.com/lianthony/NT4.0
937 lines
26 KiB
937 lines
26 KiB
// pbrusdoc.cpp : implementation of the CPBDoc class
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "global.h"
|
|
#include "pbrush.h"
|
|
#include "pbrusdoc.h"
|
|
#include "pbrusfrm.h"
|
|
#include "pbrusvw.h"
|
|
#include "srvritem.h"
|
|
#include "bmobject.h"
|
|
#include "imgwnd.h"
|
|
#include "imgsuprt.h"
|
|
#include "imgbrush.h"
|
|
#include "imgbrush.h"
|
|
#include "imgwell.h"
|
|
#include "imgtools.h"
|
|
#include "imgdlgs.h"
|
|
#include "tedit.h"
|
|
#include "t_text.h"
|
|
#include "undo.h"
|
|
#include "cmpmsg.h"
|
|
#include "ferr.h"
|
|
#include "loadimag.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static CHAR BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
IMPLEMENT_DYNCREATE(CPBDoc, COleServerDoc)
|
|
|
|
#include "memtrace.h"
|
|
|
|
/***************************************************************************/
|
|
// CPBDoc
|
|
|
|
BEGIN_MESSAGE_MAP(CPBDoc, COleServerDoc)
|
|
//{{AFX_MSG_MAP(CPBDoc)
|
|
ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
|
|
ON_COMMAND(ID_FILE_SAVE, OnFileSave)
|
|
ON_COMMAND(ID_FILE_SEND, OnFileSendMail)
|
|
ON_UPDATE_COMMAND_UI(ID_FILE_SEND, OnUpdateFileSendMail)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
BEGIN_INTERFACE_MAP(CPBDoc, COleServerDoc)
|
|
INTERFACE_PART(CPBDoc, IID_IPersistStorage, PBPersistStg)
|
|
END_INTERFACE_MAP()
|
|
|
|
/***************************************************************************/
|
|
// CPBDoc construction/destruction
|
|
|
|
CPBDoc::CPBDoc()
|
|
{
|
|
m_bObjectLoaded = FALSE;
|
|
m_pBitmapObj = NULL;
|
|
m_pBitmapObjNew = NULL;
|
|
m_bNewDoc = TRUE;
|
|
m_bPaintFormat = FALSE;
|
|
m_bNonBitmapFile= FALSE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
CPBDoc::~CPBDoc()
|
|
{
|
|
if (m_pBitmapObj)
|
|
delete m_pBitmapObj;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
BOOL CPBDoc::OnNewDocument()
|
|
{
|
|
if (! Finish())
|
|
return FALSE;
|
|
|
|
m_bObjectLoaded = FALSE;
|
|
m_bNewDoc = TRUE;
|
|
m_bNonBitmapFile= FALSE;
|
|
m_sName.Empty();
|
|
|
|
if (! CreateNewDocument()
|
|
|| ! COleServerDoc::OnNewDocument())
|
|
{
|
|
if (m_pBitmapObjNew)
|
|
{
|
|
delete m_pBitmapObjNew;
|
|
m_pBitmapObjNew = 0;
|
|
}
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
BOOL CPBDoc::OnOpenDocument( const TCHAR* pszPathName )
|
|
{
|
|
m_bObjectLoaded = FALSE;
|
|
m_bNonBitmapFile= FALSE;
|
|
|
|
if (pszPathName != NULL)
|
|
{
|
|
if (theApp.m_bEmbedded)
|
|
theApp.m_bLinked = TRUE;
|
|
|
|
m_bNewDoc = FALSE;
|
|
m_sName = pszPathName;
|
|
|
|
#ifdef PCX_SUPPORT
|
|
if (! theApp.m_bPCXfile)
|
|
{
|
|
CString cStrExt = GetExtension( pszPathName );
|
|
CString cStrPCXExt;
|
|
|
|
cStrPCXExt.LoadString( IDS_EXTENSION_PCX );
|
|
|
|
// is it a PCX extension?
|
|
theApp.m_bPCXfile = ! cStrExt.CompareNoCase( cStrPCXExt );
|
|
}
|
|
#endif
|
|
|
|
// preset the file name in case of errors.
|
|
theApp.SetFileError( IDS_ERROR_OPEN, CFileException::none, pszPathName );
|
|
}
|
|
else
|
|
{
|
|
m_bNewDoc = TRUE; /* not really but we don't have a name */
|
|
m_sName.Empty();
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
if (theApp.m_bEmbedded)
|
|
TRACE( TEXT("MSPaint Open %s Document.\n"), (theApp.m_bLinked? TEXT("Linked"): TEXT("Embedded")) );
|
|
#endif
|
|
|
|
if (! CreateNewDocument())
|
|
return FALSE;
|
|
|
|
return COleServerDoc::OnOpenDocument( pszPathName );
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
BOOL CPBDoc::OnSaveDocument( const TCHAR* pszPathName )
|
|
{
|
|
ASSERT( m_pBitmapObj != NULL );
|
|
|
|
if (! Finish() || ! COleServerDoc::OnSaveDocument( pszPathName ))
|
|
return FALSE;
|
|
|
|
// Set the name if the thing doesn't have a name yet...
|
|
if (m_pBitmapObj->m_bTempName && pszPathName != NULL)
|
|
{
|
|
m_pBitmapObj->m_bTempName = FALSE;
|
|
}
|
|
|
|
m_pBitmapObj->SetDirty( FALSE );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
void CPBDoc::OnFileSaveAs()
|
|
{
|
|
CancelToolMode(FALSE);
|
|
|
|
CDocTemplate* pTemplate = GetDocTemplate();
|
|
|
|
ASSERT( pTemplate != NULL );
|
|
|
|
CString sNewName = GetPathName();
|
|
|
|
if (sNewName.IsEmpty())
|
|
{
|
|
sNewName = GetTitle();
|
|
|
|
int iBad = sNewName.FindOneOf( TEXT("#%;/\\") ); // dubious filename
|
|
|
|
if (iBad != -1)
|
|
sNewName.ReleaseBuffer( iBad );
|
|
|
|
// append the default suffix if there is one
|
|
CString strExt;
|
|
|
|
if (pTemplate->GetDocString( strExt, CDocTemplate::filterExt )
|
|
&& ! strExt.IsEmpty())
|
|
{
|
|
ASSERT( strExt[0] == TEXT('.') );
|
|
sNewName += strExt;
|
|
}
|
|
}
|
|
|
|
if (m_bNonBitmapFile)
|
|
{
|
|
sNewName = StripExtension(sNewName);
|
|
sNewName += TEXT(".bmp");
|
|
}
|
|
|
|
int iColors = m_pBitmapObj->m_nColors;
|
|
|
|
if (theApp.DoPromptFileName( sNewName, AFX_IDS_SAVEFILE,
|
|
OFN_HIDEREADONLY | OFN_PATHMUSTEXIST,
|
|
FALSE, iColors ))
|
|
{
|
|
if (iColors < 4 && iColors >= 0)
|
|
m_pBitmapObj->m_nSaveColors = iColors;
|
|
|
|
#ifdef ICO_SUPPORT
|
|
m_pBitmapObj->m_bSaveIcon = (iColors == 5);
|
|
#endif
|
|
|
|
BOOL bSavedDifferentFormat = (iColors != m_pBitmapObj->m_nColors);
|
|
|
|
if (bSavedDifferentFormat || m_pBitmapObj->IsSaveIcon())
|
|
m_pBitmapObj->Free();
|
|
|
|
if (m_pBitmapObj->IsSaveIcon())
|
|
{
|
|
m_pBitmapObj->Export( sNewName );
|
|
m_pBitmapObj->m_bSaveIcon = FALSE; // allways reset after use
|
|
m_pBitmapObj->Free();
|
|
|
|
return;
|
|
}
|
|
|
|
if (OnSaveDocument( sNewName ))
|
|
{
|
|
if (bSavedDifferentFormat)
|
|
m_pBitmapObj->ReLoadImage( this );
|
|
|
|
// Reset the title and change the document name
|
|
SetPathName( sNewName );
|
|
m_bNonBitmapFile = FALSE;
|
|
|
|
ASSERT( GetPathName() == sNewName ); // must be set
|
|
}
|
|
else
|
|
{
|
|
// be sure to delete the file
|
|
TRY
|
|
{
|
|
CFile::Remove( sNewName );
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
TRACE0( "Warning: failed to delete file after failed SaveAs\n" );
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
void CPBDoc::ReportSaveLoadException(LPCTSTR lpszPathName, CException* e,
|
|
BOOL bSaving, UINT nIDPDefault)
|
|
{
|
|
//YUCK: those dorks wrote an appwide error handler instead of using MFC's
|
|
// don't have time to rip it out right now so make sure only one shows
|
|
if(!theApp.HasSeenAFileError())
|
|
{
|
|
// the app doesn't know about the error so let mfc complain
|
|
COleServerDoc::ReportSaveLoadException(lpszPathName, e, bSaving,
|
|
nIDPDefault);
|
|
}
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
BOOL CPBDoc::CanCloseFrame( CFrameWnd* pFrame )
|
|
{
|
|
TRACE3("CanCloseFrame: %d %s %s\n",m_bNonBitmapFile, (LPCTSTR)GetTitle(), (LPCTSTR)GetPathName());
|
|
|
|
if (! Finish() || ! COleServerDoc::CanCloseFrame( pFrame ))
|
|
return FALSE;
|
|
|
|
theUndo.Flush();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
BOOL CPBDoc::SaveModified()
|
|
{
|
|
TRACE2("SaveModified\n", IsModified(), (LPCTSTR)GetPathName());
|
|
return COleServerDoc::SaveModified();
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
BOOL CPBDoc::DoSave(LPCTSTR lpszPathName, BOOL bReplace)
|
|
{
|
|
TRACE2("DoSave: file:%s bReplace=%d\n", lpszPathName, bReplace);
|
|
BOOL bRet;
|
|
if (m_bNonBitmapFile && bReplace && lpszPathName && lstrcmpi(lpszPathName, GetPathName()) == 0)
|
|
{
|
|
TRACE0("trying to save a bitmap to a non-bitmap file\n");
|
|
OnFileSaveAs();
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
|
|
bRet = COleServerDoc::DoSave(lpszPathName,bReplace);
|
|
//
|
|
// MFC sets the modified flag when user invokes OnFileSaveCopyAs.
|
|
// Then if the user exits paint the storage in the container is never
|
|
// updated because paint thinks it's already done it.
|
|
// So after saving, set the dirty flag to true
|
|
if (bRet && !lpszPathName)
|
|
{
|
|
SetModifiedFlag (TRUE);
|
|
}
|
|
return bRet;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************/
|
|
// CPBDoc server implementation
|
|
|
|
COleServerItem* CPBDoc::OnGetEmbeddedItem()
|
|
{
|
|
// OnGetEmbeddedItem is called by the framework to get the COleServerItem
|
|
// that is associated with the document. It is only called when necessary.
|
|
|
|
CPBSrvrItem* pItem = new CPBSrvrItem( this );
|
|
|
|
ASSERT_VALID( pItem );
|
|
|
|
return pItem;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
COleServerItem* CPBDoc::OnGetLinkedItem( LPCTSTR lpszItemName )
|
|
{
|
|
ASSERT_VALID( m_pBitmapObj );
|
|
|
|
// look in current list first
|
|
COleServerItem* pItem = COleServerDoc::OnGetLinkedItem( lpszItemName );
|
|
|
|
if (pItem)
|
|
return pItem;
|
|
|
|
pItem = new CPBSrvrItem( this );
|
|
|
|
ASSERT_VALID( pItem );
|
|
|
|
// return new item that matches lpszItemName
|
|
return pItem;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
// CPBDoc serialization
|
|
|
|
BOOL CPBDoc::SerializeBitmap(CArchive& ar, CBitmapObj* pBitmapCur,
|
|
CBitmapObj* pBitmapNew, BOOL bOLEObject)
|
|
{
|
|
BOOL success = FALSE;
|
|
|
|
if (ar.IsStoring())
|
|
{
|
|
// Always write the PBrush OLE format
|
|
CBitmapObj::PBResType rtType = !bOLEObject ? CBitmapObj::rtFile :
|
|
CBitmapObj::rtPBrushOLEObj;
|
|
success = pBitmapCur->WriteResource( ar.GetFile(), rtType );
|
|
}
|
|
else
|
|
{
|
|
CBitmapObj::PBResType rtType = !bOLEObject ? CBitmapObj::rtFile :
|
|
m_bPaintFormat ? CBitmapObj::rtPaintOLEObj :
|
|
CBitmapObj::rtPBrushOLEObj;
|
|
|
|
success = pBitmapNew->ReadResource( ar.GetFile(), rtType );
|
|
|
|
//
|
|
// if we cant open the file, lets try using a filter.
|
|
//
|
|
if (success)
|
|
{
|
|
m_bNonBitmapFile = FALSE;
|
|
}
|
|
else if (!bOLEObject)
|
|
{
|
|
LPBITMAPINFOHEADER lpbi;
|
|
|
|
if (lpbi = LoadDIBFromFile(theApp.GetLastFile()))
|
|
{
|
|
success = pBitmapNew->ReadResource(lpbi);
|
|
FreeDIB(lpbi);
|
|
|
|
if (success)
|
|
{
|
|
// we loaded a non .bmp file
|
|
m_bNonBitmapFile = TRUE;
|
|
// set no error
|
|
theApp.SetFileError(0, CFileException::none);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(success);
|
|
}
|
|
|
|
void CPBDoc::Serialize( CArchive& ar )
|
|
{
|
|
m_bObjectLoaded = SerializeBitmap(ar, m_pBitmapObj, m_pBitmapObjNew, FALSE);
|
|
|
|
if (!m_bObjectLoaded) // much less than ideal but oh well
|
|
{
|
|
// let mfc know so it can tidy up internally...
|
|
AfxThrowFileException(CFileException::invalidFile);
|
|
}
|
|
}
|
|
|
|
void CPBDoc::OLESerialize( CArchive& ar )
|
|
{
|
|
m_bObjectLoaded = SerializeBitmap(ar, m_pBitmapObj, m_pBitmapObjNew, TRUE);
|
|
|
|
if (!m_bObjectLoaded) // much less than ideal but oh well
|
|
{
|
|
// let mfc know so it can tidy up internally...
|
|
AfxThrowFileException(CFileException::invalidFile);
|
|
}
|
|
}
|
|
|
|
|
|
STDMETHODIMP CPBDoc::XPBPersistStg::QueryInterface(
|
|
REFIID iid, LPVOID* ppvObj)
|
|
{
|
|
METHOD_PROLOGUE_EX(CPBDoc, PBPersistStg)
|
|
return pThis->ExternalQueryInterface(&iid, ppvObj);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CPBDoc::XPBPersistStg::AddRef()
|
|
{
|
|
METHOD_PROLOGUE_EX(CPBDoc, PBPersistStg)
|
|
return pThis->ExternalAddRef();
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CPBDoc::XPBPersistStg::Release()
|
|
{
|
|
METHOD_PROLOGUE_EX(CPBDoc, PBPersistStg)
|
|
return pThis->ExternalRelease();
|
|
}
|
|
|
|
STDMETHODIMP CPBDoc::XPBPersistStg::GetClassID(LPCLSID pclsid)
|
|
{
|
|
// Always return the CLSID for PBrush
|
|
*pclsid = CLSID_PaintBrush;
|
|
return(NOERROR);
|
|
}
|
|
|
|
STDMETHODIMP CPBDoc::XPBPersistStg::IsDirty()
|
|
{
|
|
METHOD_PROLOGUE_EX(CPBDoc, PBPersistStg)
|
|
return(pThis->m_xPersistStorage.IsDirty());
|
|
}
|
|
|
|
STDMETHODIMP CPBDoc::XPBPersistStg::InitNew(LPSTORAGE pstg)
|
|
{
|
|
METHOD_PROLOGUE_EX(CPBDoc, PBPersistStg)
|
|
return(pThis->m_xPersistStorage.InitNew(pstg));
|
|
}
|
|
|
|
STDMETHODIMP CPBDoc::XPBPersistStg::Load(LPSTORAGE pstg)
|
|
{
|
|
METHOD_PROLOGUE_EX(CPBDoc, PBPersistStg)
|
|
return(pThis->m_xPersistStorage.Load(pstg));
|
|
}
|
|
|
|
STDMETHODIMP CPBDoc::XPBPersistStg::Save(LPSTORAGE pstg, BOOL bSameAsLoad)
|
|
{
|
|
METHOD_PROLOGUE_EX(CPBDoc, PBPersistStg)
|
|
return(pThis->m_xPersistStorage.Save(pstg, bSameAsLoad));
|
|
}
|
|
|
|
STDMETHODIMP CPBDoc::XPBPersistStg::SaveCompleted(LPSTORAGE pstg)
|
|
{
|
|
METHOD_PROLOGUE_EX(CPBDoc, PBPersistStg)
|
|
return(pThis->m_xPersistStorage.SaveCompleted(pstg));
|
|
}
|
|
|
|
STDMETHODIMP CPBDoc::XPBPersistStg::HandsOffStorage()
|
|
{
|
|
METHOD_PROLOGUE_EX(CPBDoc, PBPersistStg)
|
|
return(pThis->m_xPersistStorage.HandsOffStorage());
|
|
}
|
|
|
|
|
|
#define NO_CPP_EXCEPTION(x) x
|
|
static const TCHAR szOle10Native[] = TEXT("\1Ole10Native");
|
|
static const TCHAR szOle10ItemName[] = TEXT("\1Ole10ItemName");
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Helpers for saving to IStorage based files
|
|
// (these are used in the 'docfile' implementation as well as for servers)
|
|
|
|
static const TCHAR szContents[] = TEXT("Contents");
|
|
|
|
void CPBDoc::SaveToStorage(CObject* pObject)
|
|
{
|
|
ASSERT(m_lpRootStg != NULL);
|
|
|
|
// create Contents stream
|
|
COleStreamFile file;
|
|
CFileException fe;
|
|
if (!file.CreateStream(m_lpRootStg, szOle10Native,
|
|
CFile::modeWrite|CFile::shareExclusive|CFile::modeCreate, &fe))
|
|
{
|
|
AfxThrowFileException(fe.m_cause, fe.m_lOsError);
|
|
}
|
|
|
|
// save to Contents stream
|
|
CArchive saveArchive(&file, CArchive::store | CArchive::bNoFlushOnDelete);
|
|
saveArchive.m_pDocument = this;
|
|
saveArchive.m_bForceFlat = FALSE;
|
|
|
|
TRY
|
|
{
|
|
// save the contents
|
|
if (pObject != NULL)
|
|
pObject->Serialize(saveArchive);
|
|
else
|
|
OLESerialize(saveArchive);
|
|
saveArchive.Close();
|
|
file.Close();
|
|
|
|
if (pObject != NULL)
|
|
{
|
|
if (file.CreateStream(m_lpRootStg, szOle10ItemName,
|
|
CFile::modeWrite|CFile::shareExclusive|CFile::modeCreate, &fe))
|
|
{
|
|
LPCTSTR szItemName;
|
|
DWORD dwLen;
|
|
CString strItemName = ((CPBSrvrItem*)pObject)->GetItemName();
|
|
|
|
if (strItemName.IsEmpty())
|
|
{
|
|
szItemName = TEXT("");
|
|
dwLen = 1;
|
|
}
|
|
else
|
|
{
|
|
szItemName = strItemName;
|
|
dwLen = lstrlen(szItemName) + 1;
|
|
}
|
|
|
|
file.Write( &dwLen, sizeof( dwLen ));
|
|
file.Write( &szItemName, dwLen);
|
|
|
|
file.Close();
|
|
}
|
|
}
|
|
|
|
SCODE sc;
|
|
|
|
// Always write the CLSID for PBrush
|
|
sc = WriteClassStg(m_lpRootStg, CLSID_PaintBrush);
|
|
if (sc != NOERROR)
|
|
AfxThrowOleException(sc);
|
|
|
|
sc = WriteFmtUserTypeStg(m_lpRootStg, RegisterClipboardFormat(TEXT("PBrush")),
|
|
TEXT("PBrush"));
|
|
if (sc != NOERROR)
|
|
AfxThrowOleException(sc);
|
|
|
|
// commit the root storage
|
|
sc = m_lpRootStg->Commit(STGC_ONLYIFCURRENT);
|
|
if (sc != NOERROR)
|
|
AfxThrowOleException(sc);
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
file.Abort(); // will not throw an exception
|
|
CommitItems(FALSE); // abort save in progress
|
|
NO_CPP_EXCEPTION(saveArchive.Abort());
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
|
|
void CPBDoc::LoadFromStorage()
|
|
{
|
|
ASSERT(m_lpRootStg != NULL);
|
|
|
|
// open Contents stream
|
|
COleStreamFile file;
|
|
CFileException fe;
|
|
if (file.OpenStream(m_lpRootStg, szOle10Native,
|
|
CFile::modeReadWrite|CFile::shareExclusive, &fe))
|
|
{
|
|
m_bPaintFormat = FALSE;
|
|
}
|
|
else if (file.OpenStream(m_lpRootStg, szContents,
|
|
CFile::modeReadWrite|CFile::shareExclusive, &fe))
|
|
{
|
|
m_bPaintFormat = TRUE;
|
|
}
|
|
else
|
|
{
|
|
AfxThrowFileException(fe.m_cause, fe.m_lOsError);
|
|
}
|
|
|
|
|
|
// load it with CArchive (loads from Contents stream)
|
|
CArchive loadArchive(&file, CArchive::load | CArchive::bNoFlushOnDelete);
|
|
loadArchive.m_pDocument = this;
|
|
loadArchive.m_bForceFlat = FALSE;
|
|
|
|
TRY
|
|
{
|
|
OLESerialize(loadArchive); // load main contents
|
|
loadArchive.Close();
|
|
file.Close();
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
file.Abort(); // will not throw an exception
|
|
DeleteContents(); // removed failed contents
|
|
NO_CPP_EXCEPTION(loadArchive.Abort());
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
|
|
/***************************************************************************/
|
|
// CPBDoc diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CPBDoc::AssertValid() const
|
|
{
|
|
COleServerDoc::AssertValid();
|
|
}
|
|
|
|
void CPBDoc::Dump(CDumpContext& dc) const
|
|
{
|
|
COleServerDoc::Dump(dc);
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
/***************************************************************************/
|
|
// CPBDoc commands
|
|
|
|
BOOL CPBDoc::CreateNewDocument()
|
|
{
|
|
CBitmapObj* pBitmapObj = NULL;
|
|
UINT idsType;
|
|
|
|
pBitmapObj = new CBitmapObj;
|
|
pBitmapObj->MakeEmpty();
|
|
idsType = IDCS_BITMAP;
|
|
|
|
if (! pBitmapObj)
|
|
return FALSE;
|
|
|
|
m_pBitmapObjNew = pBitmapObj;
|
|
|
|
pBitmapObj->m_bTempName = m_bNewDoc;
|
|
pBitmapObj->m_bDirty = FALSE;
|
|
|
|
theUndo.Flush();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
BOOL CPBDoc::Finish()
|
|
{
|
|
CImgTool* pImgTool = CImgTool::GetCurrent();
|
|
|
|
if (pImgTool != NULL && CImgTool::GetCurrentID() == IDMX_TEXTTOOL)
|
|
{
|
|
POSITION pos = GetFirstViewPosition();
|
|
|
|
((CTextTool*)pImgTool)->CloseTextTool( ((CPBView*)GetNextView( pos ))->m_pImgWnd );
|
|
}
|
|
|
|
CommitSelection( FALSE );
|
|
|
|
if (m_pBitmapObj == NULL)
|
|
return TRUE;
|
|
|
|
if (! m_pBitmapObj->SaveResource( TRUE ))
|
|
return FALSE;
|
|
|
|
if (m_pBitmapObj->IsDirty())
|
|
{
|
|
SetModifiedFlag();
|
|
|
|
if (theApp.m_bEmbedded)
|
|
NotifyChanged();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
BOOL CPBDoc::SaveTheDocument()
|
|
{
|
|
if (IsModified() || m_bNonBitmapFile)
|
|
OnFileSave();
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
|
|
void CPBDoc::OnFileSave()
|
|
{
|
|
CancelToolMode(FALSE);
|
|
|
|
DWORD dwAttrib = GetFileAttributes(m_strPathName);
|
|
//
|
|
// we only save .bmp files so if we loaded from a non .bmp file
|
|
// dont offer to save to the same filename.
|
|
//
|
|
if (!m_bNonBitmapFile && !(dwAttrib & FILE_ATTRIBUTE_READONLY))
|
|
{
|
|
const BOOL bReplace = TRUE; // Change this flag to inhibit overwrites
|
|
CString newName = m_strPathName;
|
|
if (newName.IsEmpty())
|
|
{
|
|
CDocTemplate* pTemplate = GetDocTemplate();
|
|
ASSERT(pTemplate != NULL);
|
|
|
|
newName = m_strPathName;
|
|
if (bReplace && newName.IsEmpty())
|
|
{
|
|
newName = m_strTitle;
|
|
#ifndef _MAC
|
|
if (newName.GetLength() > 8)
|
|
newName.ReleaseBuffer(8);
|
|
// check for dubious filename
|
|
int iBad = newName.FindOneOf(TEXT(" #%;/\\"));
|
|
#else
|
|
int iBad = newName.FindOneOf(TEXT(":"));
|
|
#endif
|
|
if (iBad != -1)
|
|
newName.ReleaseBuffer(iBad);
|
|
|
|
#ifndef _MAC
|
|
// append the default suffix if there is one
|
|
CString strExt;
|
|
if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&
|
|
!strExt.IsEmpty())
|
|
{
|
|
ASSERT(strExt[0] == TEXT('.'));
|
|
newName += strExt;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if (!AfxGetApp()->DoPromptFileName(newName,
|
|
bReplace ? AFX_IDS_SAVEFILE : AFX_IDS_SAVEFILECOPY,
|
|
OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, FALSE, pTemplate))
|
|
return; // don't even attempt to save
|
|
}
|
|
|
|
BeginWaitCursor();
|
|
if (!OnSaveDocument(newName))
|
|
{
|
|
if (m_strPathName.IsEmpty())
|
|
{
|
|
// be sure to delete the file
|
|
TRY
|
|
{
|
|
CFile::Remove(newName);
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
TRACE0("Warning: failed to delete file after failed SaveAs.\n");
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
EndWaitCursor();
|
|
return;
|
|
}
|
|
|
|
// reset the title and change the document name
|
|
if (bReplace)
|
|
SetPathName(newName);
|
|
|
|
EndWaitCursor();
|
|
}
|
|
else
|
|
OnFileSaveAs();
|
|
}
|
|
|
|
void CPBDoc::OnShowControlBars(CFrameWnd *pFrame, BOOL bShow)
|
|
{
|
|
POSITION pos = GetFirstViewPosition();
|
|
CPBView* pView = (CPBView*)(GetNextView( pos ));
|
|
|
|
if ( bShow )
|
|
{
|
|
pView->SetTools();
|
|
if ( pView->m_pImgWnd &&
|
|
pView->m_pImgWnd->GetZoom() > 1 )
|
|
pView->ShowThumbNailView();
|
|
}
|
|
else
|
|
{
|
|
pView->HideThumbNailView();
|
|
}
|
|
|
|
// BUGBUG: What I should do is add an OnShowControlBars member to
|
|
// CImgTool, but that's too big a change for right now
|
|
if (CImgTool::GetCurrentID() == IDMX_TEXTTOOL)
|
|
{
|
|
CTextTool* pTextTool = (CTextTool*)CImgTool::GetCurrent();
|
|
pTextTool->OnShowControlBars(bShow);
|
|
}
|
|
|
|
COleServerDoc::OnShowControlBars(pFrame,bShow);
|
|
}
|
|
|
|
class CCB : public CControlBar
|
|
{
|
|
public:
|
|
void ForceDelayed(void);
|
|
};
|
|
|
|
void CCB::ForceDelayed(void)
|
|
{
|
|
if (!this)
|
|
{
|
|
return;
|
|
}
|
|
|
|
BOOL bVis = GetStyle() & WS_VISIBLE;
|
|
UINT swpFlags = 0;
|
|
if ((m_nStateFlags & delayHide) && bVis)
|
|
swpFlags = SWP_HIDEWINDOW;
|
|
else if ((m_nStateFlags & delayShow) && !bVis)
|
|
swpFlags = SWP_SHOWWINDOW;
|
|
m_nStateFlags &= ~(delayShow|delayHide);
|
|
if (swpFlags != 0)
|
|
{
|
|
SetWindowPos(NULL, 0, 0, 0, 0, swpFlags|
|
|
SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
|
|
}
|
|
}
|
|
|
|
class CFW : public CFrameWnd
|
|
{
|
|
public:
|
|
void ForceDelayed(void);
|
|
};
|
|
|
|
void CFW::ForceDelayed(void)
|
|
{
|
|
if (!this)
|
|
{
|
|
return;
|
|
}
|
|
|
|
POSITION pos = m_listControlBars.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
// show/hide the next control bar
|
|
CCB* pBar = (CCB*)m_listControlBars.GetNext(pos);
|
|
pBar->ForceDelayed();
|
|
}
|
|
}
|
|
|
|
class COIPF : public COleIPFrameWnd
|
|
{
|
|
public:
|
|
void ForceDelayed(void);
|
|
};
|
|
|
|
void COIPF::ForceDelayed(void)
|
|
{
|
|
if (!this)
|
|
{
|
|
return;
|
|
}
|
|
|
|
((CFW*)m_pMainFrame)->ForceDelayed();
|
|
((CFW*)m_pDocFrame )->ForceDelayed();
|
|
}
|
|
|
|
void CPBDoc::OnDeactivateUI(BOOL bUndoable)
|
|
{
|
|
COleServerDoc::OnDeactivateUI(bUndoable);
|
|
|
|
POSITION pos = GetFirstViewPosition();
|
|
CPBView* pView = (CPBView*)(GetNextView( pos ));
|
|
|
|
if (pView != NULL)
|
|
{
|
|
#if 0
|
|
// Deselect any other tool modes (Particularly text!)
|
|
if ( g_pImgToolWnd && g_pImgToolWnd->m_hWnd &&
|
|
IsWindow(g_pImgToolWnd->m_hWnd) )
|
|
{
|
|
CImgTool::Select(IDMB_ARROW);
|
|
}
|
|
#endif
|
|
|
|
pView->HideThumbNailView();
|
|
|
|
COIPF* pFrame = (COIPF*)m_pInPlaceFrame;
|
|
pFrame->ForceDelayed();
|
|
}
|
|
}
|
|
|
|
//
|
|
// We override OnUpdateDocument to ignore the modified flag. Certain MFC paths
|
|
// set the modified flag inappropriately, causing data loss.
|
|
BOOL CPBDoc::OnUpdateDocument ()
|
|
{
|
|
// save a server document -> update
|
|
TRY
|
|
{
|
|
SaveEmbedding();
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
AfxMessageBox(AFX_IDP_FAILED_TO_UPDATE);
|
|
#ifndef _AFX_OLD_EXCEPTIONS
|
|
e->Delete();
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
return TRUE;
|
|
}
|