📄 document.cpp
字号:
/*
* DOCUMENT.CPP
* Patron Chapter 22
*
* Implementation of the CPatronDoc derivation of CDocument that
* manages pages for us.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "patron.h"
#include <memory.h>
#include <dlgs.h> //Pring Dlg button IDs
/*
* CPatronDoc::CPatronDoc
* CPatronDoc::~CPatronDoc
*
* Constructor Parameters:
* hInst HINSTANCE of the application.
* pFR PCFrame of the frame object.
* pAdv PCDocumentAdviseSink to notify on events.
*/
CPatronDoc::CPatronDoc(HINSTANCE hInst, PCFrame pFR
, PCDocumentAdviseSink pAdv)
: CDocument(hInst, pFR, pAdv)
{
m_pPG=NULL;
m_lVer=VERSIONCURRENT;
m_pIStorage=NULL;
m_fPrintSetup=TRUE;
m_pDropTarget=NULL;
//These CFSTR_* values are standard (defined in INC\CLASSLIB.H)
m_cfEmbeddedObject=RegisterClipboardFormat
(CFSTR_EMBEDDEDOBJECT);
m_cfObjectDescriptor=RegisterClipboardFormat
(CFSTR_OBJECTDESCRIPTOR);
m_cfLinkSource=RegisterClipboardFormat(CFSTR_LINKSOURCE);
m_cfLinkSrcDescriptor=RegisterClipboardFormat
(CFSTR_LINKSRCDESCRIPTOR);
m_fShowTypes=FALSE;
m_cRef=1L;
m_fRename=TRUE;
m_dwRegROT=0L;
m_dwRegROTWild=0L;
m_pImpIPersistFile=NULL;
m_pImpIOleItemContainer=NULL;
//CHAPTER22MOD
m_pImpIOleIPUIWindow=NULL;
m_pIOleIPActiveObject=NULL;
m_fNoObjectFrameTools=TRUE;
//End CHAPTER22MOD
return;
}
CPatronDoc::~CPatronDoc(void)
{
INOLE_RevokeAsRunning(&m_dwRegROT);
INOLE_RevokeAsRunning(&m_dwRegROTWild);
DeleteInterfaceImp(m_pImpIPersistFile);
DeleteInterfaceImp(m_pImpIOleItemContainer);
if (NULL!=m_pPG)
delete m_pPG;
//CHAPTER22MOD
DeleteInterfaceImp(m_pImpIOleIPUIWindow);
//End CHAPTER22MOD
ReleaseInterface(m_pIStorage);
CoFreeUnusedLibraries();
return;
}
/*
* CPatronDoc::QueryInterface
* CPatronDoc::AddRef
* CPatronDoc::Release
*/
STDMETHODIMP CPatronDoc::QueryInterface(REFIID riid, PPVOID ppv)
{
*ppv=NULL;
/*
* WARNING: Because the *ppv=this implicitly does
* *ppv=(LPVOID)this, the this pointer is incorrectly cast
* from a CPatronDoc pointer to LPVOID where we want an
* IUnknown pointer instead. CPatronDoc uses multiple
* inheritance here which means that we have to explicitly
* provide the typecast to select the base class like
* IUnknown. If you don't do this, calls to AddRef, for
* example, might call your desctructor!
*/
if (IID_IUnknown==riid)
*ppv=(LPUNKNOWN)this;
if (IID_IOleItemContainer==riid || IID_IOleContainer==riid
|| IID_IParseDisplayName==riid)
*ppv=m_pImpIOleItemContainer;
if (IID_IPersistFile==riid || IID_IPersist==riid)
*ppv=m_pImpIPersistFile;
//CHAPTER22MOD
if (IID_IOleWindow==riid || IID_IOleInPlaceUIWindow==riid)
*ppv=m_pImpIOleIPUIWindow;
//End CHAPTER22MOD
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CPatronDoc::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CPatronDoc::Release(void)
{
if (0!=--m_cRef)
return m_cRef;
PostMessage(m_hWnd, WM_CLOSE, 0, 0);
return 0;
}
/*
* CPatronDoc::Init
*
* Purpose:
* Initializes an already created document window. The client
* actually creates the window for us, then passes that here for
* further initialization.
*
* Parameters:
* pDI PDOCUMENTINIT containing initialization
* parameters.
*
* Return Value:
* BOOL TRUE if the function succeeded, FALSE otherwise.
*/
BOOL CPatronDoc::Init(PDOCUMENTINIT pDI)
{
//Change the stringtable range to our customization.
pDI->idsMin=IDS_DOCUMENTMIN;
pDI->idsMax=IDS_DOCUMENTMAX;
//Do default initialization
if (!CDocument::Init(pDI))
return FALSE;
//Pages are created when we get a Load later.
//Instantiate our interfaces
m_pImpIPersistFile=new CImpIPersistFile(this, this);
if (NULL==m_pImpIPersistFile)
return FALSE;
m_pImpIOleItemContainer=new CImpIOleItemContainer(this, this
, TRUE);
if (NULL==m_pImpIOleItemContainer)
return FALSE;
//CHAPTER22MOD
m_pImpIOleIPUIWindow=new CImpIOleInPlaceUIWindow(this, this);
if (NULL==m_pImpIOleIPUIWindow)
return FALSE;
//End CHAPTER22MOD
return TRUE;
}
/*
* CPatronDoc::FMessageHook
*
* Purpose:
* Processes WM_SIZE for the document so we can resize the Pages
* window.
*
* Parameters:
* <WndProc Parameters>
* pLRes LRESULT * in which to store the return
* value for the message.
*
* Return Value:
* BOOL TRUE to prevent further processing,
* FALSE otherwise.
*/
BOOL CPatronDoc::FMessageHook(HWND hWnd, UINT iMsg, WPARAM wParam
, LPARAM lParam, LRESULT *pLRes)
{
UINT dx, dy;
RECT rc;
*pLRes=0;
//CHAPTER22MOD
//CLASSLIB always sends MDIACTIVATE, regardless of MDI or SDI.
if (WM_MDIACTIVATE==iMsg)
{
/*
* Win32 has hWndActivate in lParam. Win16 has it in
* LOWORD(lParam). (HWND)(UINT) handles both cases.
*/
BOOL fActivate=((HWND)(UINT)lParam==hWnd);
if (NULL!=m_pIOleIPActiveObject)
{
//Hide our tools
if (fActivate)
g_pFR->ShowUIAndTools(m_fNoObjectFrameTools, FALSE);
m_pIOleIPActiveObject->OnDocWindowActivate(fActivate);
}
else
{
//Restore frame-level UI if we're becoming active.
if (fActivate)
g_pFR->ReinstateUI();
}
}
//End CHAPTER22MOD
//Eat to prevent flickering
if (WM_ERASEBKGND==iMsg)
return TRUE;
if (WM_SIZE==iMsg && NULL!=m_pPG)
{
dx=LOWORD(lParam);
dy=HIWORD(lParam);
if (SIZE_MINIMIZED!=wParam)
{
//Resize Pages window to fit the new document size.
GetClientRect(hWnd, &rc);
m_pPG->RectSet(&rc, FALSE);
}
//CHAPTER22MOD
if (NULL!=m_pIOleIPActiveObject)
{
//Also tell in-place objects that document was resized.
m_pIOleIPActiveObject->ResizeBorder(&rc
, m_pImpIOleIPUIWindow, FALSE);
}
//End CHAPTER22MOD
}
if (WM_DESTROY==iMsg)
{
/*
* We have to revoke the drop target here because the window
* will be destroyed and the property forcefully removed
* before we could do this in the destructor.
*/
if (NULL!=m_pDropTarget)
{
RevokeDragDrop(m_hWnd);
CoLockObjectExternal(m_pDropTarget, FALSE, TRUE);
m_pDropTarget->Release();
}
return FALSE;
}
/*
* We return FALSE even on WM_SIZE so we can let the default
* procedure handle maximized MDI child windows appropriately.
*/
return FALSE;
}
/*
* CPatronDoc::Clear
*
* Purpose:
* Sets all contents in the document back to defaults with no
* filename.
*
* Paramters:
* None
*
* Return Value:
* None
*/
void CPatronDoc::Clear(void)
{
//Completely reset the pages
if (NULL!=m_pPG)
m_pPG->StorageSet(NULL, FALSE, FALSE);
CDocument::Clear();
m_lVer=VERSIONCURRENT;
return;
}
/*
* CPatronDoc::FDirtySet
*
* Purpose:
* Sets or clears the document 'dirty' flag returning the previous
* state of that same flag. We override this to note change
* times in the running object table.
*
* Parameters:
* fDirty BOOL indicating the new contents of the dirty
* flag.
*
* Return Value:
* BOOL Previous value of the dirty flag.
*/
BOOL CPatronDoc::FDirtySet(BOOL fDirty)
{
BOOL fRet;
fRet=CDocument::FDirtySet(fDirty);
INOLE_NoteChangeTime(m_dwRegROT, NULL, NULL);
INOLE_NoteChangeTime(m_dwRegROTWild, NULL, NULL);
return fRet;
}
/*
* CPatronDoc::FDirtyGet
*
* Purpose:
* Returns the current dirty status of the document.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if the file is clean, FALSE otherwise.
*/
BOOL CPatronDoc::FDirtyGet()
{
BOOL fPageDirty;
fPageDirty=m_pPG->FIsDirty();
return m_fDirty | fPageDirty;
}
/*
* CPatronDoc::Delete
*
* Purpose:
* Removed the current object from the document.
*
* Paramters:
* None
*
* Return Value:
* None
*/
void CPatronDoc::Delete(void)
{
if (NULL!=m_pPG)
m_pPG->TenantDestroy();
CoFreeUnusedLibraries();
return;
}
/*
* CPatronDoc::FQueryObjectSelected
*
* Purpose:
* Returns whether or not there is an object selected in this
* document for Cut, Copy, Delete functions.
*
* Parameters:
* hMenu HMENU of the Edit menu.
*
* Return Value:
* BOOL TRUE if we have an object, FALSE otherwise.
*/
BOOL CPatronDoc::FQueryObjectSelected(HMENU hMenu)
{
return m_pPG->FQueryObjectSelected(hMenu);
}
/*
* CPatronDoc::Load
*
* Purpose:
* Loads a given document without any user interface overwriting
* the previous contents of the editor.
*
* Parameters:
* fChangeFile BOOL indicating if we're to update the window
* title and the filename from using this file.
* pszFile LPTSTR to the filename to load. Could be NULL
* for an untitled document.
*
* Return Value:
* UINT An error value from DOCERR_*
*/
UINT CPatronDoc::Load(BOOL fChangeFile, LPTSTR pszFile)
{
RECT rc;
LPSTORAGE pIStorage;
HRESULT hr;
CLSID clsID;
DWORD dwMode=STGM_TRANSACTED | STGM_READWRITE
| STGM_SHARE_EXCLUSIVE;
LPMONIKER pmk;
if (NULL==pszFile)
{
//Create a new temp file.
hr=StgCreateDocfile(NULL, dwMode | STGM_CREATE
| STGM_DELETEONRELEASE, 0, &pIStorage);
//Mark this our class since we check with ReadClassStg.
if (SUCCEEDED(hr))
WriteClassStg(pIStorage, CLSID_PatronPages);
}
else
{
hr=StgOpenStorage(pszFile, NULL, dwMode, NULL, 0, &pIStorage);
}
if (FAILED(hr))
return DOCERR_COULDNOTOPEN;
//Check if this is our type of file and exit if not.
hr=ReadClassStg(pIStorage, &clsID);
if (FAILED(hr) || CLSID_PatronPages!=clsID)
{
pIStorage->Release();
return DOCERR_READFAILURE;
}
//Attempt to create our contained Pages window.
m_pPG=new CPages(m_hInst, m_cf);
GetClientRect(m_hWnd, &rc);
//CHAPTER22MOD
//Always use WS_CLIPCHILDREN with in-place support.
if (!m_pPG->Init(m_hWnd, &rc, WS_CLIPCHILDREN | WS_CHILD
| WS_VISIBLE, ID_PAGES, NULL))
//End CHAPTER22MOD
{
pIStorage->Release();
return DOCERR_READFAILURE;
}
/*
* This moniker registration insures that all the file opening
* sequence will see this instance of the document as running
* and be able to communicate with it. This is so a link to
* an embedding on the same page of this document will hook
* up correctly.
*/
if (NULL!=pszFile)
{
CreateFileMoniker(pszFile, &pmk);
if (NULL!=pmk)
{
//This will be revoked and re-registered in Rename below
INOLE_RegisterAsRunning(this, pmk, 0, &m_dwRegROT);
pmk->Release();
}
}
if (!m_pPG->StorageSet(pIStorage, FALSE, (NULL==pszFile)))
{
pIStorage->Release();
return DOCERR_READFAILURE;
}
//Open the window up for drag-drop
m_pDropTarget=new CDropTarget(this);
if (NULL!=m_pDropTarget)
{
m_pDropTarget->AddRef();
CoLockObjectExternal(m_pDropTarget, TRUE, FALSE);
RegisterDragDrop(m_hWnd, m_pDropTarget);
}
m_pIStorage=pIStorage;
Rename(pszFile);
//Do initial setup if new file, otherwise Pages handles things.
if (NULL==pszFile)
{
//Go initialize the Pages for the default printer.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -