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

📄 helpers.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * HELPERS.CPP
 *
 * Utility functions for drawing various graphical effects
 * as well as coordinate conversion functions.
 *
 * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
 *
 * Kraig Brockschmidt, Microsoft
 * Internet  :  kraigb@microsoft.com
 * Compuserve:  >INTERNET:kraigb@microsoft.com
 */


#include "inoledll.h"


/*
 * INOLE_MetafilePictIconFree
 *
 * Purpose:
 *  Deletes the metafile contained in a METAFILEPICT structure and
 *  frees the memory for the structure itself.
 *
 * Parameters:
 *  hMetaPict       HGLOBAL metafilepict structure created in
 *                  OleMetafilePictFromIconAndLabel
 *
 * Return Value:
 *  None
 */

STDAPI_(void) INOLE_MetafilePictIconFree(HGLOBAL hMetaPict)
   {
   LPMETAFILEPICT      pMF;

   if (NULL==hMetaPict)
      return;

   pMF=(LPMETAFILEPICT)GlobalLock(hMetaPict);

   if (NULL!=pMF)
      {
      if (NULL!=pMF->hMF)
         DeleteMetaFile(pMF->hMF);
      }

   GlobalUnlock(hMetaPict);
   GlobalFree(hMetaPict);
   return;
   }





/*
 * INOLE_SwitchDisplayAspect
 *
 * Purpose:
 *  Switch the currently cached display aspect between DVASPECT_ICON
 *  and DVASPECT_CONTENT.  When setting up icon aspect, any currently
 *  cached content cache is discarded and any advise connections for
 *  content aspect are broken.
 *
 * Parameters:
 *  pObj            IUnknown * to the object in question
 *  pdwCurAspect    DWORD * containing the current aspect which
 *                  will contain the new aspect on output.
 *  dwNewAspect     DWORD with the aspect to switch to.
 *  hMetaPict       HGLOBAL containing the CF_METAFILEPICT with
 *                  the icon.
 *  fDeleteOld      BOOL indicating if we're to delete the old
 *                  aspect from the cache.
 *  fViewAdvise     BOOL indicating if we're to establish an
 *                  advise with the object for this new aspect.
 *  pSink           IAdviseSink * to the notification sink.
 *  pfMustUpdate    BOOL * in which to return whether or not
 *                  an update from a running server is necessary.
 *
 * Return Value:
 *  HRESULT         NOERROR or an error code in which case the cache
 *                  remains unchanged.
 */

STDAPI INOLE_SwitchDisplayAspect(IUnknown *pObj, LPDWORD pdwCurAspect
    , DWORD dwNewAspect, HGLOBAL hMetaPict, BOOL fDeleteOld
    , BOOL fViewAdvise, IAdviseSink *pSink, BOOL *pfMustUpdate)
    {
    IOleCache      *pCache=NULL;
    FORMATETC       fe;
    STGMEDIUM       stm;
    DWORD           dwAdvf;
    DWORD           dwNewConnection;
    DWORD           dwOldAspect=*pdwCurAspect;
    HRESULT         hr;

    if (pfMustUpdate)
       *pfMustUpdate=FALSE;

    hr=pObj->QueryInterface(IID_IOleCache, (void **)&pCache);

    if (FAILED(hr))
       return ResultFromScode(E_FAIL);

    //Establish new cache with the new aspect
    SETFormatEtc(fe, 0, dwNewAspect, NULL, TYMED_NULL, -1);

    /*
     * If we are using a custom icon for the display aspect then
     * we won't want to establish notifications with the data
     * source, that is, we don't want to change the icon.  Otherwise
     * we link up the given advise sink.
     */
    if (DVASPECT_ICON==dwNewAspect && NULL!=hMetaPict)
       dwAdvf=ADVF_NODATA;
    else
       dwAdvf=ADVF_PRIMEFIRST;

    hr=pCache->Cache(&fe, dwAdvf, &dwNewConnection);

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

    *pdwCurAspect=dwNewAspect;

    /*
     * Stuff the custom icon into the cache, or force an update
     * from the server.
     */
    if (DVASPECT_ICON==dwNewAspect && NULL!=hMetaPict)
        {
        SETFormatEtc(fe, CF_METAFILEPICT, DVASPECT_ICON, NULL
            , TYMED_MFPICT, -1);

        stm.tymed=TYMED_MFPICT;
        stm.hGlobal=hMetaPict;
        stm.pUnkForRelease=NULL;

        hr=pCache->SetData(&fe, &stm, FALSE);
        }
    else
        {
        if (pfMustUpdate)
           *pfMustUpdate=TRUE;
        }

    if (fViewAdvise && pSink)
        {
        IViewObject    *pView=NULL;

        hr=pObj->QueryInterface(IID_IViewObject, (void **)&pView);

        if (SUCCEEDED(hr))
            {
            pView->SetAdvise(dwNewAspect, 0, pSink);
            pView->Release();
            }
        }

    /*
     * Remove existing caches for the old display aspect to cut
     * down on needless storage overhead.  If you want to switch
     * frequently between icon and content aspects, then it is
     * best to actually keep both presentations in the cache.
     */
    if (fDeleteOld)
        {
        IEnumSTATDATA  *pEnum=NULL;
        STATDATA        sd;

        hr=pCache->EnumCache(&pEnum);

        while(NOERROR==hr)
            {
            hr=pEnum->Next(1, &sd, NULL);

            if (NOERROR==hr)
                {
                //Remove old aspect caches
                if (sd.formatetc.dwAspect==dwOldAspect)
                    pCache->Uncache(sd.dwConnection);
                }
            }

        if (NULL!=pEnum)
            pEnum->Release();
        }

    pCache->Release();
    return NOERROR;
    }



/*
 * INOLE_SetIconInCache
 *
 * Purpose:
 *  Stores an iconic presentation metafile in the cache.
 *
 * Parameters:
 *  pObj            IUnknown * of the object.
 *  hMetaPict       HGLOBAL containing the presentation.
 *
 * Return Value:
 *  HRESULT         From IOleCache::SetData.
 */

STDAPI INOLE_SetIconInCache(IUnknown *pObj, HGLOBAL hMetaPict)
    {
    IOleCache      *pCache;
    FORMATETC       fe;
    STGMEDIUM       stm;
    HRESULT         hr;

    if (NULL==hMetaPict)
        return ResultFromScode(E_INVALIDARG);

    if (FAILED(pObj->QueryInterface(IID_IOleCache, (void **)&pCache)))
        return ResultFromScode(E_NOINTERFACE);

    SETFormatEtc(fe, CF_METAFILEPICT, DVASPECT_ICON, NULL
        , TYMED_MFPICT, -1);

    stm.tymed=TYMED_MFPICT;
    stm.hGlobal=hMetaPict;
    stm.pUnkForRelease=NULL;

    hr=pCache->SetData(&fe, &stm, FALSE);
    pCache->Release();

    return hr;
    }





/*
 * INOLE_GetUserTypeOfClass
 *
 * Purpose:
 *  Returns the user type (human readable class name) of the
 *  specified class as stored in the registry.
 *
 * Parameters:
 *  clsID           CLSID in question
 *  iName           UINT index to the name to retrieve, where
 *                  zero is the name found as the value of
 *                  of the CLSID, anything else tries
 *                  AuxUserType\iName.
 *  pszUserType     LPTSTR in which to return the type
 *  cch             UINT length of pszUserType
 *
 * Return Value:
 *  UINT            Number of characters in returned string.
 *                  0 on error.
 */

STDAPI_(UINT) INOLE_GetUserTypeOfClass(REFCLSID clsID, UINT iName
    , LPTSTR pszUserType, UINT cch)
    {
    LPTSTR      pszCLSID;
    LPTSTR      pszProgID;
    TCHAR       szKey[300];
    LONG        dw;
    LONG        lRet;

    if (!pszUserType)
        return 0;

    *pszUserType='\0';

    //Get a string containing the class name
    StringFromCLSID(clsID, &pszCLSID);

    if (0==iName)
        wsprintf(szKey, TEXT("CLSID\\%s"), pszCLSID);
    else
        {
        wsprintf(szKey, TEXT("CLSID\\%s\\AuxUserType\\%u")
            , pszCLSID, iName);
        }

    CoTaskMemFree(pszCLSID);

    dw=cch;
    lRet=RegQueryValue(HKEY_CLASSES_ROOT, szKey, pszUserType, &dw);

    if (ERROR_SUCCESS!=lRet)
        {
        lstrcpyn(pszUserType, TEXT("Unknown"), cch);

        if (CoIsOle1Class(clsID))
            {
            //Try to get ProgID value for OLE 1 class
            ProgIDFromCLSID(clsID, &pszProgID);

            dw=cch;
            lRet=RegQueryValue(HKEY_CLASSES_ROOT, pszProgID
                , pszUserType, &dw);

            CoTaskMemFree(pszProgID);

            if (ERROR_SUCCESS!=lRet)
                dw=0;
            }
        }

    return (UINT)dw;
    }





/*
 * INOLE_DoConvert
 *
 * Purpose:
 *  Convert an embedded or linked object to another type, working
 *  in conjunection with OleUIConvert.
 *
 * Parameters:
 *  pIStorage       IStorage * to the object's data.
 *  clsID           CLSID to which we convert the object.
 *
 * Return Value:
 *  HRESULT         The usual.
 */

STDAPI INOLE_DoConvert(IStorage *pIStorage, REFCLSID clsID)
    {
    HRESULT     hr;
    CLSID       clsIDOrg;
    CLIPFORMAT  cfOrg;
    LPTSTR      pszOrg=NULL;
    TCHAR       szNew[256];

    if (FAILED(ReadClassStg(pIStorage, &clsIDOrg)))
        return ResultFromScode(E_FAIL);

    //Read original format/user type
    hr=ReadFmtUserTypeStg(pIStorage, &cfOrg, &pszOrg);

    //Get new user type
    if (0==INOLE_GetUserTypeOfClass(clsID, 0, szNew, 256))
        lstrcpy(szNew, TEXT(""));

    //Write new class into the storage
    if (SUCCEEDED(WriteClassStg(pIStorage, clsID)))
        {
        if (SUCCEEDED(WriteFmtUserTypeStg(pIStorage, cfOrg
            , szNew)))
            {
            SetConvertStg(pIStorage, TRUE);
            CoTaskMemFree((void *)pszOrg);
            return NOERROR;
            }

        //Failed to write new type, restore the old class
        WriteClassStg(pIStorage, clsIDOrg);
        }

    CoTaskMemFree((void *)pszOrg);
    return ResultFromScode(E_FAIL);
    }




/*
 * INOLE_CopyString
 *
 * Purpose:
 *  Copies a string allocated with CoTaskMemAlloc.
 *
 * Parameters:
 *  pszSrc          LPTSTR to the string to copy.
 *
 * Return Value:
 *  LPTSTR          New string or a NULL.
 */

STDAPI_(LPTSTR) INOLE_CopyString(LPTSTR pszSrc)
    {
    IMalloc    *pIMalloc;
    LPTSTR      pszDst;
    UINT        cch;

    cch=lstrlen(pszSrc);

    if (FAILED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
        return NULL;

    pszDst=(LPTSTR)pIMalloc->Alloc((cch+1)*sizeof(TCHAR));

    if (NULL!=pszDst)
       lstrcpy(pszDst, pszSrc);

    pIMalloc->Release();
    return pszDst;
    }




/*
 * INOLE_ObjectDescriptorFromOleObject
 *
 * Purpose:
 *  Fills and returns an OBJECTDESCRIPTOR structure. Information
 *  for the structure is obtained from an IOleObject instance.
 *
 * Parameters:
 *  pObj            IOleObject * from which to retrieve information.
 *  dwAspect        DWORD with the display aspect
 *  ptl             POINTL from upper-left corner of object where
 *                  mouse went down for use with Drag & Drop.
 *  pszl            LPSIZEL (optional) if the object is being scaled in
 *                  its container, then the container should pass the
 *                  extents that it is using to display the object.
 *
 * Return Value:
 *  HBGLOBAL         Handle to OBJECTDESCRIPTOR structure.
 */

STDAPI_(HGLOBAL) INOLE_ObjectDescriptorFromOleObject
    (IOleObject *pObj, DWORD dwAspect, POINTL ptl, LPSIZEL pszl)
    {
    CLSID           clsID;
    LPTSTR          pszName=NULL;
    LPTSTR          pszSrc=NULL;
    BOOL            fLink=FALSE;
    IOleLink       *pLink;
    TCHAR           szName[512];
    DWORD           dwMisc=0;
    SIZEL           szl;
    HGLOBAL         hMem;
    HRESULT         hr;
   #ifdef WIN32ANSI
   //#ifndef UNICODE
    LPWSTR			pszw;
    char            szTemp[512];
   #endif 

    if (SUCCEEDED(pObj->QueryInterface(IID_IOleLink
        , (void **)&pLink)))
        fLink=TRUE;

    if (FAILED(pObj->GetUserClassID(&clsID)))
        clsID=CLSID_NULL;

    //Get user string, expand to "Linked %s" if this is link
   #ifndef WIN32ANSI
   //#ifdef UNICODE
    pObj->GetUserType(USERCLASSTYPE_FULL, &pszName);

⌨️ 快捷键说明

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