const char *debugstr_variant(const VARIANT *v) { if(!v) return "(null)"; if(V_ISBYREF(v)) return wine_dbg_sprintf("{V_BYREF -> %s}", debugstr_variant(V_BYREF(v))); switch(V_VT(v)) { case VT_EMPTY: return "{VT_EMPTY}"; case VT_NULL: return "{VT_NULL}"; case VT_I2: return wine_dbg_sprintf("{VT_I2: %d}", V_I2(v)); case VT_I4: return wine_dbg_sprintf("{VT_I4: %d}", V_I4(v)); case VT_UI4: return wine_dbg_sprintf("{VT_UI4: %u}", V_UI4(v)); case VT_R8: return wine_dbg_sprintf("{VT_R8: %lf}", V_R8(v)); case VT_BSTR: return wine_dbg_sprintf("{VT_BSTR: %s}", debugstr_w(V_BSTR(v))); case VT_DISPATCH: return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v)); case VT_BOOL: return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v)); default: return wine_dbg_sprintf("{vt %d}", V_VT(v)); } }
static const char *vt2a(VARIANT *v) { if(V_VT(v) == (VT_BYREF|VT_VARIANT)) { static char buf[64]; sprintf(buf, "%s*", vt2a(V_BYREF(v))); return buf; } switch(V_VT(v)) { case VT_EMPTY: return "VT_EMPTY"; case VT_NULL: return "VT_NULL"; case VT_I2: return "VT_I2"; case VT_I4: return "VT_I4"; case VT_R8: return "VT_R8"; case VT_BSTR: return "VT_BSTR"; case VT_DISPATCH: return "VT_DISPATCH"; case VT_BOOL: return "VT_BOOL"; case VT_ARRAY|VT_VARIANT: return "VT_ARRAY|VT_VARIANT"; default: ok(0, "unknown vt %d\n", V_VT(v)); return NULL; } }
static void notif_complete(DocHost *This, DISPID dispid) { DISPPARAMS dispparams; VARIANTARG params[2]; VARIANT url; dispparams.cArgs = 2; dispparams.cNamedArgs = 0; dispparams.rgdispidNamedArgs = NULL; dispparams.rgvarg = params; V_VT(params) = (VT_BYREF|VT_VARIANT); V_BYREF(params) = &url; V_VT(params+1) = VT_DISPATCH; V_DISPATCH(params+1) = This->disp; V_VT(&url) = VT_BSTR; V_BSTR(&url) = SysAllocString(This->url); TRACE("%d >>>\n", dispid); call_sink(This->cps.wbe2, dispid, &dispparams); TRACE("%d <<<\n", dispid); SysFreeString(V_BSTR(&url)); This->busy = VARIANT_FALSE; }
static void navigate_complete(DocHost *This) { IDispatch *disp = NULL; DISPPARAMS dispparams; VARIANTARG params[2]; VARIANT url; HRESULT hres; hres = IUnknown_QueryInterface(This->document, &IID_IDispatch, (void**)&disp); if(FAILED(hres)) FIXME("Could not get IDispatch interface\n"); dispparams.cArgs = 2; dispparams.cNamedArgs = 0; dispparams.rgdispidNamedArgs = NULL; dispparams.rgvarg = params; V_VT(params) = (VT_BYREF|VT_VARIANT); V_BYREF(params) = &url; V_VT(params+1) = VT_DISPATCH; V_DISPATCH(params+1) = disp; V_VT(&url) = VT_BSTR; V_BSTR(&url) = SysAllocString(This->url); call_sink(This->cps.wbe2, DISPID_NAVIGATECOMPLETE2, &dispparams); call_sink(This->cps.wbe2, DISPID_DOCUMENTCOMPLETE, &dispparams); SysFreeString(V_BSTR(&url)); if(disp) IDispatch_Release(disp); This->busy = VARIANT_FALSE; }
/* * call-seq: * WIN32OLE_VARIANT[i,j,...] #=> element of OLE array. * * Returns the element of WIN32OLE_VARIANT object(OLE array). * This method is available only when the variant type of * WIN32OLE_VARIANT object is VT_ARRAY. * * REMARK: * The all indices should be 0 or natural number and * lower than or equal to max indices. * (This point is different with Ruby Array indices.) * * obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]]) * p obj[0,0] # => 1 * p obj[1,0] # => 4 * p obj[2,0] # => WIN32OLERuntimeError * p obj[0, -1] # => WIN32OLERuntimeError * */ static VALUE folevariant_ary_aref(int argc, VALUE *argv, VALUE self) { struct olevariantdata *pvar; SAFEARRAY *psa; VALUE val = Qnil; VARIANT variant; LONG *pid; HRESULT hr; TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); if (!V_ISARRAY(&(pvar->var))) { rb_raise(eWIN32OLERuntimeError, "`[]' is not available for this variant type object"); } psa = get_locked_safe_array(self); if (psa == NULL) { return val; } pid = ary2safe_array_index(argc, argv, psa); VariantInit(&variant); V_VT(&variant) = (V_VT(&(pvar->var)) & ~VT_ARRAY) | VT_BYREF; hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant)); if (FAILED(hr)) { ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPtrOfIndex"); } val = ole_variant2val(&variant); unlock_safe_array(psa); if (pid) free(pid); return val; }
//+--------------------------------------------------------------------------- // // Function: CVarToVARIANTARG // // Synopsis: Converts a C-language variable to a VARIANT. // // Arguments: [pv] -- Pointer to C-language variable. // [vt] -- Type of C-language variable. // [pvarg] -- Resulting VARIANT. Must be initialized by caller. // Any contents will be freed. // // Modifies: [pvarg] // // History: 2-23-94 adams Created // // Notes: Supports all variant pointer types, VT_UI2, VT_I2, VT_UI4, // VT_I4, VT_R4, VT_R8, VT_ERROR. // //---------------------------------------------------------------------------- void CVarToVARIANTARG(void* pv, VARTYPE vt, VARIANTARG* pvarg) { Assert(pv); Assert(pvarg); VariantClear(pvarg); V_VT(pvarg) = vt; if(V_ISBYREF(pvarg)) { // Use a supported pointer type for derefencing. vt = VT_UNKNOWN; } switch(vt) { case VT_BOOL: // convert TRUE to VT_TRUE Assert(*(BOOL*)pv==1 || *(BOOL*)pv==0); V_BOOL(pvarg) = VARIANT_BOOL(-*(BOOL*)pv); break; case VT_I2: V_I2(pvarg) = *(short*)pv; break; case VT_ERROR: case VT_I4: V_I4(pvarg) = *(long*)pv; break; case VT_R4: V_R4(pvarg) = *(float*)pv; break; case VT_R8: V_R8(pvarg) = *(double*)pv; break; case VT_CY: V_CY(pvarg) = *(CY*)pv; break; // All Pointer types. case VT_PTR: case VT_BSTR: case VT_LPSTR: case VT_LPWSTR: case VT_DISPATCH: case VT_UNKNOWN: V_BYREF(pvarg) = *(void**)pv; break; default: Assert(FALSE && "Unknown type."); break; } }
static HRESULT WINAPI DocObjectService_FireNavigateComplete2( IDocObjectService* iface, IHTMLWindow2 *pHTMLWindow2, DWORD dwFlags) { ShellBrowser *This = impl_from_IDocObjectService(iface); IHTMLPrivateWindow *priv_window; VARIANTARG params[2]; DISPPARAMS dp = {params, NULL, 2, 0}; VARIANT url_var; BSTR url; HRESULT hres; TRACE("%p %p %x\n", This, pHTMLWindow2, dwFlags); hres = IHTMLWindow2_QueryInterface(pHTMLWindow2, &IID_IHTMLPrivateWindow, (void**)&priv_window); if(FAILED(hres)) return hres; hres = IHTMLPrivateWindow_GetAddressBarUrl(priv_window, &url); IHTMLPrivateWindow_Release(priv_window); if(FAILED(hres)) return hres; TRACE("got URL %s\n", debugstr_w(url)); set_dochost_url(This->doc_host, url); V_VT(params) = (VT_BYREF|VT_VARIANT); V_BYREF(params) = &url; V_VT(params+1) = VT_DISPATCH; V_DISPATCH(params+1) = This->doc_host->disp; V_VT(&url_var) = VT_BSTR; V_BSTR(&url_var) = url; TRACE(">>>\n"); call_sink(This->doc_host->cps.wbe2, DISPID_NAVIGATECOMPLETE2, &dp); TRACE("<<<\n"); SysFreeString(url); This->doc_host->busy = VARIANT_FALSE; return S_OK; }
HRESULT CMaxMaterialCollection::GetXMLImpExp(IVIZPointerClient** ppClient) { #ifdef XXX //Begin temporary // temporary impl: Create an XMLMaterial COM object and ask it to import //TODO (JH 7/25/02 Done By CC) implement this differently, CoCreate is slow HRESULT hr = CoCreateInstance(CLSID_XmlMaterial, NULL, CLSCTX_INPROC_SERVER, __uuidof(IVIZPointerClient), (void**)ppClient); if(!SUCCEEDED(hr) || *ppClient == NULL) { //TODO (JH 7/25/02 Done By CC)Remove the message box MessageBox(NULL, _T("Failed to create XML Material importer, is it registered?"), NULL, MB_OK | MB_TASKMODAL); return E_FAIL; } VARIANT vIp, vImpIp; vIp.vt = vImpIp.vt = VT_BYREF; vIp.byref = GetCOREInterface(); vImpIp.byref = GetCOREInterface();//this is a HACK return (*ppClient)->InitPointers(vIp, vImpIp); #else *ppClient = NULL; Interface *ip = GetCOREInterface(); TSTR plugletModuleName(ip->GetDir(APP_MAX_SYS_ROOT_DIR)); plugletModuleName.Append(sXmlMaterialModuleName); HRESULT hr = CreatePluglet(CLSID_XmlMaterial, __uuidof(IVIZPointerClient), (void**)ppClient, plugletModuleName.data()); if(SUCCEEDED(hr) && *ppClient) { VARIANT vIp, vImpIp; VariantInit(&vIp); VariantInit(&vImpIp); V_VT(&vIp) = VT_BYREF; V_BYREF(&vIp) = ip; // We don't have access to an import interface ptr here. HRESULT hr = (*ppClient)->InitPointers(vIp, vImpIp); } return hr; #endif }
static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray) { IRecordInfoImpl *This = impl_from_IRecordInfo(iface); int i; TRACE("(%p)->(%p %s %p %p)\n", This, pvData, debugstr_w(szFieldName), pvarField, ppvDataCArray); if(!pvData || !szFieldName || !pvarField) return E_INVALIDARG; for(i=0; i<This->n_vars; i++) if(!strcmpW(This->fields[i].name, szFieldName)) break; if(i == This->n_vars) return TYPE_E_FIELDNOTFOUND; VariantClear(pvarField); V_VT(pvarField) = VT_BYREF|This->fields[i].vt; V_BYREF(pvarField) = ((PBYTE)pvData)+This->fields[i].offset; *ppvDataCArray = NULL; return S_OK; }
static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { switch(id) { case DISPID_GLOBAL_OK: { VARIANT *b; ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags); ok(pdp != NULL, "pdp == NULL\n"); ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs); ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); if(wFlags & INVOKE_PROPERTYGET) ok(pvarRes != NULL, "pvarRes == NULL\n"); else ok(!pvarRes, "pvarRes != NULL\n"); ok(pei != NULL, "pei == NULL\n"); ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg)); b = pdp->rgvarg+1; if(V_VT(b) == (VT_BYREF|VT_VARIANT)) b = V_BYREF(b); ok(V_VT(b) == VT_BOOL, "V_VT(b) = %d\n", V_VT(b)); ok(V_BOOL(b), "%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg))); return S_OK; } case DISPID_GLOBAL_TRACE: ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags); ok(pdp != NULL, "pdp == NULL\n"); ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs); ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); ok(!pvarRes, "pvarRes != NULL\n"); ok(pei != NULL, "pei == NULL\n"); ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg)); if(V_VT(pdp->rgvarg) == VT_BSTR) trace("%s: %s\n", test_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg))); return S_OK; case DISPID_GLOBAL_REPORTSUCCESS: CHECK_EXPECT(global_success_i); ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags); ok(pdp != NULL, "pdp == NULL\n"); ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs); ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); ok(!pvarRes, "pvarRes != NULL\n"); ok(pei != NULL, "pei == NULL\n"); return S_OK; case DISPID_GLOBAL_GETVT: ok(pdp != NULL, "pdp == NULL\n"); ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs); ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); ok(pvarRes != NULL, "pvarRes == NULL\n"); ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes)); ok(pei != NULL, "pei == NULL\n"); V_VT(pvarRes) = VT_BSTR; V_BSTR(pvarRes) = a2bstr(vt2a(pdp->rgvarg)); return S_OK; case DISPID_GLOBAL_ISENGLANG: ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags); ok(pdp != NULL, "pdp == NULL\n"); ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs); ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); ok(pvarRes != NULL, "pvarRes == NULL\n"); ok(pei != NULL, "pei == NULL\n"); V_VT(pvarRes) = VT_BOOL; if(is_lang_english()) { V_BOOL(pvarRes) = VARIANT_TRUE; }else { skip("Skipping some tests in non-English UIs\n"); V_BOOL(pvarRes) = VARIANT_FALSE; } return S_OK; case DISPID_GLOBAL_VBVAR: CHECK_EXPECT(global_vbvar_i); ok(wFlags == DISPATCH_PROPERTYPUT, "wFlags = %x\n", wFlags); ok(pdp != NULL, "pdp == NULL\n"); ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n"); ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs); ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs); ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]); ok(!pvarRes, "pvarRes != NULL\n"); ok(pei != NULL, "pei == NULL\n"); ok(V_VT(pdp->rgvarg) == VT_I2, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg)); ok(V_I2(pdp->rgvarg) == 3, "V_I2(psp->rgvargs) = %d\n", V_I2(pdp->rgvarg)); return S_OK; case DISPID_GLOBAL_TESTOBJ: ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags); ok(pdp != NULL, "pdp == NULL\n"); ok(!pdp->rgvarg, "rgvarg == NULL\n"); ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs); ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); ok(pvarRes != NULL, "pvarRes == NULL\n"); ok(pei != NULL, "pei == NULL\n"); V_VT(pvarRes) = VT_DISPATCH; V_DISPATCH(pvarRes) = (IDispatch*)&testObj; return S_OK; case DISPID_GLOBAL_ISNULLDISP: { VARIANT *v; ok(wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags); ok(pdp != NULL, "pdp == NULL\n"); ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs); ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); ok(pvarRes != NULL, "pvarRes == NULL\n"); ok(pei != NULL, "pei == NULL\n"); v = pdp->rgvarg; if(V_VT(v) == (VT_VARIANT|VT_BYREF)) v = V_VARIANTREF(v); ok(V_VT(v) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg)); V_VT(pvarRes) = VT_BOOL; V_BOOL(pvarRes) = V_DISPATCH(v) ? VARIANT_FALSE : VARIANT_TRUE; return S_OK; } case DISPID_GLOBAL_TESTDISP: ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags); ok(pdp != NULL, "pdp == NULL\n"); ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs); ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); ok(!pvarRes, "pvarRes != NULL\n"); ok(pei != NULL, "pei == NULL\n"); ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg)); test_disp(V_DISPATCH(pdp->rgvarg)); return S_OK; } ok(0, "unexpected call %d\n", id); return DISP_E_MEMBERNOTFOUND; }
HRESULT __RPC_STUB IDispatch_Invoke_Stub( IDispatch* This, DISPID dispIdMember, REFIID riid, LCID lcid, DWORD dwFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* pArgErr, UINT cVarRef, UINT* rgVarRefIdx, VARIANTARG* rgVarRef) { HRESULT hr = S_OK; VARIANTARG *rgvarg, *arg; UINT u; /* initialize out parameters, so that they can be marshalled * in case the real Invoke doesn't initialize them */ VariantInit(pVarResult); memset(pExcepInfo, 0, sizeof(*pExcepInfo)); *pArgErr = 0; /* let the real Invoke operate on a copy of the in parameters, * so we don't risk losing pointers to allocated memory */ rgvarg = pDispParams->rgvarg; arg = CoTaskMemAlloc(sizeof(VARIANTARG)*pDispParams->cArgs); if (!arg) return E_OUTOFMEMORY; /* init all args so we can call VariantClear on all the args if the copy * below fails */ for (u = 0; u < pDispParams->cArgs; u++) VariantInit(&arg[u]); for (u = 0; u < pDispParams->cArgs; u++) { hr = VariantCopy(&arg[u], &rgvarg[u]); if (FAILED(hr)) break; } if (SUCCEEDED(hr)) { pDispParams->rgvarg = arg; hr = IDispatch_Invoke(This, dispIdMember, riid, lcid, dwFlags, pDispParams, pVarResult, pExcepInfo, pArgErr); /* copy ref args to out list */ for (u=0; u<cVarRef; u++) { unsigned i = rgVarRefIdx[u]; VariantInit(&rgVarRef[u]); VariantCopy(&rgVarRef[u], &arg[i]); /* clear original if equal, to avoid double-free */ if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i])) VariantClear(&rgvarg[i]); } } /* clear the duplicate argument list */ for (u=0; u<pDispParams->cArgs; u++) VariantClear(&arg[u]); pDispParams->rgvarg = rgvarg; CoTaskMemFree(arg); return hr; }
//+--------------------------------------------------------------------------- // // Function: VARIANTARGToCVar // // Synopsis: Converts a VARIANT to a C-language variable. // // Arguments: [pvarg] -- Variant to convert. // [pfAlloc] -- BSTR allocated during conversion caller is // now owner of this BSTR or IUnknown or IDispatch // object allocated needs to be released. // [vt] -- Type to convert to. // [pv] -- Location to place C-language variable. // // Modifies: [pv]. // // Returns: HRESULT. // // History: 2-23-94 adams Created // // Notes: Supports all variant pointer types, VT_I2, VT_I4, VT_R4, // VT_R8, VT_ERROR. //---------------------------------------------------------------------------- HRESULT VARIANTARGToCVar(VARIANT* pvarg, BOOL* pfAlloc, VARTYPE vt, void* pv, IServiceProvider* pSrvProvider, WORD wMaxstrlen) { HRESULT hr = S_OK; VARIANTARG* pVArgCopy = pvarg; VARIANTARG vargNew; // variant of new type BOOL fAlloc; Assert(pvarg); Assert(pv); if(!pfAlloc) { pfAlloc = &fAlloc; } Assert((vt&~VT_TYPEMASK) == 0 || (vt&~VT_TYPEMASK)==VT_BYREF); // Assume no allocations yet. *pfAlloc = FALSE; if(vt & VT_BYREF) { // If the parameter is a variant pointer then everything is acceptable. if((vt&VT_TYPEMASK) == VT_VARIANT) { switch(V_VT(pvarg)) { case VT_VARIANT|VT_BYREF: hr = ClipVarString(pvarg->pvarVal, *(VARIANT**)pv, pfAlloc, wMaxstrlen); break; default: hr = ClipVarString(pvarg, *(VARIANT**)pv, pfAlloc, wMaxstrlen); break; } if(hr == S_FALSE) { hr = S_OK; *(PVOID*)pv = (PVOID)pvarg; } goto Cleanup; } if((V_VT(pvarg)&VT_TYPEMASK) != (vt&VT_TYPEMASK)) { hr = DISP_E_TYPEMISMATCH; goto Cleanup; } // Type of both original and destination or same type (however, original // may not be a byref only the original. if(V_ISBYREF(pvarg)) { // Destination and original are byref and same type just copy pointer. *(PVOID*)pv = V_BYREF(pvarg); } else { // Convert original to byref. switch(vt & VT_TYPEMASK) { case VT_BOOL: *(PVOID*)pv = (PVOID)&V_BOOL(pvarg); break; case VT_I2: *(PVOID*)pv = (PVOID)&V_I2(pvarg); break; case VT_ERROR: case VT_I4: *(PVOID*)pv = (PVOID)&V_I4(pvarg); break; case VT_R4: *(PVOID*)pv = (PVOID)&V_R4(pvarg); break; case VT_R8: *(PVOID*)pv = (PVOID)&V_R8(pvarg); break; case VT_CY: *(PVOID*)pv = (PVOID)&V_CY(pvarg); break; // All pointer types. case VT_PTR: case VT_BSTR: case VT_LPSTR: case VT_LPWSTR: case VT_DISPATCH: case VT_UNKNOWN: *(PVOID*)pv = (PVOID)&V_UNKNOWN(pvarg); break; case VT_VARIANT: Assert("Dead code: shudn't have gotten here!"); *(PVOID*)pv = (PVOID)pvarg; break; default: Assert(!"Unknown type in BYREF VARIANTARGToCVar().\n"); hr = DISP_E_TYPEMISMATCH; goto Cleanup; } } goto Cleanup; } // If the c style parameter is the same type as the VARIANT then we'll just // move the data. Also if the c style type is a VARIANT then there's // nothing to convert just copy the variant to the C parameter. else if((V_VT(pvarg)&(VT_TYPEMASK|VT_BYREF))!=vt && (vt!=VT_VARIANT)) { // If the request type isn't the same as the variant passed in then we // need to convert. VariantInit(&vargNew); pVArgCopy = &vargNew; hr = VariantChangeTypeSpecial(pVArgCopy, pvarg, vt,pSrvProvider); if(hr) { goto Cleanup; } *pfAlloc = (vt==VT_BSTR) || (vt==VT_UNKNOWN) || (vt==VT_DISPATCH); } // Move the variant data to C style data. switch(vt) { case VT_BOOL: // convert VT_TRUE and any other non-zero values to TRUE *(VARIANT_BOOL*)pv = V_BOOL(pVArgCopy); break; case VT_I2: *(short*)pv = V_I2(pVArgCopy); break; case VT_ERROR: case VT_I4: *(long*)pv = V_I4(pVArgCopy); break; case VT_R4: *(float*)pv = V_R4(pVArgCopy); break; case VT_R8: *(double*)pv = V_R8(pVArgCopy); break; case VT_CY: *(CY*)pv = V_CY(pVArgCopy); break; // All Pointer types. case VT_BSTR: if(wMaxstrlen && FormsStringLen(V_BSTR(pVArgCopy))>wMaxstrlen) { hr = FormsAllocStringLen(V_BSTR(pVArgCopy), wMaxstrlen, (BSTR*)pv); if(hr) { goto Cleanup; } if(*pfAlloc) { VariantClear(&vargNew); } else { *pfAlloc = TRUE; } goto Cleanup; } case VT_PTR: case VT_LPSTR: case VT_LPWSTR: case VT_DISPATCH: case VT_UNKNOWN: *(void**)pv = V_BYREF(pVArgCopy); break; case VT_VARIANT: hr = ClipVarString(pVArgCopy, (VARIANT*)pv, pfAlloc, wMaxstrlen); if(hr == S_FALSE) { hr = S_OK; // Copy entire variant to output parameter. *(VARIANT*)pv = *pVArgCopy; } break; default: Assert(FALSE && "Unknown type in VARIANTARGToCVar().\n"); hr = DISP_E_TYPEMISMATCH; break; } Cleanup: RRETURN(hr); }
HRESULT ModifyContextMenu(DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved) { ASSERT((ppt != NULL) && (pcmdtReserved != NULL)); if ((ppt == NULL) || (pcmdtReserved == NULL)) return S_OK; //#define IDR_BROWSE_CONTEXT_MENU 24641 //#define IDR_FORM_CONTEXT_MENU 24640 #define SHDVID_GETMIMECSETMENU 27 #define SHDVID_ADDMENUEXTENSIONS 53 HRESULT hr; HINSTANCE hinstSHDOCLC; HWND hwnd; HMENU hMenu; IOleCommandTarget *spCT; IOleWindow *spWnd; MENUITEMINFO mii = {0}; VARIANT var, var1, var2; hr = pcmdtReserved->QueryInterface(IID_IOleCommandTarget, (void**)&spCT); hr = pcmdtReserved->QueryInterface(IID_IOleWindow, (void**)&spWnd); hr = spWnd->GetWindow(&hwnd); hinstSHDOCLC = LoadLibrary(TEXT("SHDOCLC.DLL")); hMenu = LoadMenu(hinstSHDOCLC, MAKEINTRESOURCE(IDR_BROWSE_CONTEXT_MENU)); hMenu = GetSubMenu(hMenu, dwID); // Get the language submenu hr = spCT->Exec(&CGID_ShellDocView, SHDVID_GETMIMECSETMENU, 0, NULL, &var); mii.cbSize = sizeof(mii); mii.fMask = MIIM_SUBMENU; mii.hSubMenu = (HMENU) var.byref; // Add language submenu to Encoding context item SetMenuItemInfo(hMenu, IDM_LANGUAGE, FALSE, &mii); // Insert Shortcut Menu Extensions from registry V_VT(&var1) = VT_PTR; V_BYREF(&var1) = hMenu; V_VT(&var2) = VT_I4; V_I4(&var2) = dwID; hr = spCT->Exec(&CGID_ShellDocView, SHDVID_ADDMENUEXTENSIONS, 0, &var1, &var2); // Remove View Source ::DeleteMenu(hMenu, IDM_VIEWSOURCE, MF_BYCOMMAND); // Remove the item that produces the exta separator ::DeleteMenu(hMenu, IDM_EXTRA_ITEM, MF_BYCOMMAND); // Show shortcut menu int iSelection = ::TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, ppt->x, ppt->y, 0, hwnd, (RECT*)NULL); // Send selected shortcut menu item command to shell if (iSelection != 0) LRESULT lr = ::SendMessage(hwnd, WM_COMMAND, iSelection, NULL); FreeLibrary(hinstSHDOCLC); return S_OK; }
TclObject::TclObject (VARIANT *pSrc, const Type &type, Tcl_Interp *interp, int bytes) { if (V_ISARRAY(pSrc)) { SAFEARRAY *psa = V_ISBYREF(pSrc) ? *V_ARRAYREF(pSrc) : V_ARRAY(pSrc); VARTYPE elementType = V_VT(pSrc) & VT_TYPEMASK; unsigned numDimensions = SafeArrayGetDim(psa); std::vector<long> indices(numDimensions); m_pObj = convertFromSafeArray( psa, elementType, 1, &indices[0], type, interp, bytes); } else if (vtMissing == pSrc) { m_pObj = Extension::newNaObj(); } else { switch (V_VT(pSrc)) { case VT_BOOL: m_pObj = Tcl_NewBooleanObj(V_BOOL(pSrc)); break; case VT_ERROR: m_pObj = Tcl_NewLongObj(V_ERROR(pSrc)); break; case VT_I1: case VT_UI1: m_pObj = Tcl_NewLongObj(V_I1(pSrc)); break; case VT_I2: case VT_UI2: m_pObj = Tcl_NewLongObj(V_I2(pSrc)); break; case VT_I4: case VT_UI4: case VT_INT: case VT_UINT: m_pObj = Tcl_NewLongObj(V_I4(pSrc)); break; #ifdef V_I8 case VT_I8: case VT_UI8: m_pObj = Tcl_NewWideIntObj(V_I8(pSrc)); break; #endif case VT_R4: m_pObj = Tcl_NewDoubleObj(V_R4(pSrc)); break; case VT_DATE: case VT_R8: m_pObj = Tcl_NewDoubleObj(V_R8(pSrc)); break; case VT_DISPATCH: m_pObj = convertFromUnknown(V_DISPATCH(pSrc), type.iid(), interp); break; case VT_DISPATCH | VT_BYREF: m_pObj = convertFromUnknown( (V_DISPATCHREF(pSrc) != 0) ? *V_DISPATCHREF(pSrc) : 0, type.iid(), interp); break; case VT_UNKNOWN: m_pObj = convertFromUnknown(V_UNKNOWN(pSrc), type.iid(), interp); break; case VT_UNKNOWN | VT_BYREF: m_pObj = convertFromUnknown( (V_UNKNOWNREF(pSrc) != 0) ? *V_UNKNOWNREF(pSrc) : 0, type.iid(), interp); break; case VT_NULL: m_pObj = Extension::newNullObj(); break; case VT_LPSTR: m_pObj = Tcl_NewStringObj(V_I1REF(pSrc), -1); break; case VT_LPWSTR: { #if TCL_MINOR_VERSION >= 2 // Uses Unicode function introduced in Tcl 8.2. m_pObj = newUnicodeObj(V_UI2REF(pSrc), -1); #else const wchar_t *pWide = V_UI2REF(pSrc); _bstr_t str(pWide); m_pObj = Tcl_NewStringObj(str, -1); #endif } break; default: if (V_VT(pSrc) == VT_USERDEFINED && type.name() == "GUID") { Uuid uuid(*static_cast<UUID *>(V_BYREF(pSrc))); m_pObj = Tcl_NewStringObj( const_cast<char *>(uuid.toString().c_str()), -1); } else { if (V_VT(pSrc) == (VT_VARIANT | VT_BYREF)) { pSrc = V_VARIANTREF(pSrc); } _bstr_t str(pSrc); #if TCL_MINOR_VERSION >= 2 // Uses Unicode function introduced in Tcl 8.2. wchar_t *pWide = str; m_pObj = newUnicodeObj( reinterpret_cast<Tcl_UniChar *>(pWide), str.length()); #else m_pObj = Tcl_NewStringObj(str, -1); #endif } } } Tcl_IncrRefCount(m_pObj); }