home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / oleview / iviewers / util.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  24.2 KB  |  715 lines

  1. // util.cpp
  2.  
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "stdafx.h"
  14. #include "util.h"
  15. #include "shadow.h"
  16. /////
  17. // Utility functions
  18. //
  19. static TCHAR szBold[]       = _T("Bold") ;
  20. static TCHAR szItalic[]      = _T("Italic") ;
  21. static TCHAR szBoldItalic[]  = _T("Bold Italic") ;
  22. static TCHAR szRegular[]     = _T("Regular") ;
  23.  
  24. void ErrorMessage( const CString& str, HRESULT hr )
  25. {
  26.     LPVOID lpMessageBuffer = NULL ;
  27.     if (FormatMessage(
  28.           FORMAT_MESSAGE_ALLOCATE_BUFFER |
  29.           FORMAT_MESSAGE_FROM_SYSTEM,
  30.           NULL,
  31.           GetScode(hr),
  32.           MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  33.           (LPTSTR) &lpMessageBuffer,
  34.           0,
  35.           NULL ))
  36.     {
  37.         CString str2 ;
  38.         str2.Format( _T("\n%s %s"), (LPCTSTR)lpMessageBuffer, (LPCTSTR)HRtoString(hr) ) ;
  39.         str2 = str + str2 ;
  40.         LocalFree(lpMessageBuffer) ;
  41.         AfxMessageBox( str2 ) ;
  42.     }
  43.     else
  44.     {
  45.         CString str2 ;
  46.         str2.Format( _T("\n<No system message defined> %s"), (LPCTSTR)HRtoString(hr) ) ;
  47.         str2 = str + str2 ;
  48.         AfxMessageBox( str2 ) ;
  49.     }
  50. }
  51.  
  52. // Stolen from OLEMISC.CPP in the MFC 3.0 source.  Function names
  53. // changed from Afx* to _*.
  54. //
  55. #define _countof(array) (sizeof(array)/sizeof(array[0]))
  56. LPCTSTR AFXAPI _GetScodeString(SCODE sc)
  57. {
  58.     struct SCODE_ENTRY
  59.     {
  60.         SCODE sc;
  61.         LPCTSTR lpszName;
  62.     };
  63.     #define MAKE_SCODE_ENTRY(sc)    { sc, _T(#sc) }
  64.     static const SCODE_ENTRY scNameTable[] =
  65.     {
  66.         MAKE_SCODE_ENTRY(S_OK),
  67.         MAKE_SCODE_ENTRY(S_FALSE),
  68.  
  69.         MAKE_SCODE_ENTRY(CACHE_S_FORMATETC_NOTSUPPORTED),
  70.         MAKE_SCODE_ENTRY(CACHE_S_SAMECACHE),
  71.         MAKE_SCODE_ENTRY(CACHE_S_SOMECACHES_NOTUPDATED),
  72.         MAKE_SCODE_ENTRY(CONVERT10_S_NO_PRESENTATION),
  73.         MAKE_SCODE_ENTRY(DATA_S_SAMEFORMATETC),
  74.         MAKE_SCODE_ENTRY(DRAGDROP_S_CANCEL),
  75.         MAKE_SCODE_ENTRY(DRAGDROP_S_DROP),
  76.         MAKE_SCODE_ENTRY(DRAGDROP_S_USEDEFAULTCURSORS),
  77.         MAKE_SCODE_ENTRY(INPLACE_S_TRUNCATED),
  78.         MAKE_SCODE_ENTRY(MK_S_HIM),
  79.         MAKE_SCODE_ENTRY(MK_S_ME),
  80.         MAKE_SCODE_ENTRY(MK_S_MONIKERALREADYREGISTERED),
  81.         MAKE_SCODE_ENTRY(MK_S_REDUCED_TO_SELF),
  82.         MAKE_SCODE_ENTRY(MK_S_US),
  83.         MAKE_SCODE_ENTRY(OLE_S_MAC_CLIPFORMAT),
  84.         MAKE_SCODE_ENTRY(OLE_S_STATIC),
  85.         MAKE_SCODE_ENTRY(OLE_S_USEREG),
  86.         MAKE_SCODE_ENTRY(OLEOBJ_S_CANNOT_DOVERB_NOW),
  87.         MAKE_SCODE_ENTRY(OLEOBJ_S_INVALIDHWND),
  88.         MAKE_SCODE_ENTRY(OLEOBJ_S_INVALIDVERB),
  89.         MAKE_SCODE_ENTRY(OLEOBJ_S_LAST),
  90.         MAKE_SCODE_ENTRY(STG_S_CONVERTED),
  91.         MAKE_SCODE_ENTRY(VIEW_S_ALREADY_FROZEN),
  92.  
  93.         MAKE_SCODE_ENTRY(E_UNEXPECTED),
  94.         MAKE_SCODE_ENTRY(E_NOTIMPL),
  95.         MAKE_SCODE_ENTRY(E_OUTOFMEMORY),
  96.         MAKE_SCODE_ENTRY(E_INVALIDARG),
  97.         MAKE_SCODE_ENTRY(E_NOINTERFACE),
  98.         MAKE_SCODE_ENTRY(E_POINTER),
  99.         MAKE_SCODE_ENTRY(E_HANDLE),
  100.         MAKE_SCODE_ENTRY(E_ABORT),
  101.         MAKE_SCODE_ENTRY(E_FAIL),
  102.         MAKE_SCODE_ENTRY(E_ACCESSDENIED),
  103.  
  104.         MAKE_SCODE_ENTRY(CACHE_E_NOCACHE_UPDATED),
  105.         MAKE_SCODE_ENTRY(CLASS_E_CLASSNOTAVAILABLE),
  106.         MAKE_SCODE_ENTRY(CLASS_E_NOAGGREGATION),
  107.         MAKE_SCODE_ENTRY(CLIPBRD_E_BAD_DATA),
  108.         MAKE_SCODE_ENTRY(CLIPBRD_E_CANT_CLOSE),
  109.         MAKE_SCODE_ENTRY(CLIPBRD_E_CANT_EMPTY),
  110.         MAKE_SCODE_ENTRY(CLIPBRD_E_CANT_OPEN),
  111.         MAKE_SCODE_ENTRY(CLIPBRD_E_CANT_SET),
  112.         MAKE_SCODE_ENTRY(CO_E_ALREADYINITIALIZED),
  113.         MAKE_SCODE_ENTRY(CO_E_APPDIDNTREG),
  114.         MAKE_SCODE_ENTRY(CO_E_APPNOTFOUND),
  115.         MAKE_SCODE_ENTRY(CO_E_APPSINGLEUSE),
  116.         MAKE_SCODE_ENTRY(CO_E_BAD_PATH),
  117.         MAKE_SCODE_ENTRY(CO_E_CANTDETERMINECLASS),
  118.         MAKE_SCODE_ENTRY(CO_E_CLASS_CREATE_FAILED),
  119.         MAKE_SCODE_ENTRY(CO_E_CLASSSTRING),
  120.         MAKE_SCODE_ENTRY(CO_E_DLLNOTFOUND),
  121.         MAKE_SCODE_ENTRY(CO_E_ERRORINAPP),
  122.         MAKE_SCODE_ENTRY(CO_E_ERRORINDLL),
  123.         MAKE_SCODE_ENTRY(CO_E_IIDSTRING),
  124.         MAKE_SCODE_ENTRY(CO_E_NOTINITIALIZED),
  125.         MAKE_SCODE_ENTRY(CO_E_OBJISREG),
  126.         MAKE_SCODE_ENTRY(CO_E_OBJNOTCONNECTED),
  127.         MAKE_SCODE_ENTRY(CO_E_OBJNOTREG),
  128.         MAKE_SCODE_ENTRY(CO_E_OBJSRV_RPC_FAILURE),
  129.         MAKE_SCODE_ENTRY(CO_E_SCM_ERROR),
  130.         MAKE_SCODE_ENTRY(CO_E_SCM_RPC_FAILURE),
  131.         MAKE_SCODE_ENTRY(CO_E_SERVER_EXEC_FAILURE),
  132.         MAKE_SCODE_ENTRY(CO_E_SERVER_STOPPING),
  133.         MAKE_SCODE_ENTRY(CO_E_WRONGOSFORAPP),
  134.         MAKE_SCODE_ENTRY(CONVERT10_E_OLESTREAM_BITMAP_TO_DIB),
  135.         MAKE_SCODE_ENTRY(CONVERT10_E_OLESTREAM_FMT),
  136.         MAKE_SCODE_ENTRY(CONVERT10_E_OLESTREAM_GET),
  137.         MAKE_SCODE_ENTRY(CONVERT10_E_OLESTREAM_PUT),
  138.         MAKE_SCODE_ENTRY(CONVERT10_E_STG_DIB_TO_BITMAP),
  139.         MAKE_SCODE_ENTRY(CONVERT10_E_STG_FMT),
  140.         MAKE_SCODE_ENTRY(CONVERT10_E_STG_NO_STD_STREAM),
  141.         MAKE_SCODE_ENTRY(DISP_E_ARRAYISLOCKED),
  142.         MAKE_SCODE_ENTRY(DISP_E_BADCALLEE),
  143.         MAKE_SCODE_ENTRY(DISP_E_BADINDEX),
  144.         MAKE_SCODE_ENTRY(DISP_E_BADPARAMCOUNT),
  145.         MAKE_SCODE_ENTRY(DISP_E_BADVARTYPE),
  146.         MAKE_SCODE_ENTRY(DISP_E_EXCEPTION),
  147.         MAKE_SCODE_ENTRY(DISP_E_MEMBERNOTFOUND),
  148.         MAKE_SCODE_ENTRY(DISP_E_NONAMEDARGS),
  149.         MAKE_SCODE_ENTRY(DISP_E_NOTACOLLECTION),
  150.         MAKE_SCODE_ENTRY(DISP_E_OVERFLOW),
  151.         MAKE_SCODE_ENTRY(DISP_E_PARAMNOTFOUND),
  152.         MAKE_SCODE_ENTRY(DISP_E_PARAMNOTOPTIONAL),
  153.         MAKE_SCODE_ENTRY(DISP_E_TYPEMISMATCH),
  154.         MAKE_SCODE_ENTRY(DISP_E_UNKNOWNINTERFACE),
  155.         MAKE_SCODE_ENTRY(DISP_E_UNKNOWNLCID),
  156.         MAKE_SCODE_ENTRY(DISP_E_UNKNOWNNAME),
  157.         MAKE_SCODE_ENTRY(DRAGDROP_E_ALREADYREGISTERED),
  158.         MAKE_SCODE_ENTRY(DRAGDROP_E_INVALIDHWND),
  159.         MAKE_SCODE_ENTRY(DRAGDROP_E_NOTREGISTERED),
  160.         MAKE_SCODE_ENTRY(DV_E_CLIPFORMAT),
  161.         MAKE_SCODE_ENTRY(DV_E_DVASPECT),
  162.         MAKE_SCODE_ENTRY(DV_E_DVTARGETDEVICE),
  163.         MAKE_SCODE_ENTRY(DV_E_DVTARGETDEVICE_SIZE),
  164.         MAKE_SCODE_ENTRY(DV_E_FORMATETC),
  165.         MAKE_SCODE_ENTRY(DV_E_LINDEX),
  166.         MAKE_SCODE_ENTRY(DV_E_NOIVIEWOBJECT),
  167.         MAKE_SCODE_ENTRY(DV_E_STATDATA),
  168.         MAKE_SCODE_ENTRY(DV_E_STGMEDIUM),
  169.         MAKE_SCODE_ENTRY(DV_E_TYMED),
  170.         MAKE_SCODE_ENTRY(INPLACE_E_NOTOOLSPACE),
  171.         MAKE_SCODE_ENTRY(INPLACE_E_NOTUNDOABLE),
  172.         MAKE_SCODE_ENTRY(MEM_E_INVALID_LINK),
  173.         MAKE_SCODE_ENTRY(MEM_E_INVALID_ROOT),
  174.         MAKE_SCODE_ENTRY(MEM_E_INVALID_SIZE),
  175.         MAKE_SCODE_ENTRY(MK_E_CANTOPENFILE),
  176.         MAKE_SCODE_ENTRY(MK_E_CONNECTMANUALLY),
  177.         MAKE_SCODE_ENTRY(MK_E_ENUMERATION_FAILED),
  178.         MAKE_SCODE_ENTRY(MK_E_EXCEEDEDDEADLINE),
  179.         MAKE_SCODE_ENTRY(MK_E_INTERMEDIATEINTERFACENOTSUPPORTED),
  180.         MAKE_SCODE_ENTRY(MK_E_INVALIDEXTENSION),
  181.         MAKE_SCODE_ENTRY(MK_E_MUSTBOTHERUSER),
  182.         MAKE_SCODE_ENTRY(MK_E_NEEDGENERIC),
  183.         MAKE_SCODE_ENTRY(MK_E_NO_NORMALIZED),
  184.         MAKE_SCODE_ENTRY(MK_E_NOINVERSE),
  185.         MAKE_SCODE_ENTRY(MK_E_NOOBJECT),
  186.         MAKE_SCODE_ENTRY(MK_E_NOPREFIX),
  187.         MAKE_SCODE_ENTRY(MK_E_NOSTORAGE),
  188.         MAKE_SCODE_ENTRY(MK_E_NOTBINDABLE),
  189.         MAKE_SCODE_ENTRY(MK_E_NOTBOUND),
  190.         MAKE_SCODE_ENTRY(MK_E_SYNTAX),
  191.         MAKE_SCODE_ENTRY(MK_E_UNAVAILABLE),
  192.         MAKE_SCODE_ENTRY(OLE_E_ADVF),
  193.         MAKE_SCODE_ENTRY(OLE_E_ADVISENOTSUPPORTED),
  194.         MAKE_SCODE_ENTRY(OLE_E_BLANK),
  195.         MAKE_SCODE_ENTRY(OLE_E_CANT_BINDTOSOURCE),
  196.         MAKE_SCODE_ENTRY(OLE_E_CANT_GETMONIKER),
  197.         MAKE_SCODE_ENTRY(OLE_E_CANTCONVERT),
  198.         MAKE_SCODE_ENTRY(OLE_E_CLASSDIFF),
  199.         MAKE_SCODE_ENTRY(OLE_E_ENUM_NOMORE),
  200.         MAKE_SCODE_ENTRY(OLE_E_INVALIDHWND),
  201.         MAKE_SCODE_ENTRY(OLE_E_INVALIDRECT),
  202.         MAKE_SCODE_ENTRY(OLE_E_NOCACHE),
  203.         MAKE_SCODE_ENTRY(OLE_E_NOCONNECTION),
  204.         MAKE_SCODE_ENTRY(OLE_E_NOSTORAGE),
  205.         MAKE_SCODE_ENTRY(OLE_E_NOT_INPLACEACTIVE),
  206.         MAKE_SCODE_ENTRY(OLE_E_NOTRUNNING),
  207.         MAKE_SCODE_ENTRY(OLE_E_OLEVERB),
  208.         MAKE_SCODE_ENTRY(OLE_E_PROMPTSAVECANCELLED),
  209.         MAKE_SCODE_ENTRY(OLE_E_STATIC),
  210.         MAKE_SCODE_ENTRY(OLE_E_WRONGCOMPOBJ),
  211.         MAKE_SCODE_ENTRY(OLEOBJ_E_INVALIDVERB),
  212.         MAKE_SCODE_ENTRY(OLEOBJ_E_NOVERBS),
  213.         MAKE_SCODE_ENTRY(REGDB_E_CLASSNOTREG),
  214.         MAKE_SCODE_ENTRY(REGDB_E_IIDNOTREG),
  215.         MAKE_SCODE_ENTRY(REGDB_E_INVALIDVALUE),
  216.         MAKE_SCODE_ENTRY(REGDB_E_KEYMISSING),
  217.         MAKE_SCODE_ENTRY(REGDB_E_READREGDB),
  218.         MAKE_SCODE_ENTRY(REGDB_E_WRITEREGDB),
  219.         MAKE_SCODE_ENTRY(RPC_E_ATTEMPTED_MULTITHREAD),
  220.         MAKE_SCODE_ENTRY(RPC_E_CALL_CANCELED),
  221.         MAKE_SCODE_ENTRY(RPC_E_CALL_REJECTED),
  222.         MAKE_SCODE_ENTRY(RPC_E_CANTCALLOUT_AGAIN),
  223.         MAKE_SCODE_ENTRY(RPC_E_CANTCALLOUT_INASYNCCALL),
  224.         MAKE_SCODE_ENTRY(RPC_E_CANTCALLOUT_INEXTERNALCALL),
  225.         MAKE_SCODE_ENTRY(RPC_E_CANTCALLOUT_ININPUTSYNCCALL),
  226.         MAKE_SCODE_ENTRY(RPC_E_CANTPOST_INSENDCALL),
  227.         MAKE_SCODE_ENTRY(RPC_E_CANTTRANSMIT_CALL),
  228.         MAKE_SCODE_ENTRY(RPC_E_CHANGED_MODE),
  229.         MAKE_SCODE_ENTRY(RPC_E_CLIENT_CANTMARSHAL_DATA),
  230.         MAKE_SCODE_ENTRY(RPC_E_CLIENT_CANTUNMARSHAL_DATA),
  231.         MAKE_SCODE_ENTRY(RPC_E_CLIENT_DIED),
  232.         MAKE_SCODE_ENTRY(RPC_E_CONNECTION_TERMINATED),
  233.         MAKE_SCODE_ENTRY(RPC_E_DISCONNECTED),
  234.         MAKE_SCODE_ENTRY(RPC_E_FAULT),
  235.         MAKE_SCODE_ENTRY(RPC_E_INVALID_CALLDATA),
  236.         MAKE_SCODE_ENTRY(RPC_E_INVALID_DATA),
  237.         MAKE_SCODE_ENTRY(RPC_E_INVALID_DATAPACKET),
  238.         MAKE_SCODE_ENTRY(RPC_E_INVALID_PARAMETER),
  239.         MAKE_SCODE_ENTRY(RPC_E_INVALIDMETHOD),
  240.         MAKE_SCODE_ENTRY(RPC_E_NOT_REGISTERED),
  241.         MAKE_SCODE_ENTRY(RPC_E_OUT_OF_RESOURCES),
  242.         MAKE_SCODE_ENTRY(RPC_E_RETRY),
  243.         MAKE_SCODE_ENTRY(RPC_E_SERVER_CANTMARSHAL_DATA),
  244.         MAKE_SCODE_ENTRY(RPC_E_SERVER_CANTUNMARSHAL_DATA),
  245.         MAKE_SCODE_ENTRY(RPC_E_SERVER_DIED),
  246.         MAKE_SCODE_ENTRY(RPC_E_SERVER_DIED_DNE),
  247.         MAKE_SCODE_ENTRY(RPC_E_SERVERCALL_REJECTED),
  248.         MAKE_SCODE_ENTRY(RPC_E_SERVERCALL_RETRYLATER),
  249.         MAKE_SCODE_ENTRY(RPC_E_SERVERFAULT),
  250.         MAKE_SCODE_ENTRY(RPC_E_SYS_CALL_FAILED),
  251.         MAKE_SCODE_ENTRY(RPC_E_THREAD_NOT_INIT),
  252.         MAKE_SCODE_ENTRY(RPC_E_UNEXPECTED),
  253.         MAKE_SCODE_ENTRY(RPC_E_WRONG_THREAD),
  254.         MAKE_SCODE_ENTRY(STG_E_ABNORMALAPIEXIT),
  255.         MAKE_SCODE_ENTRY(STG_E_ACCESSDENIED),
  256.         MAKE_SCODE_ENTRY(STG_E_CANTSAVE),
  257.         MAKE_SCODE_ENTRY(STG_E_DISKISWRITEPROTECTED),
  258.         MAKE_SCODE_ENTRY(STG_E_EXTANTMARSHALLINGS),
  259.         MAKE_SCODE_ENTRY(STG_E_FILEALREADYEXISTS),
  260.         MAKE_SCODE_ENTRY(STG_E_FILENOTFOUND),
  261.         MAKE_SCODE_ENTRY(STG_E_INSUFFICIENTMEMORY),
  262.         MAKE_SCODE_ENTRY(STG_E_INUSE),
  263.         MAKE_SCODE_ENTRY(STG_E_INVALIDFLAG),
  264.         MAKE_SCODE_ENTRY(STG_E_INVALIDFUNCTION),
  265.         MAKE_SCODE_ENTRY(STG_E_INVALIDHANDLE),
  266.         MAKE_SCODE_ENTRY(STG_E_INVALIDHEADER),
  267.         MAKE_SCODE_ENTRY(STG_E_INVALIDNAME),
  268.         MAKE_SCODE_ENTRY(STG_E_INVALIDPARAMETER),
  269.         MAKE_SCODE_ENTRY(STG_E_INVALIDPOINTER),
  270.         MAKE_SCODE_ENTRY(STG_E_LOCKVIOLATION),
  271.         MAKE_SCODE_ENTRY(STG_E_MEDIUMFULL),
  272.         MAKE_SCODE_ENTRY(STG_E_NOMOREFILES),
  273.         MAKE_SCODE_ENTRY(STG_E_NOTCURRENT),
  274.         MAKE_SCODE_ENTRY(STG_E_NOTFILEBASEDSTORAGE),
  275.         MAKE_SCODE_ENTRY(STG_E_OLDDLL),
  276.         MAKE_SCODE_ENTRY(STG_E_OLDFORMAT),
  277.         MAKE_SCODE_ENTRY(STG_E_PATHNOTFOUND),
  278.         MAKE_SCODE_ENTRY(STG_E_READFAULT),
  279.         MAKE_SCODE_ENTRY(STG_E_REVERTED),
  280.         MAKE_SCODE_ENTRY(STG_E_SEEKERROR),
  281.         MAKE_SCODE_ENTRY(STG_E_SHAREREQUIRED),
  282.         MAKE_SCODE_ENTRY(STG_E_SHAREVIOLATION),
  283.         MAKE_SCODE_ENTRY(STG_E_TOOMANYOPENFILES),
  284.         MAKE_SCODE_ENTRY(STG_E_UNIMPLEMENTEDFUNCTION),
  285.         MAKE_SCODE_ENTRY(STG_E_UNKNOWN),
  286.         MAKE_SCODE_ENTRY(STG_E_WRITEFAULT),
  287.         MAKE_SCODE_ENTRY(TYPE_E_AMBIGUOUSNAME),
  288.         MAKE_SCODE_ENTRY(TYPE_E_BADMODULEKIND),
  289.         MAKE_SCODE_ENTRY(TYPE_E_BUFFERTOOSMALL),
  290.         MAKE_SCODE_ENTRY(TYPE_E_CANTCREATETMPFILE),
  291.         MAKE_SCODE_ENTRY(TYPE_E_CANTLOADLIBRARY),
  292.         MAKE_SCODE_ENTRY(TYPE_E_CIRCULARTYPE),
  293.         MAKE_SCODE_ENTRY(TYPE_E_DLLFUNCTIONNOTFOUND),
  294.         MAKE_SCODE_ENTRY(TYPE_E_DUPLICATEID),
  295.         MAKE_SCODE_ENTRY(TYPE_E_ELEMENTNOTFOUND),
  296.         MAKE_SCODE_ENTRY(TYPE_E_INCONSISTENTPROPFUNCS),
  297.         MAKE_SCODE_ENTRY(TYPE_E_INVALIDSTATE),
  298.         MAKE_SCODE_ENTRY(TYPE_E_INVDATAREAD),
  299.         MAKE_SCODE_ENTRY(TYPE_E_IOERROR),
  300.         MAKE_SCODE_ENTRY(TYPE_E_LIBNOTREGISTERED),
  301.         MAKE_SCODE_ENTRY(TYPE_E_NAMECONFLICT),
  302.         MAKE_SCODE_ENTRY(TYPE_E_OUTOFBOUNDS),
  303.         MAKE_SCODE_ENTRY(TYPE_E_QUALIFIEDNAMEDISALLOWED),
  304.         MAKE_SCODE_ENTRY(TYPE_E_REGISTRYACCESS),
  305.         MAKE_SCODE_ENTRY(TYPE_E_SIZETOOBIG),
  306.         MAKE_SCODE_ENTRY(TYPE_E_TYPEMISMATCH),
  307.         MAKE_SCODE_ENTRY(TYPE_E_UNDEFINEDTYPE),
  308.         MAKE_SCODE_ENTRY(TYPE_E_UNKNOWNLCID),
  309.         MAKE_SCODE_ENTRY(TYPE_E_UNSUPFORMAT),
  310.         MAKE_SCODE_ENTRY(TYPE_E_WRONGTYPEKIND),
  311.         MAKE_SCODE_ENTRY(VIEW_E_DRAW),
  312.     };
  313.     #undef MAKE_SCODE_ENTRY
  314.  
  315.     // look for it in the table
  316.     for (int i = 0; i < _countof(scNameTable); i++)
  317.     {
  318.         if (sc == scNameTable[i].sc)
  319.             return scNameTable[i].lpszName;
  320.     }
  321.  
  322.     static TCHAR szError[32] ;
  323.     wsprintf( szError, _T("%#08.8x"), sc ) ;
  324.  
  325.     return szError ;    // not found
  326. }
  327.  
  328. LPCTSTR AFXAPI _GetScodeRangeString(SCODE sc)
  329. {
  330.     struct RANGE_ENTRY
  331.     {
  332.         SCODE scFirst;
  333.         SCODE scLast;
  334.         LPCTSTR lpszName;
  335.     };
  336.     #define MAKE_RANGE_ENTRY(scRange) \
  337.         { scRange##_FIRST, scRange##_LAST, \
  338.             _T(#scRange) _T("_FIRST...") _T(#scRange) _T("_LAST") }
  339.  
  340.     static const RANGE_ENTRY scRangeTable[] =
  341.     {
  342.         MAKE_RANGE_ENTRY(CACHE_E),
  343.         MAKE_RANGE_ENTRY(CACHE_S),
  344.         MAKE_RANGE_ENTRY(CLASSFACTORY_E),
  345.         MAKE_RANGE_ENTRY(CLASSFACTORY_S),
  346.         MAKE_RANGE_ENTRY(CLIENTSITE_E),
  347.         MAKE_RANGE_ENTRY(CLIENTSITE_S),
  348.         MAKE_RANGE_ENTRY(CLIPBRD_E),
  349.         MAKE_RANGE_ENTRY(CLIPBRD_S),
  350.         MAKE_RANGE_ENTRY(CONVERT10_E),
  351.         MAKE_RANGE_ENTRY(CONVERT10_S),
  352.         MAKE_RANGE_ENTRY(CO_E),
  353.         MAKE_RANGE_ENTRY(CO_S),
  354.         MAKE_RANGE_ENTRY(DATA_E),
  355.         MAKE_RANGE_ENTRY(DATA_S),
  356.         MAKE_RANGE_ENTRY(DRAGDROP_E),
  357.         MAKE_RANGE_ENTRY(DRAGDROP_S),
  358.         MAKE_RANGE_ENTRY(ENUM_E),
  359.         MAKE_RANGE_ENTRY(ENUM_S),
  360.         MAKE_RANGE_ENTRY(INPLACE_E),
  361.         MAKE_RANGE_ENTRY(INPLACE_S),
  362.         MAKE_RANGE_ENTRY(MARSHAL_E),
  363.         MAKE_RANGE_ENTRY(MARSHAL_S),
  364.         MAKE_RANGE_ENTRY(MK_E),
  365.         MAKE_RANGE_ENTRY(MK_S),
  366.         MAKE_RANGE_ENTRY(OLEOBJ_E),
  367.         MAKE_RANGE_ENTRY(OLEOBJ_S),
  368.         MAKE_RANGE_ENTRY(OLE_E),
  369.         MAKE_RANGE_ENTRY(OLE_S),
  370.         MAKE_RANGE_ENTRY(REGDB_E),
  371.         MAKE_RANGE_ENTRY(REGDB_S),
  372.         MAKE_RANGE_ENTRY(VIEW_E),
  373.         MAKE_RANGE_ENTRY(VIEW_S),
  374.     };
  375.     #undef MAKE_RANGE_ENTRY
  376.  
  377.     // look for it in the table
  378.     for (int i = 0; i < _countof(scRangeTable); i++)
  379.     {
  380.         if (sc >= scRangeTable[i].scFirst && sc <= scRangeTable[i].scLast)
  381.             return scRangeTable[i].lpszName;
  382.     }
  383.     return NULL;    // not found
  384. }
  385.  
  386. LPCTSTR AFXAPI _GetSeverityString(SCODE sc)
  387. {
  388.     static const TCHAR* rgszSEVERITY[] =
  389.     {
  390.         _T("SEVERITY_SUCCESS"),
  391.         _T("SEVERITY_ERROR"),
  392.     };
  393.     return rgszSEVERITY[SCODE_SEVERITY(sc)];
  394. }
  395.  
  396. LPCTSTR AFXAPI _GetFacilityString(SCODE sc)
  397. {
  398.     static const TCHAR* rgszFACILITY[] =
  399.     {
  400.         _T("FACILITY_NULL"),
  401.         _T("FACILITY_RPC"),
  402.         _T("FACILITY_DISPATCH"),
  403.         _T("FACILITY_STORAGE"),
  404.         _T("FACILITY_ITF"),
  405.         _T("FACILITY_0x05"),
  406.         _T("FACILITY_0x06"),
  407.         _T("FACILITY_WIN32"),
  408.         _T("FACILITY_WINDOWS"),
  409.     };
  410.     if (SCODE_FACILITY(sc) >= _countof(rgszFACILITY))
  411.         return _T("<Unknown Facility>");
  412.  
  413.     return rgszFACILITY[SCODE_FACILITY(sc)];
  414. }
  415.  
  416. LPCTSTR AFXAPI _GetFullScodeString(SCODE sc)
  417. {
  418.     static TCHAR szBuf[128];
  419.     LPCTSTR lpsz;
  420.     if ((lpsz = _GetScodeString(sc)) != NULL)
  421.     {
  422.         // found exact match
  423.         wsprintf(szBuf, _T("%s ($%08lX)"), lpsz, sc);
  424.     }
  425.     else if ((lpsz = _GetScodeRangeString(sc)) != NULL)
  426.     {
  427.         // found suitable range
  428.         wsprintf(szBuf, _T("range: %s ($%08lX)"), lpsz, sc);
  429.     }
  430.     else
  431.     {
  432.         // not found at all -- split it up into its parts
  433.         wsprintf(szBuf, _T("severity: %s, facility: %s ($%08lX)"),
  434.             _GetSeverityString(sc), _GetFacilityString(sc), sc);
  435.     }
  436.     return szBuf;
  437. }
  438.  
  439.  
  440. LPTSTR HRtoString( HRESULT hr )
  441. {
  442.     SCODE   sc ;
  443.     sc = GetScode( hr ) ;
  444.  
  445. #ifdef FORMATMSG
  446.     LPVOID lpMessageBuffer ;
  447.     if (FormatMessage(
  448.           FORMAT_MESSAGE_ALLOCATE_BUFFER |
  449.           FORMAT_MESSAGE_FROM_SYSTEM,
  450.           NULL,
  451.           sc,
  452.           MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  453.           (LPTSTR) &lpMessageBuffer,
  454.           0,
  455.           NULL ))
  456.     {
  457.         wsprintf( sz, _T( "%s (0x%lx)" ), (LPTSTR)lpMessageBuffer, sc);
  458.         LocalFree(lpMessageBuffer) ;
  459.     }
  460.     else
  461.     {
  462.         wsprintf( sz, _T( "Unknown Scode (0x%lx)" ), sc);
  463.     }
  464.  
  465.  
  466. #endif // !FORMATMSG
  467.  
  468.     return (LPTSTR)_GetFullScodeString(sc) ;
  469. }
  470.  
  471. #include <ctype.h>
  472. // Very useful API that parses a LONG out of a string, updating
  473. // the string pointer before it returns.
  474. //
  475. LONG WINAPI ParseOffNumber( LPTSTR FAR *lplp, LPINT lpConv )
  476. {
  477.     LPTSTR lp = *lplp;
  478.     LONG  lValue=0;
  479.     int   sign=1;
  480.  
  481.     while( isspace(*lp) )
  482.         lp++;
  483.     if( *lp=='-' )
  484.     {
  485.         sign = -1;
  486.         lp++;
  487.     }
  488.     if (*lp=='\0')
  489.     {
  490.         *lpConv = FALSE;
  491.         return 0L;
  492.     }
  493.  
  494.     // Is it a decimal number
  495.     #ifdef UNICODE
  496.     if( _wcsnicmp( lp, (LPTSTR)_T("0x"),2) )
  497.     #else
  498.     #ifdef WIN32
  499.     if( strnicmp( lp, (LPTSTR)_T("0x"),2) )
  500.     #else
  501.     if( _fstrnicmp( lp, (LPTSTR)_T("0x"),2) )
  502.     #endif
  503.     #endif
  504.     {
  505.  
  506.         while( isdigit(*lp) )
  507.         {
  508.             lValue *= 10;
  509.             lValue += (*lp - (TCHAR)'0');
  510.             lp++;
  511.         }
  512.     }
  513.     else
  514.     {
  515.         lp+=2;
  516.  
  517.         while( isxdigit(*lp) )
  518.         {
  519.             lValue *= 16;
  520.             if( isdigit(*lp) )
  521.                 lValue += (*lp - (TCHAR)'0');
  522.             else
  523.                 lValue += (toupper(*lp) - (TCHAR)'A' + 10);
  524.             lp++;
  525.         }
  526.     }
  527.     while( isspace(*lp) )
  528.         lp++;
  529.  
  530.     lValue *= (long)sign;
  531.  
  532.     if (*lp==(TCHAR)',')
  533.     {
  534.         lp++;
  535.         while( isspace(*lp) )
  536.             lp++;
  537.         *lplp = lp;
  538.         if (lpConv)
  539.             *lpConv = (int)TRUE;
  540.     }
  541.     else
  542.     {
  543.         *lplp = lp;
  544.         if (lpConv)
  545.             *lpConv = (int)(*lp=='\0');
  546.     }
  547.     return lValue;
  548.  
  549. } //*** ParseOffNumber
  550.  
  551. static TCHAR* BASED_CODE g_rgszVT[] =
  552. {
  553.     _T("void"),             //VT_EMPTY           = 0,   /* [V]   [P]  nothing                     */
  554.     _T("null"),             //VT_NULL            = 1,   /* [V]        SQL style Null              */
  555.     _T("short"),            //VT_I2              = 2,   /* [V][T][P]  2 byte signed int           */
  556.     _T("long"),             //VT_I4              = 3,   /* [V][T][P]  4 byte signed int           */
  557.     _T("single"),           //VT_R4              = 4,   /* [V][T][P]  4 byte real                 */
  558.     _T("double"),           //VT_R8              = 5,   /* [V][T][P]  8 byte real                 */
  559.     _T("CURRENCY"),         //VT_CY              = 6,   /* [V][T][P]  currency                    */
  560.     _T("DATE"),             //VT_DATE            = 7,   /* [V][T][P]  date                        */
  561.     _T("BSTR"),             //VT_BSTR            = 8,   /* [V][T][P]  binary string               */
  562.     _T("IDispatch*"),       //VT_DISPATCH        = 9,   /* [V][T]     IDispatch FAR*              */
  563.     _T("SCODE"),            //VT_ERROR           = 10,  /* [V][T]     SCODE                       */
  564.     _T("boolean"),          //VT_BOOL            = 11,  /* [V][T][P]  True=-1, False=0            */
  565.     _T("VARIANT"),          //VT_VARIANT         = 12,  /* [V][T][P]  VARIANT FAR*                */
  566.     _T("IUnknown*"),        //VT_UNKNOWN         = 13,  /* [V][T]     IUnknown FAR*               */
  567.     _T("wchar_t"),          //VT_WBSTR           = 14,  /* [V][T]     wide binary string          */
  568.     _T(""),                 //                   = 15,
  569.     _T("char"),             //VT_I1              = 16,  /*    [T]     signed char                 */
  570.     _T("unsigned char"),             //VT_UI1             = 17,  /*    [T]     unsigned char               */
  571.     _T("unsigned short"),           //VT_UI2             = 18,  /*    [T]     unsigned short              */
  572.     _T("unsigned long"),            //VT_UI4             = 19,  /*    [T]     unsigned short              */
  573.     _T("int64"),            //VT_I8              = 20,  /*    [T][P]  signed 64-bit int           */
  574.     _T("uint64"),           //VT_UI8             = 21,  /*    [T]     unsigned 64-bit int         */
  575.     _T("int"),              //VT_INT             = 22,  /*    [T]     signed machine int          */
  576.     _T("unsigned int"),             //VT_UINT            = 23,  /*    [T]     unsigned machine int        */
  577.     _T("void"),             //VT_VOID            = 24,  /*    [T]     C style void                */
  578.     _T("HRESULT"),          //VT_HRESULT         = 25,  /*    [T]                                 */
  579.     _T("PTR"),              //VT_PTR             = 26,  /*    [T]     pointer type                */
  580.     _T("SAFEARRAY"),        //VT_SAFEARRAY       = 27,  /*    [T]     (use VT_ARRAY in VARIANT)   */
  581.     _T("CARRAY"),           //VT_CARRAY          = 28,  /*    [T]     C style array               */
  582.     _T("USERDEFINED"),      //VT_USERDEFINED     = 29,  /*    [T]     user defined type         */
  583.     _T("LPSTR"),            //VT_LPSTR           = 30,  /*    [T][P]  null terminated string      */
  584.     _T("LPWSTR"),           //VT_LPWSTR          = 31,  /*    [T][P]  wide null terminated string */
  585.     _T(""),                 //                   = 32,
  586.     _T(""),                 //                   = 33,
  587.     _T(""),                 //                   = 34,
  588.     _T(""),                 //                   = 35,
  589.     _T(""),                 //                   = 36,
  590.     _T(""),                 //                   = 37,
  591.     _T(""),                 //                   = 38,
  592.     _T(""),                 //                   = 39,
  593.     _T(""),                 //                   = 40,
  594.     _T(""),                 //                   = 41,
  595.     _T(""),                 //                   = 42,
  596.     _T(""),                 //                   = 43,
  597.     _T(""),                 //                   = 44,
  598.     _T(""),                 //                   = 45,
  599.     _T(""),                 //                   = 46,
  600.     _T(""),                 //                   = 47,
  601.     _T(""),                 //                   = 48,
  602.     _T(""),                 //                   = 49,
  603.     _T(""),                 //                   = 50,
  604.     _T(""),                 //                   = 51,
  605.     _T(""),                 //                   = 52,
  606.     _T(""),                 //                   = 53,
  607.     _T(""),                 //                   = 54,
  608.     _T(""),                 //                   = 55,
  609.     _T(""),                 //                   = 56,
  610.     _T(""),                 //                   = 57,
  611.     _T(""),                 //                   = 58,
  612.     _T(""),                 //                   = 59,
  613.     _T(""),                 //                   = 60,
  614.     _T(""),                 //                   = 61,
  615.     _T(""),                 //                   = 62,
  616.     _T(""),                 //                   = 63,
  617.     _T("FILETIME"),         //VT_FILETIME        = 64,  /*       [P]  FILETIME                    */
  618.     _T("BLOB"),             //VT_BLOB            = 65,  /*       [P]  Length prefixed bytes       */
  619.     _T("STREAM"),           //VT_STREAM          = 66,  /*       [P]  Name of the stream follows  */
  620.     _T("STORAGE"),          //VT_STORAGE         = 67,  /*       [P]  Name of the storage follows */
  621.     _T("STREAMED_OBJECT"),  //VT_STREAMED_OBJECT = 68,  /*       [P]  Stream contains an object   */
  622.     _T("STORED_OBJECT"),    //VT_STORED_OBJECT   = 69,  /*       [P]  Storage contains an object  */
  623.     _T("BLOB_OBJECT"),      //VT_BLOB_OBJECT     = 70,  /*       [P]  Blob contains an object     */
  624.     _T("CF"),               //VT_CF              = 71,  /*       [P]  Clipboard format            */
  625.     _T("CLSID"),            //VT_CLSID           = 72   /*       [P]  A Class ID                  */
  626. };
  627.  
  628. CString VTtoString( VARTYPE vt )
  629. {
  630.     CString str ;
  631.     vt &= ~0xF000 ;
  632.     if (vt <= VT_CLSID)
  633.        str = g_rgszVT[vt]  ;
  634.     else
  635.        str = "BAD VARTYPE" ;
  636.  
  637.     return str ;
  638. }
  639. CString TYPEDESCtoString( ITypeInfo* pti, TYPEDESC* ptdesc )
  640. {
  641.     CString str ;
  642.  
  643.     if (ptdesc->vt == VT_PTR)
  644.     {
  645.         // ptdesc->lptdesc points to a TYPEDESC that specifies the thing pointed to
  646.  
  647.         str = TYPEDESCtoString( pti, ptdesc->lptdesc ) ;
  648.         str += "*" ;
  649.         return str.AllocSysString() ;
  650.     }
  651.  
  652.     if ((ptdesc->vt & 0x0FFF) == VT_CARRAY)
  653.     {
  654.         // ptdesc->lpadesc points to an ARRAYDESC
  655.         str = TYPEDESCtoString( pti, &ptdesc->lpadesc->tdescElem ) ;
  656.  
  657.         // Allocate cDims * lstrlen("[123456]")
  658.         CString strTemp ;
  659.         for (USHORT n = 0 ; n < ptdesc->lpadesc->cDims ; n++)
  660.         {
  661.             strTemp.Format( _T("[%d]"), ptdesc->lpadesc->rgbounds[n].cElements ) ;
  662.             str += strTemp ;
  663.         }
  664.         return str ;
  665.     }
  666.  
  667.     if ((ptdesc->vt & 0x0FFF) == VT_SAFEARRAY)
  668.     {
  669.         str = "SAFEARRAY(" + TYPEDESCtoString( pti, ptdesc->lptdesc ) + ")" ;
  670.         return str ;
  671.     }
  672.  
  673.     if (ptdesc->vt == VT_USERDEFINED)
  674.     {
  675.         // Use ptdesc->hreftype and pti->GetRefTypeInfo
  676.         //
  677.         ASSERT(pti) ;
  678.         ITypeInfo* ptiRefType = NULL ;
  679.         HRESULT hr = pti->GetRefTypeInfo( ptdesc->hreftype, &ptiRefType ) ;
  680.         if (SUCCEEDED(hr))
  681.         {
  682.             BSTR            bstrName = NULL ;
  683.             BSTR            bstrDoc = NULL ;
  684.             BSTR            bstrHelp = NULL ;
  685.             DWORD           dwHelpID ;
  686.             hr = ptiRefType->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp ) ;
  687.             if (FAILED(hr))
  688.             {
  689.                 #ifdef _DEBUG
  690.                 ErrorMessage(_T("ITypeInfo::GetDocumentation() failed"), hr ) ;
  691.                 #endif
  692.                 return _T("ITypeInfo::GetDocumentation() failed in TYPEDESCToString") ;
  693.             }
  694.  
  695.             str = bstrName ;
  696.  
  697.             SysFreeString(bstrName) ;
  698.             SysFreeString( bstrDoc ) ;
  699.             SysFreeString( bstrHelp ) ;
  700.  
  701.             ptiRefType->Release() ;
  702.         }
  703.         else
  704.         {
  705.             #ifdef _DEBUG
  706.             ErrorMessage( _T("GetRefTypeInfo failed in TYPEDESCToString"), hr ) ;
  707.             #endif
  708.             return _T("<GetRefTypeInfo failed>") ;
  709.         }
  710.  
  711.         return str ;
  712.     }
  713.     return VTtoString( ptdesc->vt );
  714. }
  715.