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

📄 page.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
📖 第 1 页 / 共 3 页
字号:
     * we leave xOff and yOff the same to account for scrolling.
     */
    if (fPrinter)
        {
        xOff=LOMETRIC_BORDER+m_pPG->m_xMarginLeft;
        yOff=-LOMETRIC_BORDER-m_pPG->m_yMarginTop;

        /*
         * Get device information.  If this fails, ptd is
         * NULL which is acceptable.
         */
        if (m_pPG->DevReadConfig(&pcd, &hIC))
            ptd=&(pcd->td);
        }

    for (i=(int)m_cTenants-1; i >=0; i--)
        {
        if (TenantGet(i, &pTenant, FALSE))
            {
            RECT        rc, rcWin;
            RECTL       rcl;

            //Paint this tenant only if visible.
            pTenant->RectGet(&rcl, TRUE);
            RECTFROMRECTL(rc, rcl);
            OffsetRect(&rc, -(int)m_pPG->m_xPos
                , -(int)m_pPG->m_yPos);
            GetClientRect(m_hWnd, &rcWin);

            if (IntersectRect(&rc, &rc, &rcWin))
                {
                pTenant->Draw(hDC, ptd, hIC, xOff, yOff
                    , fNoColor, fPrinter);
                }
            }
        }

    //Free whatever CPages::DevReadConfig returned.
    if (NULL!=pcd)
        {
        LPMALLOC    pIMalloc;

        if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
            {
            pIMalloc->Free(pcd);
            pIMalloc->Release();
            }
        }

    if (NULL!=hIC)
        DeleteDC(hIC);

    return;
    }






/*
 * CPage::TenantCreate
 *
 * Purpose:
 *  Creates a new tenant of a specific type.
 *
 * Parameters:
 *  tType           TENANTTYPE to create.
 *  pv              LPVOID providing information for the new
 *                  object creation.
 *  pFE             LPFORMATETC describing how we want this
 *                  rendered.
 *  ppo             PPATRONOBJECT with placement data.
 *  dwData          DWORD extra data to pass to the tenant.
 *
 * Return Value:
 *  None
 */

BOOL CPage::TenantCreate(TENANTTYPE tType, LPVOID pv
    , LPFORMATETC pFE, PPATRONOBJECT ppo, DWORD dwData)
    {
    PCTenant    pTenant;
    UINT        uRet;
    int         x, y;
    int         h, v;
    POINTL      ptl;
    SIZEL       szl;
    RECTL       rcl;
    RECT        rc;

    //New tenants go at top of the pile; zero index to TenantAdd.
    if (!TenantAdd(0, m_dwIDNext, &pTenant))
        return FALSE;

    uRet=pTenant->Create(tType, pv, pFE, &ptl, &szl, m_pIStorage
        , ppo, dwData);

    if (CREATE_FAILED==uRet)
        {
        //Reverse Create AND TenantAdd
        SendMessage(m_hWndTenantList, LB_DELETESTRING, 0, 0L);
        pTenant->Destroy(m_pIStorage);

        pTenant->Release();
        return FALSE;
        }

    m_dwIDNext++;
    m_cTenants++;

    if (NULL!=m_pTenantCur)
        m_pTenantCur->Select(FALSE, TRUE);

    m_iTenantCur=0;             //First one in the list now.
    m_pTenantCur=pTenant;

    //Tell the tenant where it lives, default is (0,0) in print area
    x=LOMETRIC_BORDER+m_pPG->m_xMarginLeft;
    y=-LOMETRIC_BORDER-m_pPG->m_yMarginTop;

    h=x;
    v=y;

    if (CREATE_PLACEDOBJECT==uRet)
        {
        SetRect(&rc, 3*CXYHANDLE, 3*CXYHANDLE, 0, 0);
        RectConvertMappings(&rc, NULL, FALSE);

        //Make sure place point is on page, otherwise go to (0,0)
        if (((int)ptl.x > x)
            && ((int)ptl.x < x+(int)m_pPG->m_cx-rc.left))
            x=(int)ptl.x;

        //m_pPG->m_cy is absolute
        if (((int)ptl.y < y)
            && ((int)ptl.y > y-(int)m_pPG->m_cy-rc.top))
            y=(int)ptl.y;
        }

    //Bounds check size of the object and fit to page as necessary.
    if (x+(int)szl.cx > (int)(h+m_pPG->m_cx))
        szl.cx=h+m_pPG->m_cx-x;

    //Remember that szl we get from Create is absolute
    if (y-(int)szl.cy < (int)(v-m_pPG->m_cy))
        szl.cy=-(int)(v-m_pPG->m_cy-y);

    SETRECTL(rcl, x, y, x+szl.cx, y-szl.cy);
    m_pTenantCur->RectSet(&rcl, FALSE, TRUE);

    //Force a repaint on this new guy
    m_pTenantCur->Invalidate();
    UpdateWindow(m_hWnd);

    m_pTenantCur->Select(TRUE, TRUE);

    //Make sure this new tenant knows about showing it's type.
    m_pTenantCur->ShowObjectType(m_pPG->m_fShowTypes);

    //New tenants must know the available monikers
    if (NULL!=m_pmkFile)
        {
        LPBC        pbc;
        LPMONIKER   pmkPage;
        TCHAR       szTemp[32];
        LPTSTR      pszFile;

       #ifdef WIN32ANSI
        OLECHAR     szW[32];

        GetStorageName(szW);
        WideCharToMultiByte(CP_ACP, 0, szW, -1, szTemp, 32
           , NULL, NULL);
       #else
        GetStorageName(szTemp);
       #endif
        CreateItemMoniker(TEXT("!"), szTemp, &pmkPage);

        //We can get the filename from our file moniker
        CreateBindCtx(0, &pbc);
       #ifdef WIN32ANSI
        LPOLESTR    pszTemp;
        m_pmkFile->GetDisplayName(pbc, NULL, &pszTemp);
        pszFile=(LPTSTR)CoTaskMemAlloc(512);
        WideCharToMultiByte(CP_ACP, 0, pszTemp, -1, pszFile
           , 512, NULL, NULL);
        CoTaskMemFree((void *)pszTemp);
       #else
        m_pmkFile->GetDisplayName(pbc, NULL, &pszFile);
       #endif
        pbc->Release();

        pTenant->NotifyOfRename(pszFile, m_pmkFile, pmkPage);
        pmkPage->Release();
        CoTaskMemFree((void *)pszFile);
        }

    //Activate new objects immediately and force a save on them
    if (TENANTTYPE_EMBEDDEDOBJECT==tType)
        {
        //CHAPTER24MOD
        DWORD       dwFlags;

        /*
         * A control, by virtue of being a control, will already
         * be in-place active except in design mode.  In any case,
         * the only thing a control can do is draw on our page,
         * so there's little point in activating a control here.
         */
        dwFlags=m_pTenantCur->GetControlFlags();

        if (!(TENANTSTATE_CONTROL & dwFlags))
            {
            m_pTenantCur->Activate(OLEIVERB_SHOW, NULL);
            m_pTenantCur->Update();
            }
        //End CHAPTER24MOD
        }

    return TRUE;
    }






/*
 * CPage::TenantDestroy
 *
 * Purpose:
 *  Destroys the currently selected tenant on this page.
 *
 * Parameters:
 *  None
 *
 * Return Value:
 *  None
 */

BOOL CPage::TenantDestroy(void)
    {
    if (NULL==m_pTenantCur)
        {
        MessageBeep(0);
        return FALSE;
        }

    SendMessage(m_hWndTenantList, LB_DELETESTRING
        , m_iTenantCur, 0L);

    m_pTenantCur->Invalidate();
    m_pTenantCur->Destroy(m_pIStorage);
    m_pTenantCur->Release();
    m_pTenantCur=NULL;

    //Update counts, etc., and select the next tenant in the list.
    if (m_iTenantCur==m_cTenants-1)
        m_iTenantCur--;

    if (0==--m_cTenants)
        m_pTenantCur=NULL;
    else
        {
        TenantGet(m_iTenantCur, &m_pTenantCur, TRUE);
        m_pTenantCur->Select(TRUE, TRUE);
        }

    UpdateWindow(m_hWnd);
    return TRUE;
    }





/*
 * CPage::TenantClip
 *
 * Purpose:
 *  Copies or cuts the currently selected tenant to the clipoard.
 *
 * Parameters:
 *  fCut            BOOL TRUE to cut the object, FALSE to copy.
 *
 * Return Value:
 *  BOOL            TRUE if successful, FALSE otherwise.
 */

BOOL CPage::TenantClip(BOOL fCut)
    {
    LPDATAOBJECT    pIDataObject;
    BOOL            fRet=FALSE;

    if (NULL==m_pTenantCur)
        return FALSE;

    /*
     * To perform a data transfer operation, we need to create a
     * data object with the selected object's data inside. To do
     * this we CoCreateInstance on CLSID_DataTransferObject
     * (Also implemented in this chapter), retrieve data from the
     * object we have, stuff that data into the transfer object,
     * then stick that object on the clipboard.
     *
     * Since we'll want an identical object at other times, like for
     * drag-drop, we use a private function to actually create it.
     */

    pIDataObject=TransferObjectCreate(NULL);

    if (NULL!=pIDataObject)
        {
        if (SUCCEEDED(OleSetClipboard(pIDataObject)))
            {
            if (fCut)
                TenantDestroy();

            fRet=TRUE;
            }

        pIDataObject->Release();
        }

    return fRet;
    }





/*
 * CPage::FQueryObjectSelected
 *
 * Purpose:
 *  Returns whether or not there is an object selected on this
 *  page for Cut, Copy, Delete functions.
 *
 * Parameters:
 *  hMenu           HMENU of the Edit menu.
 *
 * Return Value:
 *  BOOL            TRUE if we have an object, FALSE otherwise.
 */

BOOL CPage::FQueryObjectSelected(HMENU hMenu)
    {
    HMENU       hMenuTemp;

    /*
     * This will only be called on WM_INITMENUPOPUP, we'll also
     * use this function to create the Verb menu for this object.
     */
    if (NULL!=m_pTenantCur)
        {
        m_pTenantCur->AddVerbMenu(hMenu, MENUPOS_OBJECT);
        return TRUE;
        }

    OleUIAddVerbMenu(NULL, NULL, hMenu, MENUPOS_OBJECT
        , IDM_VERBMIN, IDM_VERBMAX, FALSE, 0, &hMenuTemp);

    return FALSE;
    }




/*
 * CPage::ActivateObject
 *
 * Purpose:
 *  Executes a verb on the currently selected object.
 *
 * Parameters:
 *  iVerb           LONG of the selected verb.
 *  pMSG            LPMSG that caused the invocation of the verb.
 *
 * Return Value:
 *  None
 */

void CPage::ActivateObject(LONG iVerb, LPMSG pMSG)
    {
    if (NULL==m_pTenantCur)
        return;

    m_pTenantCur->Activate(iVerb, pMSG);
    return;
    }




/*
 * CPage::ShowObjectTypes
 *
 * Purpose:
 *  Loops through all the tenants and tells each one to turn on or
 *  off the Show Objects features.
 *
 * Parameters:
 *  fShow           BOOL indicating to show the type or not.
 *
 * Return Value:
 *  None
 */

void CPage::ShowObjectTypes(BOOL fShow)
    {
    PCTenant    pTenant;
    UINT        i;

    for (i=0; i < m_cTenants; i++)
        {
        if (TenantGet(i, &pTenant, FALSE))
            pTenant->ShowObjectType(fShow);
        }

    return;
    }




/*
 * CPage::NotifyTenantsOfRename
 *
 * Purpose:
 *  Loops through all the tenants and informs each of the new
 *  document name.
 *
 * Parameters:
 *  pszFile         LPTSTR of the new filename.
 *  pmk             LPMONKIER for the new filename.
 *
 * Return Value:
 *  None
 */

void CPage::NotifyTenantsOfRename(LPTSTR pszFile, LPMONIKER pmk)
    {
    PCTenant    pTenant;
    UINT        i;
    LPMONIKER   pmkPage;
    LPMONIKER   pmkAll;
    TCHAR       szTemp[32];

    //Save the file moniker
    ReleaseInterface(m_pmkFile);
    m_pmkFile=pmk;
    m_pmkFile->AddRef();

    //Create a page moniker to send to the tenants.
   #ifdef WIN32ANSI
    OLECHAR     szW[32];

    GetStorageName(szW);
    WideCharToMultiByte(CP_ACP, 0, szW, -1, szTemp, 32
       , NULL, NULL);
   #else
    GetStorageName(szTemp);
   #endif
    CreateItemMoniker(TEXT("!"), szTemp, &pmkPage);

    for (i=0; i < m_cTenants; i++)
        {
        if (TenantGet(i, &pTenant, FALSE))
            pTenant->NotifyOfRename(pszFile, pmk, pmkPage);
        }

    /*
     * Register a File!Page!"\" wildcard moniker as well.
     * Note that the page is already marked as running
     * with the document's wildcard moniker.
     */
    CreateItemMoniker(TEXT("!"), TEXT("\\"), &pmkAll);

    if (NULL!=pmkAll)
        {
        LPMONIKER   pmkWild=NULL;
        LPMONIKER   pmkTemp=NULL;

        INOLE_RevokeAsRunning(&m_dwRegROTWild);
        pmk->ComposeWith(pmkPage, FALSE, &pmkTemp);

        if (NULL!=pmkTemp)
            {
            pmkTemp->ComposeWith(pmkAll, FALSE, &pmkWild);
            pmkTemp->Release();
            }

        if (NULL!=pmkWild)
            {
            INOLE_RegisterAsRunning(this, pmk, 0
                , &m_dwRegROTWild);
            pmkWild->Release();
            }

        pmkAll->Release();
        }

    //If anything held onto this, they AddRef'd
    pmkPage->Release();
    return;
    }


/*
 * CPage::ConvertObject
 *
 * Purpose:
 *  Invokes and handles the results of the Convert dialog
 *
 * Parameters:
 *  hWndFrame       HWND to use as the parent of the dialog.
 *  fNoServer       BOOL indicating if this was called because
 *                  ActivateObject failed.
 *
 * Return Value:
 *  None
 */

BOOL CPage::ConvertObject(HWND hWndFrame, BOOL fNoServer)
    {
    HRESULT         hr;
    OLEUICONVERT    ct;
    TENANTTYPE      tType;
    TENANTINFO      ti;
    UINT            uRet;
    HCURSOR         hCur;
    BOOL            fActivate=fNoServer;
    SIZEL           szl;

    if (NULL==m_pTenantCur)
        return FALSE;

    tType=m_pTenantCur->TypeGet();

    if (TENANTTYPE_STATIC==tType)
        {
        MessageBeep(0);
        return FALSE;
        }

    //Get object information we may want.
    m_pTenantCur->GetInfo(&ti);

    //Fill the structure.
    memset(&ct, 0, sizeof(ct));
    ct.cbStruct=sizeof(OLEUICONVERT);
    ct.hWndOwner=hWndFrame;
    ct.fIsLinkedObject=(TENANTTYPE_LINKEDOBJECT==tType);
    ct.dvAspect=ti.fe.dwAspect;

    m_pTenantCur->ObjectClassFormatAndIcon(&ct.clsid, &ct.wFormat
        , &ct.lpszUserType, &ct.hMetaPict, &ct.lpszDefLabel);

    uRet=OleUIConvert(&ct);

    if (OLEUI_OK==uRet)
        {
        //Potentially a long operation.
        hCur=SetCursor(LoadCursor(NULL, IDC_WAIT));

        //Prevent multiple repaints.
        m_pTenantCur->EnableRepaint(FALSE);

        //First, let's bother with the iconic aspect switch.
        if ((DVASPECT_ICON==ct.dvAspect && ct.fObjectsIconChanged)
            || ct.dvAspect!=ti.fe.dwAspect)
            {
            HGLOBAL     hMem=NULL;

            //Only pass non-NULL handle for icon aspects.
            if (DVASPECT_ICON==ct.dvAspect)
                hMem=ct.hMetaPict;

            m_pPG->m_fDirty=m_pTenantCur->SwitchOrUpdateAspect(hMem
                , FALSE);
            }

        //Now change types around.
        if ((CF_SELECTCONVERTTO & ct.dwFlags)
            && ct.clsid!=ct.clsidNew)
            {
            LPSTORAGE   pIStorage;

            /*
             * User selected convert, so:
             *  1.  Unload the object (back to passive state)
             *  2.  Call INOLE_DoConvert, which calls WriteClassStg,
             *      WriteFmtUserTypeStg, and SetConvertStg.
             *  3.  Reload the object and force an update.
             */

            //This should be the only close necessary.
            m_pTenantCur->StorageGet(&pIStorage);
            m_pTenantCur->Close(TRUE);

            hr=INOLE_DoConvert(pIStorage, ct.clsidNew);

            //Need to commit the new type and format
            pIStorage->Commit(STGC_DEFAULT);
            pIStorage->Release();

            if (SUCCEEDED(hr))
                {
                LPUNKNOWN   pObj;
                LPOLEOBJECT pIOleObject;

                //Reload and update.
                m_pTenantCur->Load(m_pIStorage, &ti);

                m_pTenantCur->ObjectGet(&pObj);
                pObj->QueryInterface(IID_IOleObject
                    , (PPVOID)&pIOleObject);
                pIOleObject->Update();
                pIOleObject->Release();
                pObj->Release();
                }

            m_pPG->m_fDirty=TRUE;
            }


        if (CF_SELECTACTIVATEAS & ct.dwFlags)
            {

⌨️ 快捷键说明

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