home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / olemisc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  40.5 KB  |  1,388 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_OLE_SEG
  14. #pragma code_seg(AFX_OLE_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define new DEBUG_NEW
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25. // Debug diagnostics for SCODEs
  26.  
  27. #ifdef _DEBUG
  28. LPCTSTR AFXAPI AfxGetScodeString(SCODE sc)
  29. {
  30.     struct SCODE_ENTRY
  31.     {
  32.         SCODE sc;
  33.         LPCTSTR lpszName;
  34.     };
  35.     #define MAKE_SCODE_ENTRY(sc)    { sc, _T(#sc) }
  36.     static const SCODE_ENTRY scNameTable[] =
  37.     {
  38.         MAKE_SCODE_ENTRY(S_OK),
  39.         MAKE_SCODE_ENTRY(S_FALSE),
  40.  
  41.         MAKE_SCODE_ENTRY(CACHE_S_FORMATETC_NOTSUPPORTED),
  42.         MAKE_SCODE_ENTRY(CACHE_S_SAMECACHE),
  43.         MAKE_SCODE_ENTRY(CACHE_S_SOMECACHES_NOTUPDATED),
  44.         MAKE_SCODE_ENTRY(CONVERT10_S_NO_PRESENTATION),
  45.         MAKE_SCODE_ENTRY(DATA_S_SAMEFORMATETC),
  46.         MAKE_SCODE_ENTRY(DRAGDROP_S_CANCEL),
  47.         MAKE_SCODE_ENTRY(DRAGDROP_S_DROP),
  48.         MAKE_SCODE_ENTRY(DRAGDROP_S_USEDEFAULTCURSORS),
  49.         MAKE_SCODE_ENTRY(INPLACE_S_TRUNCATED),
  50.         MAKE_SCODE_ENTRY(MK_S_HIM),
  51.         MAKE_SCODE_ENTRY(MK_S_ME),
  52.         MAKE_SCODE_ENTRY(MK_S_MONIKERALREADYREGISTERED),
  53.         MAKE_SCODE_ENTRY(MK_S_REDUCED_TO_SELF),
  54.         MAKE_SCODE_ENTRY(MK_S_US),
  55.         MAKE_SCODE_ENTRY(OLE_S_MAC_CLIPFORMAT),
  56.         MAKE_SCODE_ENTRY(OLE_S_STATIC),
  57.         MAKE_SCODE_ENTRY(OLE_S_USEREG),
  58.         MAKE_SCODE_ENTRY(OLEOBJ_S_CANNOT_DOVERB_NOW),
  59.         MAKE_SCODE_ENTRY(OLEOBJ_S_INVALIDHWND),
  60.         MAKE_SCODE_ENTRY(OLEOBJ_S_INVALIDVERB),
  61.         MAKE_SCODE_ENTRY(OLEOBJ_S_LAST),
  62.         MAKE_SCODE_ENTRY(STG_S_CONVERTED),
  63.         MAKE_SCODE_ENTRY(VIEW_S_ALREADY_FROZEN),
  64.  
  65.         MAKE_SCODE_ENTRY(E_UNEXPECTED),
  66.         MAKE_SCODE_ENTRY(E_NOTIMPL),
  67.         MAKE_SCODE_ENTRY(E_OUTOFMEMORY),
  68.         MAKE_SCODE_ENTRY(E_INVALIDARG),
  69.         MAKE_SCODE_ENTRY(E_NOINTERFACE),
  70.         MAKE_SCODE_ENTRY(E_POINTER),
  71.         MAKE_SCODE_ENTRY(E_HANDLE),
  72.         MAKE_SCODE_ENTRY(E_ABORT),
  73.         MAKE_SCODE_ENTRY(E_FAIL),
  74.         MAKE_SCODE_ENTRY(E_ACCESSDENIED),
  75.  
  76.         MAKE_SCODE_ENTRY(CACHE_E_NOCACHE_UPDATED),
  77.         MAKE_SCODE_ENTRY(CLASS_E_CLASSNOTAVAILABLE),
  78.         MAKE_SCODE_ENTRY(CLASS_E_NOAGGREGATION),
  79.         MAKE_SCODE_ENTRY(CLIPBRD_E_BAD_DATA),
  80.         MAKE_SCODE_ENTRY(CLIPBRD_E_CANT_CLOSE),
  81.         MAKE_SCODE_ENTRY(CLIPBRD_E_CANT_EMPTY),
  82.         MAKE_SCODE_ENTRY(CLIPBRD_E_CANT_OPEN),
  83.         MAKE_SCODE_ENTRY(CLIPBRD_E_CANT_SET),
  84.         MAKE_SCODE_ENTRY(CO_E_ALREADYINITIALIZED),
  85.         MAKE_SCODE_ENTRY(CO_E_APPDIDNTREG),
  86.         MAKE_SCODE_ENTRY(CO_E_APPNOTFOUND),
  87.         MAKE_SCODE_ENTRY(CO_E_APPSINGLEUSE),
  88.         MAKE_SCODE_ENTRY(CO_E_BAD_PATH),
  89.         MAKE_SCODE_ENTRY(CO_E_CANTDETERMINECLASS),
  90.         MAKE_SCODE_ENTRY(CO_E_CLASS_CREATE_FAILED),
  91.         MAKE_SCODE_ENTRY(CO_E_CLASSSTRING),
  92.         MAKE_SCODE_ENTRY(CO_E_DLLNOTFOUND),
  93.         MAKE_SCODE_ENTRY(CO_E_ERRORINAPP),
  94.         MAKE_SCODE_ENTRY(CO_E_ERRORINDLL),
  95.         MAKE_SCODE_ENTRY(CO_E_IIDSTRING),
  96.         MAKE_SCODE_ENTRY(CO_E_NOTINITIALIZED),
  97.         MAKE_SCODE_ENTRY(CO_E_OBJISREG),
  98.         MAKE_SCODE_ENTRY(CO_E_OBJNOTCONNECTED),
  99.         MAKE_SCODE_ENTRY(CO_E_OBJNOTREG),
  100.         MAKE_SCODE_ENTRY(CO_E_OBJSRV_RPC_FAILURE),
  101.         MAKE_SCODE_ENTRY(CO_E_SCM_ERROR),
  102.         MAKE_SCODE_ENTRY(CO_E_SCM_RPC_FAILURE),
  103.         MAKE_SCODE_ENTRY(CO_E_SERVER_EXEC_FAILURE),
  104.         MAKE_SCODE_ENTRY(CO_E_SERVER_STOPPING),
  105.         MAKE_SCODE_ENTRY(CO_E_WRONGOSFORAPP),
  106.         MAKE_SCODE_ENTRY(CONVERT10_E_OLESTREAM_BITMAP_TO_DIB),
  107.         MAKE_SCODE_ENTRY(CONVERT10_E_OLESTREAM_FMT),
  108.         MAKE_SCODE_ENTRY(CONVERT10_E_OLESTREAM_GET),
  109.         MAKE_SCODE_ENTRY(CONVERT10_E_OLESTREAM_PUT),
  110.         MAKE_SCODE_ENTRY(CONVERT10_E_STG_DIB_TO_BITMAP),
  111.         MAKE_SCODE_ENTRY(CONVERT10_E_STG_FMT),
  112.         MAKE_SCODE_ENTRY(CONVERT10_E_STG_NO_STD_STREAM),
  113.         MAKE_SCODE_ENTRY(DISP_E_ARRAYISLOCKED),
  114.         MAKE_SCODE_ENTRY(DISP_E_BADCALLEE),
  115.         MAKE_SCODE_ENTRY(DISP_E_BADINDEX),
  116.         MAKE_SCODE_ENTRY(DISP_E_BADPARAMCOUNT),
  117.         MAKE_SCODE_ENTRY(DISP_E_BADVARTYPE),
  118.         MAKE_SCODE_ENTRY(DISP_E_EXCEPTION),
  119.         MAKE_SCODE_ENTRY(DISP_E_MEMBERNOTFOUND),
  120.         MAKE_SCODE_ENTRY(DISP_E_NONAMEDARGS),
  121.         MAKE_SCODE_ENTRY(DISP_E_NOTACOLLECTION),
  122.         MAKE_SCODE_ENTRY(DISP_E_OVERFLOW),
  123.         MAKE_SCODE_ENTRY(DISP_E_PARAMNOTFOUND),
  124.         MAKE_SCODE_ENTRY(DISP_E_PARAMNOTOPTIONAL),
  125.         MAKE_SCODE_ENTRY(DISP_E_TYPEMISMATCH),
  126.         MAKE_SCODE_ENTRY(DISP_E_UNKNOWNINTERFACE),
  127.         MAKE_SCODE_ENTRY(DISP_E_UNKNOWNLCID),
  128.         MAKE_SCODE_ENTRY(DISP_E_UNKNOWNNAME),
  129.         MAKE_SCODE_ENTRY(DRAGDROP_E_ALREADYREGISTERED),
  130.         MAKE_SCODE_ENTRY(DRAGDROP_E_INVALIDHWND),
  131.         MAKE_SCODE_ENTRY(DRAGDROP_E_NOTREGISTERED),
  132.         MAKE_SCODE_ENTRY(DV_E_CLIPFORMAT),
  133.         MAKE_SCODE_ENTRY(DV_E_DVASPECT),
  134.         MAKE_SCODE_ENTRY(DV_E_DVTARGETDEVICE),
  135.         MAKE_SCODE_ENTRY(DV_E_DVTARGETDEVICE_SIZE),
  136.         MAKE_SCODE_ENTRY(DV_E_FORMATETC),
  137.         MAKE_SCODE_ENTRY(DV_E_LINDEX),
  138.         MAKE_SCODE_ENTRY(DV_E_NOIVIEWOBJECT),
  139.         MAKE_SCODE_ENTRY(DV_E_STATDATA),
  140.         MAKE_SCODE_ENTRY(DV_E_STGMEDIUM),
  141.         MAKE_SCODE_ENTRY(DV_E_TYMED),
  142.         MAKE_SCODE_ENTRY(INPLACE_E_NOTOOLSPACE),
  143.         MAKE_SCODE_ENTRY(INPLACE_E_NOTUNDOABLE),
  144.         MAKE_SCODE_ENTRY(MEM_E_INVALID_LINK),
  145.         MAKE_SCODE_ENTRY(MEM_E_INVALID_ROOT),
  146.         MAKE_SCODE_ENTRY(MEM_E_INVALID_SIZE),
  147.         MAKE_SCODE_ENTRY(MK_E_CANTOPENFILE),
  148.         MAKE_SCODE_ENTRY(MK_E_CONNECTMANUALLY),
  149.         MAKE_SCODE_ENTRY(MK_E_ENUMERATION_FAILED),
  150.         MAKE_SCODE_ENTRY(MK_E_EXCEEDEDDEADLINE),
  151.         MAKE_SCODE_ENTRY(MK_E_INTERMEDIATEINTERFACENOTSUPPORTED),
  152.         MAKE_SCODE_ENTRY(MK_E_INVALIDEXTENSION),
  153.         MAKE_SCODE_ENTRY(MK_E_MUSTBOTHERUSER),
  154.         MAKE_SCODE_ENTRY(MK_E_NEEDGENERIC),
  155.         MAKE_SCODE_ENTRY(MK_E_NO_NORMALIZED),
  156.         MAKE_SCODE_ENTRY(MK_E_NOINVERSE),
  157.         MAKE_SCODE_ENTRY(MK_E_NOOBJECT),
  158.         MAKE_SCODE_ENTRY(MK_E_NOPREFIX),
  159.         MAKE_SCODE_ENTRY(MK_E_NOSTORAGE),
  160.         MAKE_SCODE_ENTRY(MK_E_NOTBINDABLE),
  161.         MAKE_SCODE_ENTRY(MK_E_NOTBOUND),
  162.         MAKE_SCODE_ENTRY(MK_E_SYNTAX),
  163.         MAKE_SCODE_ENTRY(MK_E_UNAVAILABLE),
  164.         MAKE_SCODE_ENTRY(OLE_E_ADVF),
  165.         MAKE_SCODE_ENTRY(OLE_E_ADVISENOTSUPPORTED),
  166.         MAKE_SCODE_ENTRY(OLE_E_BLANK),
  167.         MAKE_SCODE_ENTRY(OLE_E_CANT_BINDTOSOURCE),
  168.         MAKE_SCODE_ENTRY(OLE_E_CANT_GETMONIKER),
  169.         MAKE_SCODE_ENTRY(OLE_E_CANTCONVERT),
  170.         MAKE_SCODE_ENTRY(OLE_E_CLASSDIFF),
  171.         MAKE_SCODE_ENTRY(OLE_E_ENUM_NOMORE),
  172.         MAKE_SCODE_ENTRY(OLE_E_INVALIDHWND),
  173.         MAKE_SCODE_ENTRY(OLE_E_INVALIDRECT),
  174.         MAKE_SCODE_ENTRY(OLE_E_NOCACHE),
  175.         MAKE_SCODE_ENTRY(OLE_E_NOCONNECTION),
  176.         MAKE_SCODE_ENTRY(OLE_E_NOSTORAGE),
  177.         MAKE_SCODE_ENTRY(OLE_E_NOT_INPLACEACTIVE),
  178.         MAKE_SCODE_ENTRY(OLE_E_NOTRUNNING),
  179.         MAKE_SCODE_ENTRY(OLE_E_OLEVERB),
  180.         MAKE_SCODE_ENTRY(OLE_E_PROMPTSAVECANCELLED),
  181.         MAKE_SCODE_ENTRY(OLE_E_STATIC),
  182.         MAKE_SCODE_ENTRY(OLE_E_WRONGCOMPOBJ),
  183.         MAKE_SCODE_ENTRY(OLEOBJ_E_INVALIDVERB),
  184.         MAKE_SCODE_ENTRY(OLEOBJ_E_NOVERBS),
  185.         MAKE_SCODE_ENTRY(REGDB_E_CLASSNOTREG),
  186.         MAKE_SCODE_ENTRY(REGDB_E_IIDNOTREG),
  187.         MAKE_SCODE_ENTRY(REGDB_E_INVALIDVALUE),
  188.         MAKE_SCODE_ENTRY(REGDB_E_KEYMISSING),
  189.         MAKE_SCODE_ENTRY(REGDB_E_READREGDB),
  190.         MAKE_SCODE_ENTRY(REGDB_E_WRITEREGDB),
  191.         MAKE_SCODE_ENTRY(RPC_E_ATTEMPTED_MULTITHREAD),
  192.         MAKE_SCODE_ENTRY(RPC_E_CALL_CANCELED),
  193.         MAKE_SCODE_ENTRY(RPC_E_CALL_REJECTED),
  194.         MAKE_SCODE_ENTRY(RPC_E_CANTCALLOUT_AGAIN),
  195.         MAKE_SCODE_ENTRY(RPC_E_CANTCALLOUT_INASYNCCALL),
  196.         MAKE_SCODE_ENTRY(RPC_E_CANTCALLOUT_INEXTERNALCALL),
  197.         MAKE_SCODE_ENTRY(RPC_E_CANTCALLOUT_ININPUTSYNCCALL),
  198.         MAKE_SCODE_ENTRY(RPC_E_CANTPOST_INSENDCALL),
  199.         MAKE_SCODE_ENTRY(RPC_E_CANTTRANSMIT_CALL),
  200.         MAKE_SCODE_ENTRY(RPC_E_CHANGED_MODE),
  201.         MAKE_SCODE_ENTRY(RPC_E_CLIENT_CANTMARSHAL_DATA),
  202.         MAKE_SCODE_ENTRY(RPC_E_CLIENT_CANTUNMARSHAL_DATA),
  203.         MAKE_SCODE_ENTRY(RPC_E_CLIENT_DIED),
  204.         MAKE_SCODE_ENTRY(RPC_E_CONNECTION_TERMINATED),
  205.         MAKE_SCODE_ENTRY(RPC_E_DISCONNECTED),
  206.         MAKE_SCODE_ENTRY(RPC_E_FAULT),
  207.         MAKE_SCODE_ENTRY(RPC_E_INVALID_CALLDATA),
  208.         MAKE_SCODE_ENTRY(RPC_E_INVALID_DATA),
  209.         MAKE_SCODE_ENTRY(RPC_E_INVALID_DATAPACKET),
  210.         MAKE_SCODE_ENTRY(RPC_E_INVALID_PARAMETER),
  211.         MAKE_SCODE_ENTRY(RPC_E_INVALIDMETHOD),
  212.         MAKE_SCODE_ENTRY(RPC_E_NOT_REGISTERED),
  213.         MAKE_SCODE_ENTRY(RPC_E_OUT_OF_RESOURCES),
  214.         MAKE_SCODE_ENTRY(RPC_E_RETRY),
  215.         MAKE_SCODE_ENTRY(RPC_E_SERVER_CANTMARSHAL_DATA),
  216.         MAKE_SCODE_ENTRY(RPC_E_SERVER_CANTUNMARSHAL_DATA),
  217.         MAKE_SCODE_ENTRY(RPC_E_SERVER_DIED),
  218.         MAKE_SCODE_ENTRY(RPC_E_SERVER_DIED_DNE),
  219.         MAKE_SCODE_ENTRY(RPC_E_SERVERCALL_REJECTED),
  220.         MAKE_SCODE_ENTRY(RPC_E_SERVERCALL_RETRYLATER),
  221.         MAKE_SCODE_ENTRY(RPC_E_SERVERFAULT),
  222.         MAKE_SCODE_ENTRY(RPC_E_SYS_CALL_FAILED),
  223.         MAKE_SCODE_ENTRY(RPC_E_THREAD_NOT_INIT),
  224.         MAKE_SCODE_ENTRY(RPC_E_UNEXPECTED),
  225.         MAKE_SCODE_ENTRY(RPC_E_WRONG_THREAD),
  226.         MAKE_SCODE_ENTRY(STG_E_ABNORMALAPIEXIT),
  227.         MAKE_SCODE_ENTRY(STG_E_ACCESSDENIED),
  228.         MAKE_SCODE_ENTRY(STG_E_CANTSAVE),
  229.         MAKE_SCODE_ENTRY(STG_E_DISKISWRITEPROTECTED),
  230.         MAKE_SCODE_ENTRY(STG_E_EXTANTMARSHALLINGS),
  231.         MAKE_SCODE_ENTRY(STG_E_FILEALREADYEXISTS),
  232.         MAKE_SCODE_ENTRY(STG_E_FILENOTFOUND),
  233.         MAKE_SCODE_ENTRY(STG_E_INSUFFICIENTMEMORY),
  234.         MAKE_SCODE_ENTRY(STG_E_INUSE),
  235.         MAKE_SCODE_ENTRY(STG_E_INVALIDFLAG),
  236.         MAKE_SCODE_ENTRY(STG_E_INVALIDFUNCTION),
  237.         MAKE_SCODE_ENTRY(STG_E_INVALIDHANDLE),
  238.         MAKE_SCODE_ENTRY(STG_E_INVALIDHEADER),
  239.         MAKE_SCODE_ENTRY(STG_E_INVALIDNAME),
  240.         MAKE_SCODE_ENTRY(STG_E_INVALIDPARAMETER),
  241.         MAKE_SCODE_ENTRY(STG_E_INVALIDPOINTER),
  242.         MAKE_SCODE_ENTRY(STG_E_LOCKVIOLATION),
  243.         MAKE_SCODE_ENTRY(STG_E_MEDIUMFULL),
  244.         MAKE_SCODE_ENTRY(STG_E_NOMOREFILES),
  245.         MAKE_SCODE_ENTRY(STG_E_NOTCURRENT),
  246.         MAKE_SCODE_ENTRY(STG_E_NOTFILEBASEDSTORAGE),
  247.         MAKE_SCODE_ENTRY(STG_E_OLDDLL),
  248.         MAKE_SCODE_ENTRY(STG_E_OLDFORMAT),
  249.         MAKE_SCODE_ENTRY(STG_E_PATHNOTFOUND),
  250.         MAKE_SCODE_ENTRY(STG_E_READFAULT),
  251.         MAKE_SCODE_ENTRY(STG_E_REVERTED),
  252.         MAKE_SCODE_ENTRY(STG_E_SEEKERROR),
  253.         MAKE_SCODE_ENTRY(STG_E_SHAREREQUIRED),
  254.         MAKE_SCODE_ENTRY(STG_E_SHAREVIOLATION),
  255.         MAKE_SCODE_ENTRY(STG_E_TOOMANYOPENFILES),
  256.         MAKE_SCODE_ENTRY(STG_E_UNIMPLEMENTEDFUNCTION),
  257.         MAKE_SCODE_ENTRY(STG_E_UNKNOWN),
  258.         MAKE_SCODE_ENTRY(STG_E_WRITEFAULT),
  259.         MAKE_SCODE_ENTRY(TYPE_E_AMBIGUOUSNAME),
  260.         MAKE_SCODE_ENTRY(TYPE_E_BADMODULEKIND),
  261.         MAKE_SCODE_ENTRY(TYPE_E_BUFFERTOOSMALL),
  262.         MAKE_SCODE_ENTRY(TYPE_E_CANTCREATETMPFILE),
  263.         MAKE_SCODE_ENTRY(TYPE_E_CANTLOADLIBRARY),
  264.         MAKE_SCODE_ENTRY(TYPE_E_CIRCULARTYPE),
  265.         MAKE_SCODE_ENTRY(TYPE_E_DLLFUNCTIONNOTFOUND),
  266.         MAKE_SCODE_ENTRY(TYPE_E_DUPLICATEID),
  267.         MAKE_SCODE_ENTRY(TYPE_E_ELEMENTNOTFOUND),
  268.         MAKE_SCODE_ENTRY(TYPE_E_INCONSISTENTPROPFUNCS),
  269.         MAKE_SCODE_ENTRY(TYPE_E_INVALIDSTATE),
  270.         MAKE_SCODE_ENTRY(TYPE_E_INVDATAREAD),
  271.         MAKE_SCODE_ENTRY(TYPE_E_IOERROR),
  272.         MAKE_SCODE_ENTRY(TYPE_E_LIBNOTREGISTERED),
  273.         MAKE_SCODE_ENTRY(TYPE_E_NAMECONFLICT),
  274.         MAKE_SCODE_ENTRY(TYPE_E_OUTOFBOUNDS),
  275.         MAKE_SCODE_ENTRY(TYPE_E_QUALIFIEDNAMEDISALLOWED),
  276.         MAKE_SCODE_ENTRY(TYPE_E_REGISTRYACCESS),
  277.         MAKE_SCODE_ENTRY(TYPE_E_SIZETOOBIG),
  278.         MAKE_SCODE_ENTRY(TYPE_E_TYPEMISMATCH),
  279.         MAKE_SCODE_ENTRY(TYPE_E_UNDEFINEDTYPE),
  280.         MAKE_SCODE_ENTRY(TYPE_E_UNKNOWNLCID),
  281.         MAKE_SCODE_ENTRY(TYPE_E_UNSUPFORMAT),
  282.         MAKE_SCODE_ENTRY(TYPE_E_WRONGTYPEKIND),
  283.         MAKE_SCODE_ENTRY(VIEW_E_DRAW),
  284.     };
  285.     #undef MAKE_SCODE_ENTRY
  286.  
  287.     // look for it in the table
  288.     for (int i = 0; i < _countof(scNameTable); i++)
  289.     {
  290.         if (sc == scNameTable[i].sc)
  291.             return scNameTable[i].lpszName;
  292.     }
  293.     return NULL;    // not found
  294. }
  295.  
  296. LPCTSTR AFXAPI AfxGetScodeRangeString(SCODE sc)
  297. {
  298.     struct RANGE_ENTRY
  299.     {
  300.         SCODE scFirst;
  301.         SCODE scLast;
  302.         LPCTSTR lpszName;
  303.     };
  304.     #define MAKE_RANGE_ENTRY(scRange) \
  305.         { scRange##_FIRST, scRange##_LAST, \
  306.             _T(#scRange) _T("_FIRST...") _T(#scRange) _T("_LAST") }
  307.  
  308.     static const RANGE_ENTRY scRangeTable[] =
  309.     {
  310.         MAKE_RANGE_ENTRY(CACHE_E),
  311.         MAKE_RANGE_ENTRY(CACHE_S),
  312.         MAKE_RANGE_ENTRY(CLASSFACTORY_E),
  313.         MAKE_RANGE_ENTRY(CLASSFACTORY_S),
  314.         MAKE_RANGE_ENTRY(CLIENTSITE_E),
  315.         MAKE_RANGE_ENTRY(CLIENTSITE_S),
  316.         MAKE_RANGE_ENTRY(CLIPBRD_E),
  317.         MAKE_RANGE_ENTRY(CLIPBRD_S),
  318.         MAKE_RANGE_ENTRY(CONVERT10_E),
  319.         MAKE_RANGE_ENTRY(CONVERT10_S),
  320.         MAKE_RANGE_ENTRY(CO_E),
  321.         MAKE_RANGE_ENTRY(CO_S),
  322.         MAKE_RANGE_ENTRY(DATA_E),
  323.         MAKE_RANGE_ENTRY(DATA_S),
  324.         MAKE_RANGE_ENTRY(DRAGDROP_E),
  325.         MAKE_RANGE_ENTRY(DRAGDROP_S),
  326.         MAKE_RANGE_ENTRY(ENUM_E),
  327.         MAKE_RANGE_ENTRY(ENUM_S),
  328.         MAKE_RANGE_ENTRY(INPLACE_E),
  329.         MAKE_RANGE_ENTRY(INPLACE_S),
  330.         MAKE_RANGE_ENTRY(MARSHAL_E),
  331.         MAKE_RANGE_ENTRY(MARSHAL_S),
  332.         MAKE_RANGE_ENTRY(MK_E),
  333.         MAKE_RANGE_ENTRY(MK_S),
  334.         MAKE_RANGE_ENTRY(OLEOBJ_E),
  335.         MAKE_RANGE_ENTRY(OLEOBJ_S),
  336.         MAKE_RANGE_ENTRY(OLE_E),
  337.         MAKE_RANGE_ENTRY(OLE_S),
  338.         MAKE_RANGE_ENTRY(REGDB_E),
  339.         MAKE_RANGE_ENTRY(REGDB_S),
  340.         MAKE_RANGE_ENTRY(VIEW_E),
  341.         MAKE_RANGE_ENTRY(VIEW_S),
  342.     };
  343.     #undef MAKE_RANGE_ENTRY
  344.  
  345.     // look for it in the table
  346.     for (int i = 0; i < _countof(scRangeTable); i++)
  347.     {
  348.         if (sc >= scRangeTable[i].scFirst && sc <= scRangeTable[i].scLast)
  349.             return scRangeTable[i].lpszName;
  350.     }
  351.     return NULL;    // not found
  352. }
  353.  
  354. LPCTSTR AFXAPI AfxGetSeverityString(SCODE sc)
  355. {
  356.     static const TCHAR* rgszSEVERITY[] =
  357.     {
  358.         _T("SEVERITY_SUCCESS"),
  359.         _T("SEVERITY_ERROR"),
  360.     };
  361.     return rgszSEVERITY[SCODE_SEVERITY(sc)];
  362. }
  363.  
  364. LPCTSTR AFXAPI AfxGetFacilityString(SCODE sc)
  365. {
  366.     static const TCHAR* rgszFACILITY[] =
  367.     {
  368.         _T("FACILITY_NULL"),
  369.         _T("FACILITY_RPC"),
  370.         _T("FACILITY_DISPATCH"),
  371.         _T("FACILITY_STORAGE"),
  372.         _T("FACILITY_ITF"),
  373.         _T("FACILITY_0x05"),
  374.         _T("FACILITY_0x06"),
  375.         _T("FACILITY_WIN32"),
  376.         _T("FACILITY_WINDOWS"),
  377.     };
  378.     if (SCODE_FACILITY(sc) >= _countof(rgszFACILITY))
  379.         return _T("<Unknown Facility>");
  380.  
  381.     return rgszFACILITY[SCODE_FACILITY(sc)];
  382. }
  383.  
  384. LPCTSTR AFXAPI AfxGetFullScodeString(SCODE sc)
  385. {
  386.     static TCHAR szBuf[128];
  387.     LPCTSTR lpsz;
  388.     if ((lpsz = AfxGetScodeString(sc)) != NULL)
  389.     {
  390.         // found exact match
  391.         wsprintf(szBuf, _T("%s ($%08lX)"), lpsz, sc);
  392.     }
  393.     else if ((lpsz = AfxGetScodeRangeString(sc)) != NULL)
  394.     {
  395.         // found suitable range
  396.         wsprintf(szBuf, _T("range: %s ($%08lX)"), lpsz, sc);
  397.     }
  398.     else
  399.     {
  400.         // not found at all -- split it up into its parts
  401.         wsprintf(szBuf, _T("severity: %s, facility: %s ($%08lX)"),
  402.             AfxGetSeverityString(sc), AfxGetFacilityString(sc), sc);
  403.     }
  404.     return szBuf;
  405. }
  406. #endif //_DEBUG
  407.  
  408. /////////////////////////////////////////////////////////////////////////////
  409. // Exceptions for OLE Support
  410.  
  411. void AFXAPI AfxThrowOleException(SCODE sc)
  412. {
  413. #ifdef _DEBUG
  414.     TRACE1("Warning: constructing COleException, scode = %s.\n",
  415.         AfxGetFullScodeString(sc));
  416. #endif
  417.     COleException* pException = new COleException;
  418.     pException->m_sc = sc;
  419.     THROW(pException);
  420. }
  421.  
  422. BOOL COleException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
  423.         PUINT pnHelpContext)
  424. {
  425.     ASSERT(lpszError != NULL && AfxIsValidString(lpszError, nMaxError));
  426.  
  427.     if (pnHelpContext != NULL)
  428.         *pnHelpContext = 0;
  429.  
  430.     LPTSTR lpBuffer;
  431.     if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  432.                 FORMAT_MESSAGE_FROM_SYSTEM,
  433.                 NULL, m_sc,
  434.                 MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
  435.                 (LPTSTR) &lpBuffer, 0, NULL) == 0)
  436.     {
  437.         *lpszError = '\0';
  438.         return FALSE;
  439.     }
  440.     else
  441.     {
  442.         lstrcpyn(lpszError, lpBuffer, nMaxError);
  443.         LocalFree(lpBuffer);
  444.         return TRUE;
  445.     }
  446. }
  447.  
  448. /////////////////////////////////////////////////////////////////////////////
  449. // Turn a caught exception into an OLE return code
  450.  
  451. SCODE PASCAL COleException::Process(const CException* pAnyException)
  452. {
  453.     SCODE sc;
  454.     if (pAnyException->IsKindOf(RUNTIME_CLASS(COleException)))
  455.         sc = ((COleException*)pAnyException)->m_sc;
  456.     else if (pAnyException->IsKindOf(RUNTIME_CLASS(CMemoryException)))
  457.         sc = E_OUTOFMEMORY;
  458.     else if (pAnyException->IsKindOf(RUNTIME_CLASS(CNotSupportedException)))
  459.         sc = E_NOTIMPL;
  460.     else
  461.         sc = E_UNEXPECTED;  // some other problem
  462.  
  463.     return sc;
  464. }
  465.  
  466. /////////////////////////////////////////////////////////////////////////////
  467. // Implementation helpers
  468.  
  469. HMENU AFXAPI AfxMergeMenus(HMENU hMenuShared, HMENU hMenuSource,
  470.     LONG* lpMenuWidths, int iWidthIndex, BOOL bMergeHelpMenus /* = FALSE */)
  471. {
  472.     ASSERT(hMenuShared != NULL && WCE_FCTN(IsMenu)(hMenuShared));
  473.     ASSERT(hMenuSource != NULL && WCE_FCTN(IsMenu)(hMenuSource));
  474.  
  475.     BOOL bHelpMergedAsSubMenu = FALSE;
  476.     HMENU hHelpSubMenu = NULL;
  477.  
  478.     // copy the popups from the pMenuSource
  479.     int cMenuItems = WCE_FCTN(GetMenuItemCount)(hMenuSource);
  480.     int cGroupWidth = 0;
  481.     int nPosition = 0;
  482.  
  483.     // insert at appropriate spot depending on iWidthIndex
  484.     ASSERT(iWidthIndex == 0 || iWidthIndex == 1);
  485.     if (iWidthIndex == 1)
  486.         nPosition = (int)lpMenuWidths[0];
  487.  
  488.     for (int i = 0; i < cMenuItems; i++)
  489.     {
  490.         // get the HMENU of the popup
  491.         HMENU hMenuPopup = ::GetSubMenu(hMenuSource, i);
  492.  
  493.         // separators move us to next group
  494.         UINT state = WCE_FCTN(GetMenuState)(hMenuSource, i, MF_BYPOSITION);
  495.         if (hMenuPopup == NULL && (state & MF_SEPARATOR) != 0)
  496.         {
  497.             ASSERT(iWidthIndex <= 5);   // servers should not touch past 5
  498.             lpMenuWidths[iWidthIndex] = cGroupWidth;
  499.             cGroupWidth = 0;
  500.             if (iWidthIndex < 5)
  501.                 nPosition += (int)lpMenuWidths[iWidthIndex+1];
  502.             iWidthIndex += 2;
  503.         }
  504.         else
  505.         {
  506.             HMENU hHelpMenu = NULL;
  507.  
  508.             // are we processing the help menu group?
  509.  
  510.             if (bMergeHelpMenus && iWidthIndex == 5)
  511.             {
  512.                 // if so, see if the container has Help any menu items
  513.                 if (lpMenuWidths[iWidthIndex] == 1)
  514.                 {
  515.                     // get the help menu from the container
  516.                     hHelpMenu = GetSubMenu(hMenuShared, nPosition);
  517.                 }
  518.             }
  519.  
  520.             // get the menu item text
  521.             TCHAR szItemText[256];
  522.             int nLen = WCE_FCTN(GetMenuString)(hMenuSource, i, szItemText,
  523.                 sizeof szItemText, MF_BYPOSITION);
  524.  
  525.             // popups are handled differently than normal menu items
  526.             if (hMenuPopup != NULL)
  527.             {
  528.                 if (hHelpMenu != NULL)
  529.                 {
  530.                     CString strTearOff = AfxGetAppName();
  531.                     if (!strTearOff.IsEmpty())
  532.                         strTearOff += ' ';
  533.                     strTearOff += szItemText;
  534.  
  535.                     // container has help items -- add ours to its submenu
  536.                     AppendMenu(hHelpMenu, MF_STRING | MF_POPUP,
  537.                         (UINT)hMenuPopup, strTearOff);
  538.  
  539.                     // clear the count of Help group items and add
  540.                     // the help menu to the window group
  541.  
  542.                     lpMenuWidths[iWidthIndex] = 0;
  543.                     lpMenuWidths[iWidthIndex-1]++;
  544.  
  545.                     bHelpMergedAsSubMenu = TRUE;
  546.                     hHelpSubMenu = hMenuPopup;
  547.                 }
  548.                 else if (::WCE_FCTN(GetMenuItemCount)(hMenuPopup) != 0)
  549.                 {
  550.                     // strip the HIBYTE because it contains a count of items
  551.                     state = LOBYTE(state) | MF_POPUP;   // must be popup
  552.  
  553.                     // non-empty popup -- add it to the shared menu bar
  554.                     InsertMenu(hMenuShared, nPosition, state | MF_BYPOSITION,
  555.                         (UINT)hMenuPopup, szItemText);
  556.                     ++nPosition;
  557.                     ++cGroupWidth;
  558.                 }
  559.             }
  560.             else if (nLen > 0)
  561.             {
  562.                 // only non-empty items are added
  563.                 ASSERT(szItemText[0] != 0);
  564.  
  565.                 // here the state does not contain a count in the HIBYTE
  566.                 InsertMenu(hMenuShared, nPosition, state | MF_BYPOSITION,
  567.                     WCE_FCTN(GetMenuItemID)(hMenuSource, i), szItemText);
  568.                 ++nPosition;
  569.                 ++cGroupWidth;
  570.             }
  571.         }
  572.     }
  573.  
  574.     // set the last group width
  575.  
  576.     if (!bHelpMergedAsSubMenu)
  577.     {
  578.         ASSERT(iWidthIndex <= 5);   // servers should not touch past 5
  579.         lpMenuWidths[iWidthIndex] = cGroupWidth;
  580.     }
  581.  
  582.     return hHelpSubMenu;
  583. }
  584.  
  585. void AFXAPI AfxUnmergeMenus(HMENU hMenuShared, HMENU hMenuSource,
  586.     HMENU hHelpMenuPopup /* = NULL */)
  587. {
  588.     ASSERT(hMenuShared != NULL && WCE_FCTN(IsMenu)(hMenuShared));
  589.     ASSERT(hMenuSource != NULL && WCE_FCTN(IsMenu)(hMenuSource));
  590.     ASSERT(hHelpMenuPopup == NULL || WCE_FCTN(IsMenu)(hHelpMenuPopup));
  591.  
  592.     int cOurItems = WCE_FCTN(GetMenuItemCount)(hMenuSource);
  593.     int cMenuItems = WCE_FCTN(GetMenuItemCount)(hMenuShared);
  594.  
  595.     for (int i = cMenuItems-1; i >= 0; i--)
  596.     {
  597.         // check out the popup menus
  598.         HMENU hMenuPopup = ::GetSubMenu(hMenuShared, i);
  599.         if (hMenuPopup != NULL)
  600.         {
  601.             // if we have a Help submenu, check to see if it appears in this
  602.             // submenu someplace... this normally happens only in
  603.             // DocObject frame windows
  604.  
  605.             if (hHelpMenuPopup != NULL)
  606.             {
  607.                 int cPopupItems = ::WCE_FCTN(GetMenuItemCount)(hMenuPopup);
  608.                 for (int k = 0; k < cPopupItems; k++)
  609.                 {
  610.                     if (::GetSubMenu(hMenuPopup, k) == hHelpMenuPopup)
  611.                     {
  612.                         ::RemoveMenu(hMenuPopup, k, MF_BYPOSITION);
  613.                         hHelpMenuPopup = NULL;  // can only have one
  614.                         break;
  615.                     }
  616.                 }
  617.             }
  618.             else
  619.             {
  620.                 // if it is one of ours, remove it from the pMenuShared
  621.                 for (int j = 0; j < cOurItems; j++)
  622.                 {
  623.                     if (::GetSubMenu(hMenuSource, j) == hMenuPopup)
  624.                     {
  625.                         // remove the menu from pMenuShared
  626.                         RemoveMenu(hMenuShared, i, MF_BYPOSITION);
  627.                         break;
  628.                     }
  629.                 }
  630.             }
  631.         }
  632.     }
  633. }
  634.  
  635. // Helper for creating default FORMATETC from cfFormat
  636. LPFORMATETC AFXAPI _AfxFillFormatEtc(
  637.     LPFORMATETC lpFormatEtc, CLIPFORMAT cfFormat, LPFORMATETC lpFormatEtcFill)
  638. {
  639.     ASSERT(lpFormatEtcFill != NULL);
  640.     if (lpFormatEtc == NULL && cfFormat != 0)
  641.     {
  642.         lpFormatEtc = lpFormatEtcFill;
  643.         lpFormatEtc->cfFormat = cfFormat;
  644.         lpFormatEtc->ptd = NULL;
  645.         lpFormatEtc->dwAspect = DVASPECT_CONTENT;
  646.         lpFormatEtc->lindex = -1;
  647.         lpFormatEtc->tymed = (DWORD) -1;
  648.     }
  649.     return lpFormatEtc;
  650. }
  651.  
  652. AFX_STATIC HGLOBAL AFXAPI _AfxCopyGlobalMemory(HGLOBAL hDest, HGLOBAL hSource)
  653. {
  654.     ASSERT(hSource != NULL);
  655.  
  656.     // make sure we have suitable hDest
  657.     DWORD nSize = ::WCE_FCTN(GlobalSize)(hSource);
  658.     if (hDest == NULL)
  659.     {
  660.         hDest = ::WCE_FCTN(GlobalAlloc)(GMEM_SHARE|GMEM_MOVEABLE, nSize);
  661.         if (hDest == NULL)
  662.             return NULL;
  663.     }
  664.     else if (nSize > ::WCE_FCTN(GlobalSize)(hDest))
  665.     {
  666.         // hDest is not large enough
  667.         return NULL;
  668.     }
  669.  
  670.     // copy the bits
  671.     LPVOID lpSource = ::WCE_FCTN(GlobalLock)(hSource);
  672.     LPVOID lpDest = ::WCE_FCTN(GlobalLock)(hDest);
  673.     ASSERT(lpDest != NULL);
  674.     ASSERT(lpSource != NULL);
  675.     memcpy(lpDest, lpSource, nSize);
  676.     ::WCE_FCTN(GlobalUnlock)(hDest);
  677.     ::WCE_FCTN(GlobalUnlock)(hSource);
  678.  
  679.     // success -- return hDest
  680.     return hDest;
  681. }
  682.  
  683. BOOL AFXAPI _AfxCopyStgMedium(
  684.     CLIPFORMAT cfFormat, LPSTGMEDIUM lpDest, LPSTGMEDIUM lpSource)
  685. {
  686.     if (lpDest->tymed == TYMED_NULL)
  687.     {
  688.         ASSERT(lpSource->tymed != TYMED_NULL);
  689.         switch (lpSource->tymed)
  690.         {
  691.         case TYMED_ENHMF:
  692. #if defined(_WIN32_WCE)
  693. // WinCE: TYMED_ENHMF is not supported by the OS
  694.             ASSERT(FALSE);
  695. #endif // _WIN32_WCE
  696.         case TYMED_HGLOBAL:
  697.             ASSERT(sizeof(HGLOBAL) == sizeof(HENHMETAFILE));
  698.             lpDest->tymed = lpSource->tymed;
  699.             lpDest->hGlobal = NULL;
  700.             break;  // fall through to CopyGlobalMemory case
  701.  
  702.         case TYMED_ISTREAM:
  703.             lpDest->pstm = lpSource->pstm;
  704.             lpDest->pstm->AddRef();
  705.             lpDest->tymed = TYMED_ISTREAM;
  706.             return TRUE;
  707.  
  708.         case TYMED_ISTORAGE:
  709.             lpDest->pstg = lpSource->pstg;
  710.             lpDest->pstg->AddRef();
  711.             lpDest->tymed = TYMED_ISTORAGE;
  712.             return TRUE;
  713.  
  714.         case TYMED_MFPICT:
  715.             {
  716. #if defined(_WIN32_WCE)
  717.     // WinCE: TYMED_MFPICT is not supported by the OS
  718.     ASSERT(FALSE);
  719. #else // _WIN32_WCE
  720.                 // copy LPMETAFILEPICT struct + embedded HMETAFILE
  721.                 HGLOBAL hDest = _AfxCopyGlobalMemory(NULL, lpSource->hGlobal);
  722.                 if (hDest == NULL)
  723.                     return FALSE;
  724.                 LPMETAFILEPICT lpPict = (LPMETAFILEPICT)::WCE_FCTN(GlobalLock)(hDest);
  725.                 ASSERT(lpPict != NULL);
  726.                 lpPict->hMF = ::CopyMetaFile(lpPict->hMF, NULL);
  727.                 if (lpPict->hMF == NULL)
  728.                 {
  729.                     ::WCE_FCTN(GlobalUnlock)(hDest);
  730.                     ::GlobalFree(hDest);
  731.                     return FALSE;
  732.                 }
  733.                 ::WCE_FCTN(GlobalUnlock)(hDest);
  734.  
  735.                 // fill STGMEDIUM struct
  736.                 lpDest->hGlobal = hDest;
  737.                 lpDest->tymed = TYMED_MFPICT;
  738. #endif // _WIN32_WCE
  739.             }
  740.             return TRUE;
  741.  
  742.         case TYMED_GDI:
  743. #if defined(_WIN32_WCE)
  744. // WinCE: TYMED_GDI is not supported by the OS
  745.             ASSERT(FALSE);
  746. #else // _WIN32_WCE
  747.             lpDest->tymed = TYMED_GDI;
  748.             lpDest->hGlobal = NULL;
  749.             break;
  750. #endif // _WIN32_WCE
  751.  
  752.         case TYMED_FILE:
  753.             {
  754.                 USES_CONVERSION;
  755.                 lpDest->tymed = TYMED_FILE;
  756.                 ASSERT(lpSource->lpszFileName != NULL);
  757.                 UINT cbSrc = ocslen(lpSource->lpszFileName);
  758.                 LPOLESTR szFileName = (LPOLESTR)CoTaskMemAlloc(cbSrc*sizeof(OLECHAR));
  759.                 lpDest->lpszFileName = szFileName;
  760.                 if (szFileName == NULL)
  761.                     return FALSE;
  762.                 memcpy(szFileName, lpSource->lpszFileName,  (cbSrc+1)*sizeof(OLECHAR));
  763.                 return TRUE;
  764.             }
  765.  
  766.         // unable to create + copy other TYMEDs
  767.         default:
  768.             return FALSE;
  769.         }
  770.     }
  771.     ASSERT(lpDest->tymed == lpSource->tymed);
  772.  
  773.     switch (lpSource->tymed)
  774.     {
  775.     case TYMED_HGLOBAL:
  776.         {
  777.             HGLOBAL hDest = _AfxCopyGlobalMemory(lpDest->hGlobal,
  778.                 lpSource->hGlobal);
  779.             if (hDest == NULL)
  780.                 return FALSE;
  781.  
  782.             lpDest->hGlobal = hDest;
  783.         }
  784.         return TRUE;
  785.  
  786.     case TYMED_ISTREAM:
  787.         {
  788.             ASSERT(lpDest->pstm != NULL);
  789.             ASSERT(lpSource->pstm != NULL);
  790.  
  791.             // get the size of the source stream
  792.             STATSTG stat;
  793.             if (lpSource->pstm->Stat(&stat, STATFLAG_NONAME) != S_OK)
  794.             {
  795.                 // unable to get size of source stream
  796.                 return FALSE;
  797.             }
  798.             ASSERT(stat.pwcsName == NULL);
  799.  
  800.             // always seek to zero before copy
  801.             LARGE_INTEGER zero = { 0, 0 };
  802.             lpDest->pstm->Seek(zero, STREAM_SEEK_SET, NULL);
  803.             lpSource->pstm->Seek(zero, STREAM_SEEK_SET, NULL);
  804.  
  805.             // copy source to destination
  806.             if (lpSource->pstm->CopyTo(lpDest->pstm, stat.cbSize,
  807.                 NULL, NULL) != NULL)
  808.             {
  809.                 // copy from source to dest failed
  810.                 return FALSE;
  811.             }
  812.  
  813.             // always seek to zero after copy
  814.             lpDest->pstm->Seek(zero, STREAM_SEEK_SET, NULL);
  815.             lpSource->pstm->Seek(zero, STREAM_SEEK_SET, NULL);
  816.         }
  817.         return TRUE;
  818.  
  819.     case TYMED_ISTORAGE:
  820.         {
  821.             ASSERT(lpDest->pstg != NULL);
  822.             ASSERT(lpSource->pstg != NULL);
  823.  
  824.             // just copy source to destination
  825.             if (lpSource->pstg->CopyTo(0, NULL, NULL, lpDest->pstg) != S_OK)
  826.                 return FALSE;
  827.         }
  828.         return TRUE;
  829.  
  830.     case TYMED_FILE:
  831.         {
  832.             USES_CONVERSION;
  833.             ASSERT(lpSource->lpszFileName != NULL);
  834.             ASSERT(lpDest->lpszFileName != NULL);
  835.             return CopyFile(OLE2T(lpSource->lpszFileName), OLE2T(lpDest->lpszFileName), FALSE);
  836.         }
  837.  
  838.  
  839.     case TYMED_ENHMF:
  840.     case TYMED_GDI:
  841.         {
  842. #if defined(_WIN32_WCE)
  843. // WinCE: TYMED_ENHMF and TYMED_GDI are not supported by the OS
  844.             ASSERT(FALSE);
  845. #else // _WIN32_WCE
  846.             ASSERT(sizeof(HGLOBAL) == sizeof(HENHMETAFILE));
  847.  
  848.             // with TYMED_GDI cannot copy into existing HANDLE
  849.             if (lpDest->hGlobal != NULL)
  850.                 return FALSE;
  851.  
  852.             // otherwise, use OleDuplicateData for the copy
  853.             lpDest->hGlobal = OleDuplicateData(lpSource->hGlobal, cfFormat, 0);
  854.             if (lpDest->hGlobal == NULL)
  855.                 return FALSE;
  856. #endif // _WIN32_WCE
  857.         }
  858.         return TRUE;
  859.  
  860.     // other TYMEDs cannot be copied
  861.     default:
  862.         return FALSE;
  863.     }
  864. }
  865.  
  866. /////////////////////////////////////////////////////////////////////////////
  867. // OLE utility functions (some borrowed from OLE2UI library)
  868.  
  869. HGLOBAL AFXAPI _AfxOleGetObjectDescriptorData(
  870.     CLSID       clsid,
  871.     DWORD       dwDrawAspect,
  872.     SIZEL       sizel,
  873.     POINTL      pointl,
  874.     DWORD       dwStatus,
  875.     LPCOLESTR   lpszFullUserTypeName,
  876.     LPCOLESTR   lpszSrcOfCopy)
  877. {
  878.     HGLOBAL     hMem = NULL;
  879.     LPOBJECTDESCRIPTOR lpOD;
  880.     DWORD       dwObjectDescSize, dwFullUserTypeNameLen, dwSrcOfCopyLen;
  881.  
  882.     // Get the length of Full User Type Name; Add 1 for the null terminator
  883.     dwFullUserTypeNameLen = lpszFullUserTypeName ?
  884.         ocslen(lpszFullUserTypeName)+1 : 0;
  885.  
  886.     // Get the Source of Copy string and it's length;
  887.     //  Add 1 for the null terminator
  888.     if (lpszSrcOfCopy && lpszSrcOfCopy[0] != '\0')
  889.        dwSrcOfCopyLen = ocslen(lpszSrcOfCopy)+1;
  890.     else
  891.     {
  892.        // No src moniker so use user type name as source string.
  893.        lpszSrcOfCopy =  lpszFullUserTypeName;
  894.        dwSrcOfCopyLen = dwFullUserTypeNameLen;
  895.     }
  896.  
  897.     // Allocate space for OBJECTDESCRIPTOR and the additional string data
  898.     dwObjectDescSize = sizeof(OBJECTDESCRIPTOR);
  899.     hMem = WCE_FCTN(GlobalAlloc)(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT,
  900.        dwObjectDescSize + (dwFullUserTypeNameLen + dwSrcOfCopyLen) *
  901.         sizeof(OLECHAR));
  902.     if (!hMem)
  903.         return NULL;
  904.  
  905.     lpOD = (LPOBJECTDESCRIPTOR)WCE_FCTN(GlobalLock)(hMem);
  906.  
  907.     // Set the FullUserTypeName offset and copy the string
  908.     if (lpszFullUserTypeName)
  909.     {
  910.         lpOD->dwFullUserTypeName = dwObjectDescSize;
  911.         ocscpy((LPOLESTR)((LPBYTE)lpOD+lpOD->dwFullUserTypeName), lpszFullUserTypeName);
  912.     }
  913.     else
  914.         lpOD->dwFullUserTypeName = 0;  // zero offset indicates that string is not present
  915.  
  916.     // Set the SrcOfCopy offset and copy the string
  917.     if (lpszSrcOfCopy)
  918.     {
  919.         lpOD->dwSrcOfCopy = dwObjectDescSize + dwFullUserTypeNameLen * sizeof(OLECHAR);
  920.         ocscpy((LPOLESTR)((LPBYTE)lpOD+lpOD->dwSrcOfCopy), lpszSrcOfCopy);
  921.     }
  922.     else
  923.         lpOD->dwSrcOfCopy = 0;  // zero offset indicates that string is not present
  924.  
  925.     // Initialize the rest of the OBJECTDESCRIPTOR
  926.     lpOD->cbSize       = dwObjectDescSize +
  927.         (dwFullUserTypeNameLen + dwSrcOfCopyLen) * sizeof(OLECHAR);
  928.     lpOD->clsid        = clsid;
  929.     lpOD->dwDrawAspect = dwDrawAspect;
  930.     lpOD->sizel        = sizel;
  931.     lpOD->pointl       = pointl;
  932.     lpOD->dwStatus     = dwStatus;
  933.  
  934.     WCE_FCTN(GlobalUnlock)(hMem);
  935.     return hMem;
  936. }
  937.  
  938. HGLOBAL AFXAPI _AfxOleGetObjectDescriptorData(
  939.     LPOLEOBJECT     lpOleObj,
  940.     LPCOLESTR       lpszSrcOfCopy,
  941.     DWORD           dwDrawAspect,
  942.     POINTL          pointl,
  943.     LPSIZEL         lpSizelHim)
  944. {
  945.     USES_CONVERSION;
  946.  
  947.     CLSID           clsid;
  948.     LPOLESTR        lpszFullUserTypeName = NULL;
  949.     LPMONIKER       lpSrcMonikerOfCopy = NULL;
  950.     HGLOBAL         hObjDesc = NULL;
  951.     IBindCtx        *pbc = NULL;
  952.     SCODE           sc;
  953.     SIZEL           sizelHim;
  954.     BOOL            bFreeSrcOfCopy = FALSE;
  955.     LPVIEWOBJECT2   lpViewObj2;
  956.     LPOLELINK       lpOleLink;
  957.     BOOL            fIsLink;
  958.     TCHAR           szLinkedTypeFmt[80];
  959.     LPCOLESTR       lpszLinkedTypeFmt;
  960.     LPOLESTR        lpszBuf = NULL;
  961.     DWORD           dwStatus = 0;
  962.  
  963.     // query for IOleLink
  964.     lpOleLink = QUERYINTERFACE(lpOleObj, IOleLink);
  965.     fIsLink = lpOleLink != NULL;
  966.  
  967.     // query for IViewObject2
  968.     lpViewObj2 = QUERYINTERFACE(lpOleObj, IViewObject2);
  969.  
  970.     // Get CLSID
  971.     sc = lpOleObj->GetUserClassID(&clsid);
  972.     if (sc != S_OK)
  973.         clsid = CLSID_NULL;
  974.  
  975.     // Get FullUserTypeName
  976.     sc = lpOleObj->GetUserType(USERCLASSTYPE_FULL, &lpszFullUserTypeName);
  977.  
  978.     // if object is a link, then expand usertypename to be "Linked %s"
  979.     if (fIsLink && lpszFullUserTypeName != NULL)
  980.     {
  981.         // Note: If this LoadString call fails, it is likely that
  982.         //  _AFX_NO_OLE_RESOURCES is defined in your .RC file.
  983.         // To correct the situation remove the following line from your
  984.         //  resource script:
  985.         //      #define _AFX_NO_OLE_RESOURCES
  986.         // This should be done using the Resource.Set Includes... command.
  987.  
  988.         VERIFY(AfxLoadString(AFX_IDS_PASTELINKEDTYPE, szLinkedTypeFmt));
  989.         lpszLinkedTypeFmt = T2COLE(szLinkedTypeFmt);
  990.         lpszBuf = (LPOLESTR)CoTaskMemAlloc((ocslen(lpszFullUserTypeName) +
  991.             ocslen(lpszLinkedTypeFmt) + 1) * sizeof(OLECHAR));
  992.         if (lpszBuf != NULL)
  993.         {
  994. #ifdef OLE2ANSI
  995.             sprintf(lpszBuf, lpszLinkedTypeFmt, lpszFullUserTypeName);
  996. #else
  997.             swprintf(lpszBuf, lpszLinkedTypeFmt, lpszFullUserTypeName);
  998. #endif
  999.             CoTaskMemFree(lpszFullUserTypeName);
  1000.             lpszFullUserTypeName = lpszBuf;
  1001.         }
  1002.     }
  1003.  
  1004.     // get source of copy
  1005.     if (fIsLink)
  1006.     {
  1007.         sc = lpOleLink->GetSourceDisplayName((LPOLESTR*)&lpszSrcOfCopy);
  1008.         bFreeSrcOfCopy = TRUE;
  1009.     }
  1010.     else if (lpszSrcOfCopy == NULL)
  1011.     {
  1012.         sc = lpOleObj->GetMoniker(
  1013.             OLEGETMONIKER_TEMPFORUSER, OLEWHICHMK_OBJFULL, &lpSrcMonikerOfCopy);
  1014.         if (sc == S_OK)
  1015.         {
  1016. #if defined(_WIN32_WCE)
  1017.             TCHAR szUnspecifiedName[] = _T("Unspecified");
  1018.             lpszSrcOfCopy = (LPOLESTR)::CoTaskMemAlloc(sizeof(szUnspecifiedName));
  1019.             if(lpszSrcOfCopy != NULL)
  1020.                 _tcscpy((TCHAR*)lpszSrcOfCopy,szUnspecifiedName);
  1021. #else // _WIN32_WCE
  1022.             CreateBindCtx(0, &pbc);
  1023.             lpSrcMonikerOfCopy->GetDisplayName(pbc, NULL,
  1024.                 (LPOLESTR*)&lpszSrcOfCopy);
  1025.             RELEASE(pbc);
  1026.             bFreeSrcOfCopy = TRUE;
  1027. #endif // _WIN32_WCE
  1028.         }
  1029.     }
  1030.  
  1031.     if (lpSizelHim)
  1032.     {
  1033.         // Use extents passed by the caller
  1034.         sizelHim = *lpSizelHim;
  1035.     }
  1036.     else if (lpViewObj2)
  1037.     {
  1038.         // Get the current extents from the object
  1039.         sc = lpViewObj2->GetExtent(dwDrawAspect, -1, NULL,
  1040.             (LPSIZEL)&sizelHim);
  1041.         if (sc != S_OK)
  1042.             sizelHim.cx = sizelHim.cy = 0;
  1043.     }
  1044.     else
  1045.     {
  1046.         sizelHim.cx = sizelHim.cy = 0;
  1047.     }
  1048.  
  1049.     // Get dwStatus
  1050.     sc = lpOleObj->GetMiscStatus(dwDrawAspect, &dwStatus);
  1051.     if (sc != S_OK)
  1052.         dwStatus = 0;
  1053.  
  1054.     // Get OBJECTDESCRIPTOR
  1055.     hObjDesc = _AfxOleGetObjectDescriptorData(clsid, dwDrawAspect, sizelHim,
  1056.         pointl, dwStatus, lpszFullUserTypeName, lpszSrcOfCopy);
  1057.  
  1058.     // Clean up
  1059.     CoTaskMemFree(lpszFullUserTypeName);
  1060.     if (bFreeSrcOfCopy)
  1061.         CoTaskMemFree((LPOLESTR)lpszSrcOfCopy);
  1062.     RELEASE(lpSrcMonikerOfCopy);
  1063.     RELEASE(lpOleLink);
  1064.     RELEASE(lpViewObj2);
  1065.  
  1066.     return hObjDesc;
  1067. }
  1068.  
  1069. #if !defined(_WIN32_WCE)
  1070. SCODE AFXAPI _AfxOleDoConvert(LPSTORAGE lpStg, REFCLSID rClsidNew)
  1071. {
  1072.     SCODE sc;
  1073.     CLSID clsidOld;
  1074.     if ((sc = ReadClassStg(lpStg, &clsidOld)) != S_OK)
  1075.     {
  1076.         clsidOld = CLSID_NULL;
  1077.         return sc;
  1078.     }
  1079.  
  1080.     // read old fmt/old user type; sets out params to NULL on error
  1081.     CLIPFORMAT cfOld;
  1082.     LPOLESTR lpszOld = NULL;
  1083.     sc = ReadFmtUserTypeStg(lpStg, &cfOld, &lpszOld);
  1084.     ASSERT(sc == S_OK || (cfOld == 0 && lpszOld == NULL));
  1085.  
  1086.     // get new user type name; if error, set to NULL string
  1087.     OLECHAR chZero = 0;
  1088.     LPOLESTR lpszNew = NULL;
  1089.     if (OleRegGetUserType(rClsidNew, USERCLASSTYPE_FULL, &lpszNew) != S_OK)
  1090.         lpszNew = &chZero;
  1091.  
  1092.     // write class stg
  1093.     if ((sc = WriteClassStg(lpStg, rClsidNew)) != S_OK)
  1094.         goto ErrorReturn;
  1095.  
  1096.     // write old fmt/new user type;
  1097.     if ((sc = WriteFmtUserTypeStg(lpStg, cfOld, lpszNew)) != S_OK)
  1098.         goto RewriteInfo;
  1099.  
  1100.     // set convert bit
  1101.     if ((sc = SetConvertStg(lpStg, TRUE)) != S_OK)
  1102.         goto RewriteInfo;
  1103.  
  1104.     goto ErrorReturn;
  1105.  
  1106. RewriteInfo:
  1107.     WriteClassStg(lpStg, clsidOld);
  1108.     WriteFmtUserTypeStg(lpStg, cfOld, lpszOld);
  1109.  
  1110. ErrorReturn:
  1111.     if (lpszNew != &chZero)
  1112.         CoTaskMemFree(lpszNew);
  1113.  
  1114.     CoTaskMemFree(lpszOld);
  1115.     return sc;
  1116. }
  1117.  
  1118. SCODE AFXAPI _AfxOleDoTreatAsClass(
  1119.     LPCTSTR lpszUserType, REFCLSID rclsid, REFCLSID rclsidNew)
  1120. {
  1121.     LPTSTR  lpszCLSID = NULL;
  1122.     HKEY    hKey;
  1123.  
  1124.     SCODE sc = CoTreatAsClass(rclsid, rclsidNew);
  1125.     if (sc != S_OK && lpszUserType != NULL)
  1126.     {
  1127.         RegOpenKey(HKEY_CLASSES_ROOT, _T("CLSID"), &hKey);
  1128.         LPOLESTR lpOleStr = NULL;
  1129.         StringFromCLSID(rclsid, &lpOleStr);
  1130.         lpszCLSID = TASKSTRINGOLE2T(lpOleStr);
  1131.         RegSetValue(hKey, lpszCLSID, REG_SZ, lpszUserType,
  1132.             lstrlen(lpszUserType) * sizeof(TCHAR));
  1133.  
  1134.         CoTaskMemFree(lpszCLSID);
  1135.         sc = CoTreatAsClass(rclsid, rclsidNew);
  1136.         RegCloseKey(hKey);
  1137.     }
  1138.     return sc;
  1139. }
  1140.  
  1141. #define DEVNAMEPART(pdn, x) (pdn->x == 0 ? NULL : (LPCTSTR)pdn + pdn->x)
  1142.  
  1143. DVTARGETDEVICE* AFXAPI _AfxOleCreateTargetDevice(LPDEVNAMES pDN, LPDEVMODE pDM)
  1144. {
  1145.     USES_CONVERSION;
  1146.  
  1147.     DVTARGETDEVICE* ptd = NULL;
  1148.     DWORD dwDevNamesSize, dwDevModeSize, dwPtdSize;
  1149.  
  1150.     LPCTSTR lpszDriverName = DEVNAMEPART(pDN, wDriverOffset);
  1151.     LPCTSTR lpszDeviceName = DEVNAMEPART(pDN, wDeviceOffset);
  1152.     LPCTSTR lpszPortName = DEVNAMEPART(pDN, wOutputOffset);
  1153.  
  1154.     LPCOLESTR lpszDriverNameOle = T2COLE(lpszDriverName);
  1155.     LPCOLESTR lpszDeviceNameOle = T2COLE(lpszDeviceName);
  1156.     LPCOLESTR lpszPortNameOle = T2COLE(lpszPortName);
  1157.     int nDriverNameSize = (lpszDriverNameOle == NULL) ? 0 : (ocslen(lpszDriverNameOle)+1)*sizeof(OLECHAR);
  1158.     int nDeviceNameSize = (lpszDeviceNameOle == NULL) ? 0 : (ocslen(lpszDeviceNameOle)+1)*sizeof(OLECHAR);
  1159.     int nPortNameSize = (lpszPortNameOle == NULL) ? 0 : (ocslen(lpszPortNameOle)+1)*sizeof(OLECHAR);
  1160.  
  1161.     LPDEVMODEOLE lpDevModeOle = DEVMODET2OLE(pDM);
  1162.  
  1163.     dwDevNamesSize = nDriverNameSize + nDeviceNameSize + nPortNameSize;
  1164.     dwDevModeSize = (DWORD)(lpDevModeOle->dmSize + lpDevModeOle->dmDriverExtra);
  1165.  
  1166.     dwPtdSize = sizeof(DVTARGETDEVICE) + dwDevNamesSize + dwDevModeSize;
  1167.  
  1168.     if ((ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(dwPtdSize)) != NULL)
  1169.     {
  1170.         // copy in the info
  1171.         ptd->tdSize = (UINT)dwPtdSize;
  1172.  
  1173.         ptd->tdDriverNameOffset = sizeof(DVTARGETDEVICE);
  1174.         ocscpy((LPOLESTR)((BYTE*)ptd + ptd->tdDriverNameOffset), lpszDriverNameOle);
  1175.         ptd->tdDeviceNameOffset = (WORD)(ptd->tdDriverNameOffset + nDriverNameSize);
  1176.         ocscpy((LPOLESTR)((BYTE*)ptd + ptd->tdDeviceNameOffset), lpszDeviceNameOle);
  1177.         ptd->tdPortNameOffset = (WORD)(ptd->tdDeviceNameOffset + nDeviceNameSize);
  1178.         ocscpy((LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset), lpszPortNameOle);
  1179.         ptd->tdExtDevmodeOffset = (WORD)(ptd->tdPortNameOffset + nPortNameSize);
  1180.         memcpy((BYTE*)ptd + ptd->tdExtDevmodeOffset, lpDevModeOle,
  1181.             sizeof(DEVMODEOLE)+lpDevModeOle->dmDriverExtra);
  1182.     }
  1183.     return ptd;
  1184. }
  1185.  
  1186. DVTARGETDEVICE* AFXAPI _AfxOleCreateTargetDevice(LPPRINTDLG lpPrintDlg)
  1187. {
  1188.     DVTARGETDEVICE* ptd=NULL;
  1189.     LPDEVNAMES pDN;
  1190.     LPDEVMODE pDM;
  1191.  
  1192.     if ((pDN = (LPDEVNAMES)WCE_FCTN(GlobalLock)(lpPrintDlg->hDevNames)) == NULL)
  1193.         return NULL;
  1194.  
  1195.     if ((pDM = (LPDEVMODE)WCE_FCTN(GlobalLock)(lpPrintDlg->hDevMode)) == NULL)
  1196.     {
  1197.         WCE_FCTN(GlobalUnlock)(lpPrintDlg->hDevNames);
  1198.         return NULL;
  1199.     }
  1200.  
  1201.     ptd = _AfxOleCreateTargetDevice(pDN, pDM);
  1202.  
  1203.     WCE_FCTN(GlobalUnlock)(lpPrintDlg->hDevNames);
  1204.     WCE_FCTN(GlobalUnlock)(lpPrintDlg->hDevMode);
  1205.  
  1206.     return ptd;
  1207. }
  1208.  
  1209. LPMONIKER AFXAPI _AfxOleGetFirstMoniker(LPMONIKER lpmk)
  1210. {
  1211.     if (lpmk == NULL)
  1212.         return NULL;
  1213.  
  1214.     DWORD dwMksys;
  1215.     if (lpmk->IsSystemMoniker(&dwMksys) == S_OK
  1216.         && dwMksys == MKSYS_GENERICCOMPOSITE)
  1217.     {
  1218.         LPENUMMONIKER lpenumMoniker = NULL;
  1219.         SCODE sc = lpmk->Enum(TRUE, &lpenumMoniker);
  1220.         if (sc != S_OK)
  1221.             return NULL;
  1222.  
  1223.         ASSERT(lpenumMoniker != NULL);
  1224.         LPMONIKER lpmkFirst = NULL;
  1225.         sc = lpenumMoniker->Next(1, &lpmkFirst, NULL);
  1226.         RELEASE(lpenumMoniker);
  1227.         return lpmkFirst;
  1228.     }
  1229.  
  1230.     // otherwise -- return the moniker itself
  1231.     lpmk->AddRef();
  1232.     return lpmk;
  1233. }
  1234.  
  1235. DWORD AFXAPI _AfxOleGetLenFilePrefixOfMoniker(LPMONIKER lpmk)
  1236. {
  1237.     USES_CONVERSION;
  1238.  
  1239.     if (lpmk == NULL)
  1240.         return 0;
  1241.  
  1242.     DWORD nLen = 0;
  1243.     LPMONIKER lpmkFirst = _AfxOleGetFirstMoniker(lpmk);
  1244.     if (lpmkFirst != NULL)
  1245.     {
  1246.         DWORD  dwMksys;
  1247.         if (lpmkFirst->IsSystemMoniker(&dwMksys) == S_OK &&
  1248.             dwMksys == MKSYS_FILEMONIKER)
  1249.         {
  1250.             LPBC lpbc = NULL;
  1251.             SCODE sc = CreateBindCtx(0, &lpbc);
  1252.             if (sc == S_OK)
  1253.             {
  1254.                 LPOLESTR lpw = NULL;
  1255.                 sc = lpmkFirst->GetDisplayName(lpbc, NULL, &lpw);
  1256.                 LPTSTR lpsz = OLE2T(lpw);
  1257.                 if (sc == S_OK && lpsz != NULL)
  1258.                 {
  1259.                     nLen = lstrlen(lpsz);
  1260.                     CoTaskMemFree(lpw);
  1261.                 }
  1262.                 RELEASE(lpbc);
  1263.             }
  1264.         }
  1265.         RELEASE(lpmkFirst);
  1266.     }
  1267.     return nLen;
  1268. }
  1269.  
  1270. DVTARGETDEVICE* AFXAPI _AfxOleCopyTargetDevice(DVTARGETDEVICE* ptdSrc)
  1271. {
  1272.     if (ptdSrc == NULL)
  1273.         return NULL;
  1274.  
  1275.     DVTARGETDEVICE* ptdDest =
  1276.         (DVTARGETDEVICE*)CoTaskMemAlloc(ptdSrc->tdSize);
  1277.     if (ptdDest == NULL)
  1278.         return NULL;
  1279.  
  1280.     memcpy(ptdDest, ptdSrc, (size_t)ptdSrc->tdSize);
  1281.     return ptdDest;
  1282. }
  1283.  
  1284. void AFXAPI _AfxOleCopyFormatEtc(LPFORMATETC petcDest, LPFORMATETC petcSrc)
  1285. {
  1286.     ASSERT(petcDest != NULL);
  1287.     ASSERT(petcSrc != NULL);
  1288.  
  1289.     petcDest->cfFormat = petcSrc->cfFormat;
  1290.     petcDest->ptd = _AfxOleCopyTargetDevice(petcSrc->ptd);
  1291.     petcDest->dwAspect = petcSrc->dwAspect;
  1292.     petcDest->lindex = petcSrc->lindex;
  1293.     petcDest->tymed = petcSrc->tymed;
  1294. }
  1295.  
  1296. HDC WINAPI _AfxOleCreateDC(DVTARGETDEVICE* ptd)
  1297. {
  1298.     USES_CONVERSION;
  1299.  
  1300.     // return screen DC for NULL target device
  1301.     if (ptd == NULL)
  1302.         return ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
  1303.  
  1304.     LPDEVMODEOLE lpDevMode;
  1305.     LPOLESTR lpszDriverName;
  1306.     LPOLESTR lpszDeviceName;
  1307.     LPOLESTR lpszPortName;
  1308.  
  1309.     if (ptd->tdExtDevmodeOffset == 0)
  1310.         lpDevMode = NULL;
  1311.     else
  1312.         lpDevMode  = (LPDEVMODEOLE) ((LPSTR)ptd + ptd->tdExtDevmodeOffset);
  1313.  
  1314.     lpszDriverName = (LPOLESTR)((BYTE*)ptd + ptd->tdDriverNameOffset);
  1315.     lpszDeviceName = (LPOLESTR)((BYTE*)ptd + ptd->tdDeviceNameOffset);
  1316.     lpszPortName   = (LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset);
  1317.  
  1318.     return ::CreateDC(OLE2CT(lpszDriverName), OLE2CT(lpszDeviceName),
  1319.         OLE2CT(lpszPortName), DEVMODEOLE2T(lpDevMode));
  1320. }
  1321.  
  1322. void AFXAPI _AfxDeleteMetafilePict(HGLOBAL hMetaPict)
  1323. {
  1324.     if (hMetaPict != NULL)
  1325.     {
  1326.         STGMEDIUM stgMedium;
  1327.         stgMedium.hGlobal = hMetaPict;
  1328.         stgMedium.tymed = TYMED_MFPICT;
  1329.         stgMedium.pUnkForRelease = NULL;
  1330.         WCE_FCTN(ReleaseStgMedium)(&stgMedium);
  1331.     }
  1332. }
  1333. #endif // _WIN32_WCE
  1334.  
  1335. #define HIMETRIC_PER_INCH   2540
  1336. #define MAP_PIX_TO_LOGHIM(x,ppli)   WCE_FCTN(MulDiv)(HIMETRIC_PER_INCH, (x), (ppli))
  1337. #define MAP_LOGHIM_TO_PIX(x,ppli)   WCE_FCTN(MulDiv)((ppli), (x), HIMETRIC_PER_INCH)
  1338.  
  1339. void AFXAPI _AfxXformSizeInPixelsToHimetric(
  1340.     HDC hDC, LPSIZEL lpSizeInPix, LPSIZEL lpSizeInHiMetric)
  1341. {
  1342.     int cxPPI;
  1343.     int cyPPI;
  1344.  
  1345.     if ((NULL == hDC) || (GetDeviceCaps(hDC, LOGPIXELSX) == 0))
  1346.     {
  1347.         cxPPI = afxData.cxPixelsPerInch;
  1348.         cyPPI = afxData.cyPixelsPerInch;
  1349.     }
  1350.     else
  1351.     {
  1352.         cxPPI = GetDeviceCaps(hDC, LOGPIXELSX);
  1353.         cyPPI = GetDeviceCaps(hDC, LOGPIXELSY);
  1354.     }
  1355.  
  1356.     lpSizeInHiMetric->cx = (long)MAP_PIX_TO_LOGHIM((int)lpSizeInPix->cx, cxPPI);
  1357.     lpSizeInHiMetric->cy = (long)MAP_PIX_TO_LOGHIM((int)lpSizeInPix->cy, cyPPI);
  1358. }
  1359.  
  1360. void AFXAPI _AfxXformSizeInHimetricToPixels(
  1361.     HDC hDC, LPSIZEL lpSizeInHiMetric, LPSIZEL lpSizeInPix)
  1362. {
  1363.     int cxPPI;
  1364.     int cyPPI;
  1365.  
  1366.     if ((NULL == hDC) || (GetDeviceCaps(hDC, LOGPIXELSX) == 0))
  1367.     {
  1368.         cxPPI = afxData.cxPixelsPerInch;
  1369.         cyPPI = afxData.cyPixelsPerInch;
  1370.     }
  1371.     else
  1372.     {
  1373.         cxPPI = GetDeviceCaps(hDC, LOGPIXELSX);
  1374.         cyPPI = GetDeviceCaps(hDC, LOGPIXELSY);
  1375.     }
  1376.  
  1377.     lpSizeInPix->cx = (long)MAP_LOGHIM_TO_PIX((int)lpSizeInHiMetric->cx, cxPPI);
  1378.     lpSizeInPix->cy = (long)MAP_LOGHIM_TO_PIX((int)lpSizeInHiMetric->cy, cyPPI);
  1379. }
  1380.  
  1381. #ifdef AFX_INIT_SEG
  1382. #pragma code_seg(AFX_INIT_SEG)
  1383. #endif
  1384.  
  1385. IMPLEMENT_DYNAMIC(COleException, CException)
  1386.  
  1387. /////////////////////////////////////////////////////////////////////////////
  1388.