⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 document.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * DOCUMENT.CPP
 * Freeloader Chapter 11
 *
 * Implementation of the CFreeloaderDoc derivation of CDocument.
 * We create a default handler object and use it for drawing, data
 * caching, and serialization.
 *
 * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
 *
 * Kraig Brockschmidt, Microsoft
 * Internet  :  kraigb@microsoft.com
 * Compuserve:  >INTERNET:kraigb@microsoft.com
 */


#include "freeload.h"


/*
 * CFreeloaderDoc::CFreeloaderDoc
 * CFreeloaderDoc::~CFreeloaderDoc
 *
 * Constructor Parameters:
 *  hInst           HINSTANCE of the application.
 *  pFR             PCFrame of the frame object.
 *  pAdv            PCDocumentAdviseSink to notify on events
 */

CFreeloaderDoc::CFreeloaderDoc(HINSTANCE hInst, PCFrame pFR
    , PCDocumentAdviseSink pAdv)
    : CDocument(hInst, pFR, pAdv)
    {
    m_pIStorage=NULL;
    m_pIUnknown=NULL;
    m_dwConn=0;
    m_clsID=CLSID_NULL;
    return;
    }


CFreeloaderDoc::~CFreeloaderDoc(void)
    {
    ReleaseObject();
    ReleaseInterface(m_pIStorage);
    return;
    }




/*
 * CFreeloaderDoc::ReleaseObject
 *
 * Purpose:
 *  Centralizes cleanup code for the object and its cache.
 *
 * Parameters:
 *  None
 *
 * Return Value:
 *  None
 */

void CFreeloaderDoc::ReleaseObject(void)
    {
    LPOLECACHE      pIOleCache;
    HRESULT         hr;

    if (0!=m_dwConn)
        {
        hr=m_pIUnknown->QueryInterface(IID_IOleCache
            , (PPVOID)&pIOleCache);

        if (SUCCEEDED(hr))
            {
            pIOleCache->Uncache(m_dwConn);
            pIOleCache->Release();
            }
        }

    ReleaseInterface(m_pIUnknown);
    CoFreeUnusedLibraries();
    m_dwConn=0;
    return;
    }



/*
 * CFreeloaderDoc::FInit
 *
 * Purpose:
 *  Initializes an already created document window.  Here we
 *  only change the stringtable bounds.
 *
 * Parameters:
 *  pDI             PDOCUMENTINIT containing initialization
 *                  parameters.
 *
 * Return Value:
 *  BOOL            TRUE if the function succeeded, FALSE otherwise.
 */

BOOL CFreeloaderDoc::FInit(PDOCUMENTINIT pDI)
    {
    //Change the stringtable range to our customization.
    pDI->idsMin=IDS_DOCUMENTMIN;
    pDI->idsMax=IDS_DOCUMENTMAX;

    //Do default initialization
    return CDocument::Init(pDI);
    }





/*
 * CFreeloaderDoc::FMessageHook
 *
 * Purpose:
 *  Processes WM_PAINT for the document so we can draw the object.
 *
 * 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 CFreeloaderDoc::FMessageHook(HWND hWnd, UINT iMsg
    , WPARAM wParam, LPARAM lParam, LRESULT *pLRes)
    {
    PAINTSTRUCT     ps;
    HDC             hDC;
    RECT            rc;
    RECTL           rcl;
    LPVIEWOBJECT2   pIViewObject2;
    HRESULT         hr;

    if (WM_PAINT!=iMsg)
        return FALSE;

    hDC=BeginPaint(hWnd, &ps);
    GetClientRect(hWnd, &rc);

    //Draw the object with IViewObject2::Draw, allowing ESC
    if (NULL!=m_pIUnknown)
        {
        hr=m_pIUnknown->QueryInterface(IID_IViewObject2
            , (PPVOID)&pIViewObject2);

        if (SUCCEEDED(hr))
            {
            //Put "Hit Esc to stop" in the status line
            m_pFR->StatusLine()->MessageSet(PSZ(IDS_HITESCTOSTOP));

            RECTLFROMRECT(rcl, rc);
            pIViewObject2->Draw(DVASPECT_CONTENT, -1, NULL, NULL
                , 0, hDC, &rcl, NULL, ContinuePaint, 0);
            pIViewObject2->Release();

            m_pFR->StatusLine()->MessageDisplay(ID_MESSAGEREADY);
            }
        }

    EndPaint(hWnd, &ps);
    return FALSE;
    }



/*
 * ContinuePaint
 *
 * Purpose:
 *  Callback function for IViewObject2::Draw that allows us to
 *  abort a long repaint.  This implementation watches the
 *  Esc key through GetAsyncKeyState.
 *
 * Parameters:
 *  dwContinue      DWORD custom data passed to IViewObject::Draw
 *                  which in our case holds the document pointer.
 *
 * Return Value:
 *  BOOL            TRUE to continue painting, FALSE to stop it.
 */

BOOL CALLBACK ContinuePaint(DWORD dwContinue)
    {
    return !(GetAsyncKeyState(VK_ESCAPE) < 0);
    }





/*
 * CFreeloaderDoc::Load
 *
 * Purpose:
 *  Loads a given document without any user interface overwriting
 *  the previous contents of the window.
 *
 * 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, NULL if the file
 *                  is new and untitled.
 *
 * Return Value:
 *  UINT            An error value from DOCERR_...
 */

UINT CFreeloaderDoc::Load(BOOL fChangeFile, LPTSTR pszFile)
    {
    HRESULT             hr;
    LPSTORAGE           pIStorage;
    LPUNKNOWN           pIUnknown;
    LPPERSISTSTORAGE    pIPersistStorage;
    DWORD               dwMode=STGM_TRANSACTED | STGM_READWRITE
                            | STGM_SHARE_EXCLUSIVE;
    CLSID               clsID;

    if (NULL==pszFile)
        {
        //Create a new temp file.
        hr=StgCreateDocfile(NULL, dwMode | STGM_CREATE
            | STGM_DELETEONRELEASE, 0, &pIStorage);

        if (FAILED(hr))
            return DOCERR_COULDNOTOPEN;

        m_pIStorage=pIStorage;

        FDirtySet(FALSE);
        Rename(NULL);
        return DOCERR_NONE;
        }

    //Attempt to open the storage.
    hr=StgOpenStorage(pszFile, NULL, dwMode, NULL, 0, &pIStorage);

    if (FAILED(hr))
        return DOCERR_COULDNOTOPEN;

    /*
     * When we previously called IPersistStorage::Save, we saved
     * the class of this object type with WriteClassStg.  Now
     * we read that CLSID, create a data cache for it, then
     * have it reload its data into the cache through
     * IPersistStorage::Load.
     */

    hr=ReadClassStg(pIStorage, &clsID);

    hr=CreateDataCache(NULL, clsID, IID_IUnknown
        , (PPVOID)&pIUnknown);

    if (FAILED(hr))
        {
        pIStorage->Release();
        return DOCERR_READFAILURE;
        }

    //Get IPersistStorage for the data we hold.
    pIUnknown->QueryInterface(IID_IPersistStorage
        , (PPVOID)&pIPersistStorage);

    //Load might fail because the object is already open...
    hr=pIPersistStorage->Load(pIStorage);
    pIPersistStorage->Release();

    if (FAILED(hr))
        {
        pIUnknown->Release();
        pIStorage->Release();
        return DOCERR_READFAILURE;
        }

    m_pIStorage=pIStorage;
    m_pIUnknown=pIUnknown;

    Rename(pszFile);
    SizeToGraphic(FALSE);
    FDirtySet(FALSE);
    return DOCERR_NONE;
    }







/*
 * CFreeloaderDoc::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 CFreeloaderDoc::Save(UINT uType, LPTSTR pszFile)
    {
    HRESULT             hr;
    LPSTORAGE           pIStorage;
    LPPERSISTSTORAGE    pIPersistStorage;
    CLSID               clsID;

    //If we have no data object, there's nothing to save.
    if (NULL==m_pIUnknown)
        return DOCERR_WRITEFAILURE;

    //Get IPersistStorage for the data we hold.
    hr=m_pIUnknown->QueryInterface(IID_IPersistStorage
        , (PPVOID)&pIPersistStorage);

    if (FAILED(hr))
        return DOCERR_WRITEFAILURE;

    //Save or Save As with the same file is just a commit.
    if (NULL==pszFile || (NULL!=pszFile
        && 0==lstrcmpi(pszFile, m_szFile)))
        {
        pIPersistStorage->Save(m_pIStorage, TRUE);
        m_pIStorage->Commit(STGC_ONLYIFCURRENT);

        pIPersistStorage->SaveCompleted(NULL);
        pIPersistStorage->Release();

        FDirtySet(FALSE);
        return DOCERR_NONE;
        }

    /*
     * When we're given a name, open the storage, creating it new
     * ifit does not exist or overwriting the old one.  Then CopyTo
     * from the current to the new, Commit the new, then Release
     * the old.
     */

    hr=StgCreateDocfile(pszFile, STGM_TRANSACTED | STGM_READWRITE
        | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &pIStorage);

    if (FAILED(hr))
        return DOCERR_COULDNOTOPEN;

    //Insure the image is up to date, then tell it we're changing
    pIPersistStorage->Save(m_pIStorage, TRUE);
    pIPersistStorage->HandsOffStorage();

    //Save the class, bitmap or metafile
    if (FAILED(pIPersistStorage->GetClassID(&clsID)))
        clsID=m_clsID;

    hr=WriteClassStg(m_pIStorage, clsID);

    hr=m_pIStorage->CopyTo(NULL, NULL, NULL, pIStorage);

    if (FAILED(hr))
        {
        pIPersistStorage->SaveCompleted(m_pIStorage);
        pIPersistStorage->Release();
        pIStorage->Release();
        return DOCERR_WRITEFAILURE;
        }

    pIStorage->Commit(STGC_ONLYIFCURRENT);

    /*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -