📄 document.cpp
字号:
* 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;
pIPersistStorage->SaveCompleted(m_pIStorage);
pIPersistStorage->Release();
Rename(pszFile);
FDirtySet(FALSE);
return DOCERR_NONE;
}
/*
* CFreeloaderDoc::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 CFreeloaderDoc::Clip(HWND hWndFrame, BOOL fCut)
{
BOOL fRet=TRUE;
static UINT rgcf[3]={CF_METAFILEPICT, CF_DIB, CF_BITMAP};
const UINT cFormats=3;
UINT i;
HGLOBAL hMem;
if (NULL==m_pIUnknown)
return FALSE;
if (!OpenClipboard(hWndFrame))
return FALSE;
//Clean out whatever junk is in the clipboard.
EmptyClipboard();
for (i=0; i < cFormats; i++)
{
hMem=RenderFormat(rgcf[i]);
if (NULL!=hMem)
{
SetClipboardData(rgcf[i], hMem);
fRet=TRUE;
break;
}
}
//Free clipboard ownership.
CloseClipboard();
//If we're cutting, clean out the cache and the object we hold.
if (fRet && fCut)
{
ReleaseObject();
InvalidateRect(m_hWnd, NULL, TRUE);
UpdateWindow(m_hWnd);
FDirtySet(TRUE);
}
return fRet;
}
/*
* CFreeloaderDoc::RenderFormat
*
* Purpose:
* Renders a specific clipboard format into global memory.
*
* Parameters:
* cf UINT format to render.
*
* Return Value:
* HGLOBAL Global memory handle containing the data.
*/
HGLOBAL CFreeloaderDoc::RenderFormat(UINT cf)
{
LPDATAOBJECT pIDataObject;
FORMATETC fe;
STGMEDIUM stm;
if (NULL==m_pIUnknown)
return NULL;
//We only have to ask the data object (cache) for the data.
switch (cf)
{
case CF_METAFILEPICT:
stm.tymed=TYMED_MFPICT;
break;
case CF_DIB:
stm.tymed=TYMED_HGLOBAL;
break;
case CF_BITMAP:
stm.tymed=TYMED_GDI;
break;
default:
return NULL;
}
stm.hGlobal=NULL;
SETDefFormatEtc(fe, cf, stm.tymed);
m_pIUnknown->QueryInterface(IID_IDataObject
, (PPVOID)&pIDataObject);
pIDataObject->GetData(&fe, &stm);
pIDataObject->Release();
return stm.hGlobal;
}
/*
* CFreeloaderDoc::FQueryPaste
*
* Purpose:
* Determines if we can paste data from the clipboard.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if data is available, FALSE otherwise.
*/
BOOL CFreeloaderDoc::FQueryPaste(void)
{
return IsClipboardFormatAvailable(CF_BITMAP)
|| IsClipboardFormatAvailable(CF_DIB)
|| IsClipboardFormatAvailable(CF_METAFILEPICT);
}
/*
* CFreeloaderDoc::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 CFreeloaderDoc::Paste(HWND hWndFrame)
{
UINT cf=0;
HGLOBAL hMem;
HRESULT hr;
DWORD dwConn;
LPUNKNOWN pIUnknown;
LPOLECACHE pIOleCache;
LPPERSISTSTORAGE pIPersistStorage;
FORMATETC fe;
STGMEDIUM stm;
CLSID clsID;
if (!OpenClipboard(hWndFrame))
return FALSE;
/*
* Try to get data in order of metafile, dib, bitmap. We set
* stm.tymed up front so if we actually get something a call
* to ReleaseStgMedium will clean it up for us.
*/
stm.pUnkForRelease=NULL;
stm.tymed=TYMED_MFPICT;
hMem=GetClipboardData(CF_METAFILEPICT);
if (NULL!=hMem)
cf=CF_METAFILEPICT;
if (0==cf)
{
stm.tymed=TYMED_HGLOBAL;
hMem=GetClipboardData(CF_DIB);
if (NULL!=hMem)
cf=CF_DIB;
}
if (0==cf)
{
stm.tymed=TYMED_GDI;
hMem=GetClipboardData(CF_BITMAP);
if (NULL!=hMem)
cf=CF_BITMAP;
}
stm.hGlobal=OleDuplicateData(hMem, cf, NULL);
CloseClipboard();
//Didn't get anything? Then we're finished.
if (0==cf)
return FALSE;
//This now describes the data we have.
SETDefFormatEtc(fe, cf, stm.tymed);
/*
* Create a data cache to deal with this data using
* either CoCreateInstance for an OLE-supported CLSID or
* CreateDataCache. The first will go through all the
* exercises of looking up the CLSID in the regDB, finding
* the OLE DLL (registered for these classes), getting a class
* factory, and using IClassFactory::CreateInstance. The
* second goes into OLE directly, creating the same object
* with less overhead. Thus we use CreateDataCache.
*/
if (CF_METAFILEPICT==cf)
clsID=CLSID_Picture_Metafile;
else
clsID=CLSID_Picture_Dib;
hr=CreateDataCache(NULL, clsID, IID_IUnknown
, (PPVOID)&pIUnknown);
if (FAILED(hr))
{
ReleaseStgMedium(&stm);
return FALSE;
}
/*
* Our contract says we provide storage through
* IPersistStorage::InitNew. We know that the object we're
* dealing with supports IPersistStorage and IOleCache, so
* we don't bother to check return values. I guess we're
* living dangerously...
*/
pIUnknown->QueryInterface(IID_IPersistStorage
, (PPVOID)&pIPersistStorage);
pIPersistStorage->InitNew(m_pIStorage);
pIPersistStorage->Release();
/*
* Now that we have the cache object, shove the data into it.
* No advise flags are necessary for static data.
*/
pIUnknown->QueryInterface(IID_IOleCache, (PPVOID)&pIOleCache);
pIOleCache->Cache(&fe, ADVF_PRIMEFIRST, &dwConn);
hr=pIOleCache->SetData(&fe, &stm, TRUE);
pIOleCache->Release();
if (FAILED(hr))
{
ReleaseStgMedium(&stm);
pIUnknown->Release();
return FALSE;
}
//Now that that's all done, replace our current with the new.
ReleaseObject();
m_pIUnknown=pIUnknown;
m_dwConn=dwConn;
m_clsID=clsID;
FDirtySet(TRUE);
InvalidateRect(m_hWnd, NULL, TRUE);
UpdateWindow(m_hWnd);
return TRUE;
}
/*
* CFreeloaderDoc::SizeToGraphic
*
* Purpose:
* Determines if we can size the window to the contained
* graphic and alternately performs the operation.
*
* Parameters:
* fQueryOnly BOOL indicating if we just want to know
* if sizing is possible (TRUE) or that we
* want to perform the sizing (FALSE).
*
* Return Value:
* BOOL TRUE if data is available, FALSE otherwise.
*/
BOOL CFreeloaderDoc::SizeToGraphic(BOOL fQueryOnly)
{
HRESULT hr;
LPVIEWOBJECT2 pIViewObject2;
SIZEL szl;
RECT rc;
UINT cx, cy;
HDC hDC;
DWORD dwStyle;
if (NULL==m_pIUnknown)
return FALSE;
m_pIUnknown->QueryInterface(IID_IViewObject2
, (PPVOID)&pIViewObject2);
if (FAILED(hr))
return FALSE;
if (fQueryOnly)
{
pIViewObject2->Release();
return TRUE;
}
hr=pIViewObject2->GetExtent(DVASPECT_CONTENT, -1, NULL, &szl);
pIViewObject2->Release();
if (FAILED(hr))
return FALSE;
//Calculate new doc rectangle based on these extents.
hDC=GetDC(NULL);
cx=MulDiv((int)szl.cx, GetDeviceCaps(hDC, LOGPIXELSX)
, HIMETRIC_PER_INCH);
cy=MulDiv((int)szl.cy, GetDeviceCaps(hDC, LOGPIXELSY)
, HIMETRIC_PER_INCH);
ReleaseDC(NULL, hDC);
SetRect(&rc, 0, 0, cx, cy);
dwStyle=GetWindowLong(m_hWnd, GWL_STYLE);
AdjustWindowRect(&rc, dwStyle, FALSE);
/*
* If the window is currently maximized, then we have to
* restore it first before sizing.
*/
if (IsZoomed(m_hWnd))
ShowWindow(m_hWnd, SW_RESTORE);
SetWindowPos(m_hWnd, NULL, 0, 0
, rc.right-rc.left , rc.bottom-rc.top
, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -