|
|
1.1 ! root 1: /*** ! 2: *disphelp.cpp - IDispatch helpers ! 3: * ! 4: * Copyright (C) 1992, Microsoft Corporation. All Rights Reserved. ! 5: * Information Contained Herein Is Proprietary and Confidential. ! 6: * ! 7: *Purpose: ! 8: * This file contains several useful IDispatch related utilities. ! 9: * ! 10: *****************************************************************************/ ! 11: ! 12: #include <windows.h> ! 13: #include <ole2.h> ! 14: #include <dispatch.h> ! 15: ! 16: #include <stdarg.h> ! 17: ! 18: #include "disphelp.h" ! 19: ! 20: // Adjust for WIN16/WIN32 synchronization ! 21: #if defined(WIN32) && !defined(OLE2FINAL) ! 22: #define E_FAIL E_UNSPEC ! 23: #endif ! 24: ! 25: /* helper for DispBuildParams */ ! 26: HRESULT PASCAL ! 27: CArgsOfFmt(DISPPARAMS FAR* pdispparams, char FAR* szFmt) ! 28: { ! 29: char FAR* sz; ! 30: ! 31: pdispparams->cArgs = 0; ! 32: pdispparams->cNamedArgs = 0; ! 33: ! 34: if(szFmt == NULL) ! 35: return NOERROR; ! 36: ! 37: for(sz = szFmt; *sz != '\0'; ++sz){ ! 38: if(*sz == '&') ! 39: ++sz; ! 40: ! 41: switch(*sz){ ! 42: case 'e': ! 43: case 'n': ! 44: case 'f': ! 45: case 'i': case 'I': ! 46: case 'r': case 'R': ! 47: case 'c': ! 48: case 'b': ! 49: case 's': ! 50: case 'd': ! 51: case 'v': ! 52: case 'D': ! 53: ++pdispparams->cArgs; ! 54: break; ! 55: ! 56: default: ! 57: return ResultFromScode(E_INVALIDARG); ! 58: } ! 59: } ! 60: ! 61: return NOERROR; ! 62: } ! 63: ! 64: ! 65: /* helper for DispBuildParams */ ! 66: VARTYPE PASCAL ! 67: VtOfFmtChar(char ch) ! 68: { ! 69: switch(ch){ ! 70: case 'e': return VT_EMPTY; ! 71: case 'n': return VT_NULL; ! 72: case 'f': return VT_BOOL; ! 73: case 'i': return VT_I2; ! 74: case 'I': return VT_I4; ! 75: case 'r': return VT_R4; ! 76: case 'R': return VT_R8; ! 77: case 'c': return VT_CY; ! 78: case 'b': return VT_BSTR; ! 79: case 's': return VT_ERROR; ! 80: case 'd': return VT_DATE; ! 81: case 'v': return VT_VARIANT; ! 82: case 'U': return VT_UNKNOWN; ! 83: case 'D': return VT_DISPATCH; ! 84: } ! 85: ! 86: // REVIEW: this is really an error ! 87: return VT_EMPTY; ! 88: } ! 89: ! 90: ! 91: /*** ! 92: *PUBLIC DispBuildParams(DISPPARAMS**, UINT, DISPID*, char*, ...) ! 93: *Purpose: ! 94: * Construct a DISPPARAMS struct based on the given format string. ! 95: * ! 96: * '&' = mark the following record VT_BYREF ! 97: * ! 98: * 'e' = VT_EMPTY ! 99: * 'n' = VT_NULL ! 100: * 'f' = VT_BOOL 'f' as in flag ! 101: * 'i' = VT_I2 ! 102: * 'I' = VT_I4 ! 103: * 'r' = VT_R4 ! 104: * 'R' = VT_R8 ! 105: * 'c' = VT_CY ! 106: * 'b' = VT_BSTR ! 107: * 's' = VT_ERROR 's' as in scode ! 108: * 'd' = VT_DATE ! 109: * 'v' = VT_VARIANT ! 110: * 'D' = VT_DISPATCH ! 111: * 'U' = VT_UNKNOWN ! 112: * ! 113: # ! 114: *Entry: ! 115: * UNDONE ! 116: * ! 117: *Exit: ! 118: * UNDONE ! 119: * ! 120: ***********************************************************************/ ! 121: extern "C" HRESULT FAR CDECL ! 122: DispBuildParams( ! 123: DISPPARAMS FAR* FAR* ppdispparams, ! 124: UINT cNamedArgs, ! 125: DISPID FAR* rgdispid, ! 126: char FAR* szFmt, ...) ! 127: { ! 128: int ix; ! 129: va_list args; ! 130: char FAR* sz; ! 131: HRESULT hresult; ! 132: VARIANTARG FAR* pvarg; ! 133: ! 134: VARTYPE vt, vtMode; ! 135: DISPPARAMS FAR* pdispparams; ! 136: ! 137: ! 138: pdispparams = new DISPPARAMS; ! 139: if(pdispparams == NULL) ! 140: return ResultFromScode(E_OUTOFMEMORY); ! 141: ! 142: // compute the total number of arguments represented by the format ! 143: // string, *and* validate the contents of the format string. ! 144: // ! 145: if((hresult = CArgsOfFmt(pdispparams, szFmt)) != NOERROR) ! 146: goto LFreeDispParams; ! 147: ! 148: // the total number of arguments numst be >= the number of named args. ! 149: // ! 150: if(pdispparams->cArgs < cNamedArgs){ ! 151: hresult = ResultFromScode(E_INVALIDARG); ! 152: goto LFreeDispParams; ! 153: } ! 154: pdispparams->cNamedArgs = cNamedArgs; ! 155: ! 156: pdispparams->rgvarg = new VARIANTARG[pdispparams->cArgs]; ! 157: if((pdispparams->rgvarg) == NULL){ ! 158: hresult = ResultFromScode(E_OUTOFMEMORY); ! 159: goto LFreeDispParams; ! 160: } ! 161: ! 162: if(pdispparams->cNamedArgs == 0){ ! 163: pdispparams->rgdispidNamedArgs = NULL; ! 164: }else{ ! 165: pdispparams->rgdispidNamedArgs = new DISPID[pdispparams->cNamedArgs]; ! 166: if((pdispparams->rgdispidNamedArgs) == NULL){ ! 167: hresult = ResultFromScode(E_OUTOFMEMORY); ! 168: goto LFreeRgVarg; ! 169: } ! 170: for(UINT i = 0; i < cNamedArgs; ++i) ! 171: pdispparams->rgdispidNamedArgs[i] = rgdispid[cNamedArgs - i - 1]; ! 172: } ! 173: ! 174: va_start(args, szFmt); ! 175: ix = pdispparams->cArgs; ! 176: ! 177: for(sz = szFmt; *sz != '\0'; ++sz){ ! 178: --ix; ! 179: ! 180: vtMode = 0; ! 181: pvarg = &pdispparams->rgvarg[ix]; ! 182: ! 183: if(*sz == '&'){ ! 184: ++sz; ! 185: vtMode |= VT_BYREF; ! 186: } ! 187: ! 188: vt = VtOfFmtChar(*sz); ! 189: ! 190: if(vtMode & VT_BYREF){ ! 191: ! 192: V_BYREF(pvarg) = va_arg(args, void FAR*); ! 193: ! 194: }else{ ! 195: ! 196: switch(*sz){ ! 197: case 'e': // VT_EMPTY ! 198: break; ! 199: ! 200: case 'n': // VT_NULL ! 201: V_I4(pvarg) = 0; ! 202: break; ! 203: ! 204: case 'I': // VT_I4 ! 205: case 's': // VT_ERROR ! 206: V_I4(pvarg) = va_arg(args, long); ! 207: break; ! 208: ! 209: case 'f': // VT_BOOL ! 210: case 'i': // VT_I2 ! 211: V_I2(pvarg) = va_arg(args, short); ! 212: break; ! 213: ! 214: case 'r': // VT_R4 ! 215: V_R4(pvarg) = (float)va_arg(args, double); ! 216: break; ! 217: ! 218: case 'd': // VT_DATE ! 219: case 'R': // VT_R8 ! 220: V_R8(pvarg) = va_arg(args, double); ! 221: break; ! 222: ! 223: case 'c': // VT_CY ! 224: V_CY(pvarg) = va_arg(args, CY); ! 225: break; ! 226: ! 227: case 'b': // VT_BSTR ! 228: //REVIEW: do we need to make a copy of this? ! 229: V_BSTR(pvarg) = va_arg(args, BSTR); ! 230: break; ! 231: ! 232: case 'v': // VT_VARIANT ! 233: V_VARIANTREF(pvarg) = va_arg(args, VARIANT FAR*); ! 234: break; ! 235: ! 236: case 'U': // VT_UNKNOWN ! 237: vt = VT_DISPATCH; ! 238: V_UNKNOWN(pvarg) = va_arg(args, IUnknown FAR*); ! 239: break; ! 240: ! 241: case 'D': // VT_DISPATCH ! 242: vt = VT_DISPATCH; ! 243: V_DISPATCH(pvarg) = va_arg(args, IDispatch FAR*); ! 244: break; ! 245: ! 246: default: ! 247: hresult = ResultFromScode(E_FAIL); ! 248: goto LFreeRgVarg; ! 249: } ! 250: } ! 251: ! 252: V_VT(pvarg) = vtMode | vt; ! 253: } ! 254: ! 255: *ppdispparams = pdispparams; ! 256: ! 257: return NOERROR; ! 258: ! 259: ! 260: LFreeRgVarg:; ! 261: delete pdispparams->rgvarg; ! 262: ! 263: LFreeDispParams:; ! 264: delete pdispparams; ! 265: ! 266: return hresult; ! 267: } ! 268: ! 269: ! 270: /*** ! 271: *PUBLIC HRESULT DispFreeParams(DISPPARAMS*) ! 272: *Purpose: ! 273: * Free the given DISPPARAMS struct, and its contents. ! 274: * ! 275: *Entry: ! 276: * pdispparams = the DISPPARAMS structure to free ! 277: * ! 278: *Exit: ! 279: * return value = HRESULT ! 280: * ! 281: ***********************************************************************/ ! 282: STDAPI ! 283: DispFreeParams(DISPPARAMS FAR* pdispparams) ! 284: { ! 285: UINT i; ! 286: HRESULT hresult; ! 287: ! 288: for(i = 0; i < pdispparams->cArgs; ++i){ ! 289: if ((hresult = VariantClear(&pdispparams->rgvarg[i])) != NOERROR) ! 290: return hresult; ! 291: } ! 292: ! 293: delete pdispparams->rgvarg; ! 294: delete pdispparams->rgdispidNamedArgs; ! 295: delete pdispparams; ! 296: ! 297: return NOERROR; ! 298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.