📄 document.cpp
字号:
if (!PrinterSetup(NULL, TRUE))
return DOCERR_COULDNOTOPEN;
//Go create an initial page.
m_pPG->PageInsert(0);
}
else
{
//Can't change an already saved configuration
m_fPrintSetup=FALSE;
}
FDirtySet(FALSE);
return DOCERR_NONE;
}
/*
* CPatronDoc::Save
*
* Purpose:
* Writes the file to a known filename, requiring that the user
* has previously used FileOpen or FileSaveAs in order to have
* a filename.
*
* Parameters:
* uType UINT indicating the type of file the user
* requested to save in the File Save As dialog.
* pszFile LPTSTR under which to save. If NULL, use the
* current name.
*
* Return Value:
* UINT An error value from DOCERR_*
*/
UINT CPatronDoc::Save(UINT uType, LPTSTR pszFile)
{
HRESULT hr;
LPSTORAGE pIStorage;
//Save or Save As with the same file is just a commit.
if (NULL==pszFile
|| (NULL!=pszFile && 0==lstrcmpi(pszFile, m_szFile)))
{
WriteFmtUserTypeStg(m_pIStorage, m_cf
, PSZ(IDS_CLIPBOARDFORMAT));
//Insure pages are up to date.
m_pPG->StorageUpdate(FALSE);
//Commit everyting
m_pIStorage->Commit(STGC_DEFAULT);
FDirtySet(FALSE);
return DOCERR_NONE;
}
/*
* When we're given a name, open the storage, creating it new
* if it does not exist or overwriting the old one. Then CopyTo
* from the current to the new, Commit the new, Release the old.
*/
hr=StgCreateDocfile(pszFile, STGM_TRANSACTED | STGM_READWRITE
| STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &pIStorage);
if (FAILED(hr))
return DOCERR_COULDNOTOPEN;
WriteClassStg(pIStorage, CLSID_PatronPages);
WriteFmtUserTypeStg(pIStorage, m_cf, PSZ(IDS_CLIPBOARDFORMAT));
//Insure all pages are up-to-date.
m_pPG->StorageUpdate(TRUE);
//This also copies the CLSID we stuff in here on file creation.
hr=m_pIStorage->CopyTo(NULL, NULL, NULL, pIStorage);
if (FAILED(hr))
{
SCODE sc;
pIStorage->Release();
sc=GetScode(hr);
/*
* If we failed because of low memory, use IRootStorage
* to switch into the new file.
*/
if (E_OUTOFMEMORY==sc)
{
LPROOTSTORAGE pIRoot;
//Delete file we already created
DeleteFile(pszFile);
if (FAILED(m_pIStorage->QueryInterface
(IID_IRootStorage, (PPVOID)&pIRoot)))
return DOCERR_WRITEFAILURE;
#ifdef WIN32ANSI
OLECHAR szTemp[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, pszFile, -1, szTemp, MAX_PATH);
hr=pIRoot->SwitchToFile(szTemp);
#else
hr=pIRoot->SwitchToFile(pszFile);
#endif
pIRoot->Release();
if (FAILED(hr))
return DOCERR_WRITEFAILURE;
//If successful, the Commit below finishes the save.
pIStorage=m_pIStorage;
m_pIStorage->AddRef(); //Matches Release below
}
}
if (m_fRename)
Rename(pszFile); //Update caption bar.
pIStorage->Commit(STGC_DEFAULT);
/*
* Revert changes on the original storage. If this was a temp
* file, it's deleted since we used STGM_DELETEONRELEASE.
*/
m_pIStorage->Release();
//Make this new storage current
m_pIStorage=pIStorage;
m_pPG->StorageSet(pIStorage, TRUE, FALSE);
FDirtySet(FALSE);
return DOCERR_NONE;
}
/*
* CPatronDoc::Clip
*
* Purpose:
* Places a private format, a metafile, and a bitmap of the display
* on the clipboard, optionally implementing Cut by deleting the
* data in the current window after rendering.
*
* Parameters:
* hWndFrame HWND of the main window.
* fCut BOOL indicating cut (TRUE) or copy (FALSE).
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
*/
BOOL CPatronDoc::Clip(HWND hWndFrame, BOOL fCut)
{
if (NULL==m_pPG)
return FALSE;
return m_pPG->TenantClip(fCut);
}
/*
* CPatronDoc::Paste
*
* Purpose:
* Retrieves the private data format from the clipboard and sets it
* to the current figure in the editor window.
*
* Note that if this function is called, then the clipboard format
* is available because the Paste menu item is only enabled if the
* format is present.
*
* Parameters:
* hWndFrame HWND of the main window.
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
*/
BOOL CPatronDoc::Paste(HWND hWndFrame)
{
LPDATAOBJECT pIDataObject;
BOOL fRet=FALSE;
FORMATETC fe;
TENANTTYPE tType;
if (NULL==m_pPG)
return FALSE;
if (FAILED(OleGetClipboard(&pIDataObject)))
return FALSE;
//Go get type and format we *can* paste, then actually paste it.
if (FQueryPasteFromData(pIDataObject, &fe, &tType))
{
fRet=PasteFromData(pIDataObject, &fe, tType, NULL
, 0L, TRUE);
}
pIDataObject->Release();
return fRet;
}
/*
* CPatronDoc::FQueryPaste
*
* Purpose:
* Determines if we can paste data from the clipboard.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if data is available, FALSE otherwise.
*/
BOOL CPatronDoc::FQueryPaste(void)
{
LPDATAOBJECT pIDataObject;
BOOL fRet;
if (FAILED(OleGetClipboard(&pIDataObject)))
return FALSE;
fRet=FQueryPasteFromData(pIDataObject, NULL, NULL);
fRet |= FQueryPasteLinkFromData(pIDataObject, NULL, NULL);
pIDataObject->Release();
return fRet;
}
/*
* CPatronDoc::PasteSpecial
*
* Purpose:
* Retrieves a specific data format from the clipboard and sends
* it to the editor window appropriately.
*
* Note that if this function is called, then the appropriate
* format is available because the Paste menu item is only
* enabled if the format is present.
*
* Parameters:
* hWndFrame HWND of the main window
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
*/
BOOL CPatronDoc::PasteSpecial(HWND hWndFrame)
{
OLEUIPASTESPECIAL ps;
OLEUIPASTEENTRY rgPaste[6];
UINT rgcf[1]; //For ps.m_arrLinkTypes
DWORD dwData=0;
UINT uTemp;
BOOL fRet=FALSE;
if (NULL==m_pPG)
return FALSE;
memset(&ps, 0, sizeof(ps));
if (FAILED(OleGetClipboard(&ps.lpSrcDataObj)))
return FALSE;
ps.cbStruct=sizeof(ps);
ps.hWndOwner=hWndFrame;
ps.dwFlags=PSF_SELECTPASTE;
ps.arrPasteEntries=rgPaste;
//Set up Paste Special descriptor arrays.
SETDefFormatEtc(rgPaste[0].fmtetc, m_cf, TYMED_HGLOBAL);
rgPaste[0].lpstrFormatName=PSZ(IDS_CLIPBOARDFORMAT);
rgPaste[0].lpstrResultText=PSZ(IDS_PASTEASPATRON);
rgPaste[0].dwFlags=OLEUIPASTE_PASTEONLY;
//Embedded objects can be iconic displays if the user wants.
SETDefFormatEtc(rgPaste[1].fmtetc, m_cfEmbeddedObject
, TYMED_ISTORAGE);
rgPaste[1].lpstrFormatName=PSZ(IDS_PASTEOBJECT);
rgPaste[1].lpstrResultText=PSZ(IDS_PASTEASOBJECT);
/*
* CAUTION: Use OLEUI_PASTE with embedded objects or else
* this item will not show up in the dialog. I learned this the
* hard way (that is, after about 6 hours of pulling hair!).
*/
rgPaste[1].dwFlags=OLEUIPASTE_PASTE | OLEUIPASTE_ENABLEICON;
SETDefFormatEtc(rgPaste[2].fmtetc,CF_METAFILEPICT,TYMED_MFPICT);
rgPaste[2].lpstrFormatName=PSZ(IDS_PASTEMETAFILE);
rgPaste[2].lpstrResultText=PSZ(IDS_PASTEASMETAFILE);
rgPaste[2].dwFlags=OLEUIPASTE_PASTEONLY;
SETDefFormatEtc(rgPaste[3].fmtetc, CF_DIB, TYMED_HGLOBAL);
rgPaste[3].lpstrFormatName=PSZ(IDS_PASTEDIB);
rgPaste[3].lpstrResultText=PSZ(IDS_PASTEASDIB);
rgPaste[3].dwFlags=OLEUIPASTE_PASTEONLY;
SETDefFormatEtc(rgPaste[4].fmtetc, CF_BITMAP, TYMED_GDI);
rgPaste[4].lpstrFormatName=PSZ(IDS_PASTEBITMAP);
rgPaste[4].lpstrResultText=PSZ(IDS_PASTEASBITMAP);
rgPaste[4].dwFlags=OLEUIPASTE_PASTEONLY;
SETDefFormatEtc(rgPaste[5].fmtetc,m_cfLinkSource,TYMED_ISTREAM);
rgPaste[5].lpstrFormatName=PSZ(IDS_PASTELINK);
rgPaste[5].lpstrResultText=PSZ(IDS_PASTEASLINK);
rgPaste[5].dwFlags=OLEUIPASTE_LINKTYPE1 | OLEUIPASTE_ENABLEICON;
//Types we can Paste Link from the clipboard.
rgcf[0]=m_cfLinkSource;
ps.arrLinkTypes=rgcf;
ps.cLinkTypes=1;
ps.cPasteEntries=6;
uTemp=OleUIPasteSpecial(&ps);
if (OLEUI_OK==uTemp)
{
UINT i=ps.nSelectedIndex;
TENANTTYPE tType;
if (ps.fLink)
tType=TENANTTYPE_LINKEDOBJECTFROMDATA;
else
{
if (1==ps.nSelectedIndex)
tType=TENANTTYPE_EMBEDDEDOBJECTFROMDATA;
else
tType=TENANTTYPE_STATIC;
}
//Handle iconic aspects...from links as well
if ((1==i || ps.fLink) && (PSF_CHECKDISPLAYASICON
& ps.dwFlags) && NULL!=ps.hMetaPict)
{
rgPaste[i].fmtetc.dwAspect=DVASPECT_ICON;
dwData=(DWORD)(UINT)ps.hMetaPict;
}
fRet=PasteFromData(ps.lpSrcDataObj, &rgPaste[i].fmtetc
, tType, NULL, dwData, FALSE);
//Always free this regardless of what we do with it.
INOLE_MetafilePictIconFree(ps.hMetaPict);
}
ps.lpSrcDataObj->Release();
return fRet;
}
/*
* CPatronDoc::FQueryPasteFromData
* (Protected)
*
* Purpose:
* Determines if we can paste data from a data object.
*
* Parameters:
* pIDataObject LPDATAOBJECT from which we might want to paste.
* pFE LPFORMATETC in which to return the first format
* we can use. Ignored if NULL.
* ptType PTENANTTYPE in which to store the type of
* object we can paste. Ignored if NULL.
*
* Return Value:
* BOOL TRUE if data is available, FALSE otherwise.
*/
BOOL CPatronDoc::FQueryPasteFromData(LPDATAOBJECT pIDataObject
, LPFORMATETC pFE, PTENANTTYPE ptType)
{
FORMATETC fe;
HRESULT hr, hr2;
if (NULL!=(LPVOID)ptType)
*ptType=TENANTTYPE_STATIC;
//Any of our specific data here?
SETDefFormatEtc(fe, m_cf, TYMED_HGLOBAL);
hr=pIDataObject->QueryGetData(&fe);
//If embedded object data is available, set the appropriate type
hr2=OleQueryCreateFromData(pIDataObject);
if (NOERROR==hr2)
{
if (NULL!=pFE)
{
/*
* Default to content. Paste will use
* CFSTR_OBJECTDESCRIPTOR to figure the actual aspect.
*/
SETDefFormatEtc(*pFE, m_cfEmbeddedObject
, TYMED_ISTORAGE);
}
if (NULL!=(LPVOID)ptType)
*ptType=TENANTTYPE_EMBEDDEDOBJECTFROMDATA;
/*
* Return now if PatronObject wasn't available, otherwise
* break out so that pFE gets PatronObject format.
*/
if (NOERROR!=hr)
return TRUE;
}
if (NOERROR!=hr && NOERROR!=hr2)
{
//Try metafile, DIB, then bitmap, setting fe each time
SETDefFormatEtc(fe, CF_METAFILEPICT, TYMED_MFPICT);
hr=pIDataObject->QueryGetData(&fe);
if (NOERROR!=hr)
{
SETDefFormatEtc(fe, CF_DIB, TYMED_HGLOBAL);
hr=pIDataObject->QueryGetData(&fe);
if (NOERROR!=hr)
{
SETDefFormatEtc(fe, CF_BITMAP, TYMED_GDI);
hr=pIDataObject->QueryGetData(&fe);
}
}
}
if (NOERROR==hr && NULL!=pFE)
*pFE=fe;
return (NOERROR==hr);
}
/*
* CPatronDoc::FQueryPasteLinkFromData
* (Protected)
*
* Purpose:
* Determines if we can paste link from a data object.
*
* Parameters:
* pIDataObject LPDATAOBJECT from which we might want to paste.
* pFE LPFORMATETC in which to return the first format
* we can use. Ignored if NULL.
* ptType PTENANTTYPE in which to store the type of object
* we can paste. Ignored if NULL.
*
* Return Value:
* BOOL TRUE if data is available, FALSE otherwise.
*/
BOOL CPatronDoc::FQueryPasteLinkFromData(LPDATAOBJECT pIDataObject
, LPFORMATETC pFE, PTENANTTYPE ptType)
{
HRESULT hr;
if (NULL==pIDataObject)
return FALSE;
hr=OleQueryLinkFromData(pIDataObject);
if (NOERROR!=hr)
return FALSE;
if (NULL!=pFE)
SETDefFormatEtc(*pFE, m_cfLinkSource, TYMED_ISTREAM);
if (NULL!=(LPVOID)ptType)
*ptType=TENANTTYPE_LINKEDOBJECTFROMDATA;
return TRUE;
}
/*
* CPatronDoc::PasteFromData
* (Protected)
*
* Purpose:
* Retrieves the private data format from a data object and sets
* it to the current figure in the editor window.
*
* Parameters:
* pIDataObject LPDATAOBJECT from which to paste.
* pFE LPFORMATETC to use in the paste. Cannot be NULL.
* tType TENANTTYPE to paste.
* ppo PPATRONOBJECT containing placement data.
* dwData DWORD extra data sensitive to tType
* fUseObjDesc BOOL indicating to use CFSTR_OBJECTDESCRIPTOR
* format for determining the aspect of the object
* if the format is available.
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
*/
BOOL CPatronDoc::PasteFromData(LPDATAOBJECT pIDataObject
, LPFORMATETC pFE, TENANTTYPE tType, PPATRONOBJECT ppo
, DWORD dwData, BOOL fUseObjDesc)
{
BOOL fRet;
HRESULT hr;
PATRONOBJECT po;
STGMEDIUM stm;
LPOBJECTDESCRIPTOR pOD;
FORMATETC fe;
BOOL fRelease=FALSE;
if (NULL==pFE)
return FALSE;
//If not given any placement data, see if we can retrieve it
if (pFE->cfFormat==m_cf && NULL==ppo)
{
hr=pIDataObject->GetData(pFE, &stm);
if (SUCCEEDED(hr))
{
ppo=(PPATRONOBJECT)GlobalLock(stm.hGlobal);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -