HRESULT CBDictionary::putItem(VARIANT* pvarKey, VARIANT* pvar) { if(pvarKey->vt == VT_ERROR)return DISP_E_PARAMNOTOPTIONAL; if(pvarKey->vt & VT_ARRAY)return E_INVALIDARG; if(pvarKey->vt == VT_BSTR) { if(pvarKey->bstrVal == NULL) return DISP_E_TYPEMISMATCH; UINT len = SysStringByteLen(pvarKey->bstrVal); if(len & 1) return DISP_E_TYPEMISMATCH; for(UINT i = 0; i < len / 2; i ++) if(pvarKey->bstrVal[i] == 0) return DISP_E_TYPEMISMATCH; } if(pvar->vt == VT_ERROR) return DISP_E_PARAMNOTOPTIONAL; m_cs.Enter(); if(m_bArrayMode && (pvarKey->vt == VT_I4 || pvarKey->vt == VT_I2)) { long i = varGetNumber(*pvarKey); if(i >=0 && i < (int)m_posArray.GetCount()) { VariantCopyInd(&m_posArray[i]->m_value, pvar); m_cs.Leave(); return S_OK; } } CRBMap<CBVariant, CComVariant>::CPair* pPair = m_mapItems.Lookup(*(CBVariant*)pvarKey); if(pPair == NULL) { static VARIANT varTemp; pPair = (CRBMap<CBVariant, CComVariant>::CPair*)m_mapItems.SetAt(*(CBVariant*)pvarKey, varTemp); m_posArray.Add(pPair); } VariantCopyInd(&pPair->m_value, pvar); m_cs.Leave(); return S_OK; }
//////////////////////////////////////////////////////////////////////// // put_Value // HRESULT CDocProperty::put_Value(VARIANT *pvValue) { VARIANT vtTmp; vtTmp.vt = VT_EMPTY; ODS(_T("CDocProperty::put_Value\n")); CHECK_NULL_RETURN(pvValue, E_POINTER); CHECK_FLAG_RETURN((m_fDeadObj || m_fRemovedItem), E_INVALIDOBJECT); // We don't support arrays (in this sample at least)... if ((pvValue->vt) & VT_ARRAY) return E_INVALIDARG; // Sanity check of VARTYPE (if it is not one we can save, don't bother)... switch (((pvValue->vt) & VT_TYPEMASK)) { case VT_I2: case VT_I4: case VT_R4: case VT_R8: case VT_DATE: case VT_BSTR: case VT_BOOL: break; default: return E_INVALIDARG; } // Swap out the variant value and set the dirty flag. We make independent // copy of the VARIANT (performs indirection as needed)... m_fModified = TRUE; VariantClear(&m_vValue); return VariantCopyInd(&m_vValue, pvValue); }
static HRESULT invoke_variant_prop(script_ctx_t *ctx, VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res) { HRESULT hres; switch(flags) { case DISPATCH_PROPERTYGET|DISPATCH_METHOD: case DISPATCH_PROPERTYGET: if(dp->cArgs) { WARN("called with arguments\n"); return DISP_E_MEMBERNOTFOUND; /* That's what tests show */ } hres = VariantCopyInd(res, v); break; case DISPATCH_PROPERTYPUT: case DISPATCH_PROPERTYPUTREF: case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: { VARIANT put_val; BOOL own_val; hres = get_propput_arg(ctx, dp, flags, &put_val, &own_val); if(FAILED(hres)) return hres; if(arg_cnt(dp)) { FIXME("Arguments not supported\n"); return E_NOTIMPL; } if(res) V_VT(res) = VT_EMPTY; if(own_val) *v = put_val; else hres = VariantCopyInd(v, &put_val); break; } default: FIXME("unimplemented flags %x\n", flags); return E_NOTIMPL; } return hres; }
static HRESULT add_keyitem_pair(dictionary *dict, VARIANT *key, VARIANT *item) { struct keyitem_pair *pair; struct list *head; VARIANT hash; HRESULT hr; hr = IDictionary_get_HashVal(&dict->IDictionary_iface, key, &hash); if (FAILED(hr)) return hr; pair = heap_alloc(sizeof(*pair)); if (!pair) return E_OUTOFMEMORY; pair->hash = V_I4(&hash); VariantInit(&pair->key); VariantInit(&pair->item); hr = VariantCopyInd(&pair->key, key); if (FAILED(hr)) goto failed; hr = VariantCopyInd(&pair->item, item); if (FAILED(hr)) goto failed; head = get_bucket_head(dict, pair->hash); if (!head->next) /* this only happens once per bucket */ list_init(head); /* link to bucket list and to full list */ list_add_tail(head, &pair->bucket); list_add_tail(&dict->pairs, &pair->entry); dict->count++; return S_OK; failed: VariantClear(&pair->key); VariantClear(&pair->item); heap_free(pair); return hr; }
static HRESULT invoke_variant_prop(VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res) { HRESULT hres; switch(flags) { case DISPATCH_PROPERTYGET|DISPATCH_METHOD: case DISPATCH_PROPERTYGET: if(dp->cArgs) { WARN("called with arguments\n"); return DISP_E_MEMBERNOTFOUND; /* That's what tests show */ } hres = VariantCopyInd(res, v); break; case DISPATCH_PROPERTYPUT: { VARIANT *put_val; put_val = get_propput_arg(dp); if(!put_val) { WARN("no value to set\n"); return DISP_E_PARAMNOTOPTIONAL; } if(arg_cnt(dp)) { FIXME("Arguments not supported\n"); return E_NOTIMPL; } if(res) V_VT(res) = VT_EMPTY; hres = VariantCopyInd(v, put_val); break; } default: FIXME("unimplemented flags %x\n", flags); return E_NOTIMPL; } return hres; }
STDMETHODIMP CBQueue::AddTail(VARIANT var) { VARIANT varTemp = {VT_EMPTY}; VariantCopyInd(&varTemp, &var); m_cs.Enter(); m_listItems.AddTail(varTemp); m_cs.Leave(); return S_OK; }
SEXP createRVariantObject(VARIANT *var, VARTYPE kind) { const char *className; SEXP klass, ans, tmp; VARIANT *dupvar; switch(kind) { case VT_DATE: className = "DateVARIANT"; break; case VT_CY: className = "CurrencyVARIANT"; break; default: className = "VARIANT"; } PROTECT(klass = MAKE_CLASS(className)); if(klass == NULL || klass == R_NilValue) { PROBLEM "Can't locate S4 class definition %s", className ERROR; } dupvar = (VARIANT *) malloc(sizeof(VARIANT)); VariantCopyInd(dupvar, var); PROTECT(ans = NEW(klass)); PROTECT(tmp = R_MakeExternalPtr(dupvar, Rf_install(className), R_NilValue)); R_RegisterCFinalizer(tmp, R_Variant_finalizer); SET_SLOT(ans, Rf_install("ref"), tmp); UNPROTECT(1); PROTECT(tmp = NEW_INTEGER(1)); INTEGER(tmp)[0] = kind; SET_SLOT(ans, Rf_install("kind"), tmp); UNPROTECT(3); return(ans); }
zend_object* php_com_object_clone(zval *object) { php_com_dotnet_object *cloneobj, *origobject; origobject = (php_com_dotnet_object*)Z_OBJ_P(object); cloneobj = (php_com_dotnet_object*)emalloc(sizeof(php_com_dotnet_object)); memcpy(cloneobj, origobject, sizeof(*cloneobj)); /* VariantCopy will perform VariantClear; we don't want to clobber * the IDispatch that we memcpy'd, so we init a new variant in the * clone structure */ VariantInit(&cloneobj->v); /* We use the Indirection-following version of the API since we * want to clone as much as possible */ VariantCopyInd(&cloneobj->v, &origobject->v); if (cloneobj->typeinfo) { ITypeInfo_AddRef(cloneobj->typeinfo); } return (zend_object*)cloneobj; }
PHP_COM_DOTNET_API void php_com_wrap_variant(zval *z, VARIANT *v, int codepage) { php_com_dotnet_object *obj; obj = emalloc(sizeof(*obj)); memset(obj, 0, sizeof(*obj)); obj->code_page = codepage; obj->ce = php_com_variant_class_entry; obj->zo.ce = php_com_variant_class_entry; VariantInit(&obj->v); VariantCopyInd(&obj->v, v); obj->modified = 0; if ((V_VT(&obj->v) == VT_DISPATCH) && (V_DISPATCH(&obj->v) != NULL)) { IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo); } zend_object_std_init(&obj->zo, php_com_variant_class_entry); obj->zo.handlers = &php_com_object_handlers; ZVAL_OBJ(z, &obj->zo); }
STDMETHODIMP CAvatarProfileObject::AddKey(BSTR bstrKey, VARIANT varKeyVal, VARIANT varStrGraphic, VARIANT varAccess, VARIANT varOwner) { HRESULT hr = S_OK; CComVariant varTemp; long psbits = 0; IThing* pUser = NULL; IThing* pCaller = NULL; IThing* pOwner = NULL; IAvatarProfileData* pProfileData = NULL; VARIANT_BOOL bShouldExecute = VARIANT_TRUE; VARIANT_BOOL bShouldRemote = VARIANT_FALSE; VARIANT_BOOL bShouldNotify = VARIANT_FALSE; // REVIEW: should really create an AddKeyExt method which takes the real datatypes hr = VariantCopyInd(&varTemp, &varKeyVal); if (FAILED(hr)) goto ERROR_ENCOUNTERED; if (m_pWorld) { hr = m_pWorld->ValidateProperty(varTemp); if (FAILED(hr)) goto ERROR_ENCOUNTERED; } GetMarshallingFlags(&bShouldExecute, &bShouldRemote, &bShouldNotify); if (bShouldRemote == VARIANT_TRUE) GetMarshallingBits(&psbits, &bShouldExecute, &bShouldRemote, &bShouldNotify); #ifdef _DEBUG VWTRACE(m_pWorld, "VWPROPERTY", VWT_METHOD, "CAvatarProfileObject::AddKey\n"); #endif if (bShouldExecute == VARIANT_TRUE) { VARIANT_BOOL bValid = VARIANT_FALSE; CComBSTR bstrGraphic; short sAccess = 0; if (m_pParent) { if (FAILED(m_pParent->CheckPropertySecurityExt(m_bstrPropertyName, PS_WRITE))) { VWTRACE(m_pWorld, "VWOBJECT", VWT_ERROR, "CAvatarProfileObject::AddKey: security violation (PS_WRITE)\n"); hr = VWOBJECT_E_PERMISSION_DENIED; goto ERROR_ENCOUNTERED; } } if (m_pKeys == NULL) { VWTRACE(m_pWorld, "VWPROPERTY", VWT_ERROR, "CAvatarProfileObject::AddKey: invalid key map\n"); hr = VWAVATARPROFILE_E_INVALIDKEYMAP; goto ERROR_ENCOUNTERED; } if (m_pBannedObjects == NULL) { VWTRACE(m_pWorld, "VWPROPERTY", VWT_ERROR, "CAvatarProfileObject::AddKey: invalid banned object list\n"); hr = VWAVATARPROFILE_E_INVALIDBANNEDOBJECTLIST; goto ERROR_ENCOUNTERED; } // if user isn't avatar if (bShouldRemote == VARIANT_TRUE) { hr = m_pWorld->get_User(&pUser); if (FAILED(hr)) goto ERROR_ENCOUNTERED; // we are the originator - check protocol if (pUser && m_pAvatar && (pUser != m_pAvatar)) { long lIndex = -1; /* hr = */ m_pBannedObjects->Find(CComVariant(pUser), &lIndex); // if user is banned object, fail if (lIndex != -1) { VWTRACE(m_pWorld, "VWPROPERTY", VWT_ERROR, "CAvatarProfileObject::AddKey: user is banned object, failed to add key\n"); hr = VWAVATARPROFILE_E_BANNEDOBJECT; goto ERROR_ENCOUNTERED; } } } // if key already exists, fail hr = m_pKeys->IsValid(bstrKey, &bValid); if (FAILED(hr)) goto ERROR_ENCOUNTERED; if (bValid == VARIANT_TRUE) { #ifdef _DEBUG VWTRACE(m_pWorld, "VWPROPERTY", VWT_IMPORTANT, "CAvatarProfileObject::AddKey: key (%s) already exists, failed to add key\n", CString(bstrKey)); #endif hr = VWAVATARPROFILE_E_KEYEXISTS; goto ERROR_ENCOUNTERED; } // add the property.. pProfileData = new CComAvatarProfileData; if (pProfileData == NULL) goto ERROR_ENCOUNTERED; pProfileData->AddRef(); /* hr = */ pProfileData->put_World(m_pWorld); // now, create the optional data items if (varStrGraphic.vt == VT_BSTR) bstrGraphic = varStrGraphic.bstrVal; if ((varAccess.vt == VT_EMPTY) || (varAccess.vt == VT_ERROR)) sAccess = kKeyPublic; else { CComVariant varI2; ::VariantChangeType(&varI2, &varAccess, 0, VT_I2); ASSERT(varI2.vt == VT_I2); sAccess = (short)varI2.iVal; } if (varOwner.vt == VT_DISPATCH) { pOwner = (IThing *)varOwner.pdispVal; SAFEADDREF(pOwner); } else { // if no owner passed in, set owner to be avatar pOwner = m_pAvatar; SAFEADDREF(pOwner); } // can only set the owner to the user if (bShouldRemote == VARIANT_TRUE) { // REVIEW: why are we resetting the owner? hr = m_pWorld->get_Caller(&pCaller); if (FAILED(hr)) goto ERROR_ENCOUNTERED; // check protocol: // otherwise, make sure passed in owner is either user or caller if ((pOwner != NULL) && (pUser != NULL) && (pCaller != NULL) && (pOwner != pUser) && (pOwner != pCaller)) { #ifdef _DEBUG CComBSTR bstrUser("n/a"), bstrCaller("n/a"), bstrOwner("n/a"); /* hr = */ pUser->get_Name(&bstrUser.m_str); /* hr = */ pCaller->get_Name(&bstrCaller.m_str); /* hr = */ pOwner->get_Name(&bstrOwner.m_str); VWTRACE(m_pWorld, "VWPROPERTY", VWT_ERROR, "CAvatarProfileObject::AddKey: invalid owner (not user or caller), user (%s), caller (%s), owner (%s)\n", CString(bstrUser), CString(bstrCaller), CString(bstrOwner)); #endif hr = VWAVATARPROFILE_E_INVALIDOWNER; goto ERROR_ENCOUNTERED; } } /* hr = */ pProfileData->put_Value(varTemp); /* hr = */ pProfileData->put_Owner(pOwner); /* hr = */ pProfileData->put_Graphic(bstrGraphic); /* hr = */ pProfileData->put_Access(sAccess); hr = m_pKeys->put_ObjectProperty(bstrKey, pProfileData); if (FAILED(hr)) goto ERROR_ENCOUNTERED; } // remote if (bShouldRemote == VARIANT_TRUE) { DISPPARAMS dispparams; // package up args into DISPPARAMS struct hr = InitializeDISPPARAMS(&dispparams, 5); if (FAILED(hr)) goto ERROR_ENCOUNTERED; dispparams.rgvarg[4].vt = VT_BSTR; dispparams.rgvarg[4].bstrVal = bstrKey; dispparams.rgvarg[3] = varTemp; dispparams.rgvarg[2] = varStrGraphic; dispparams.rgvarg[1] = varAccess; dispparams.rgvarg[0] = varOwner; hr = SendObjectPropertyCommand(psbits, DISPID_AVATARPROFILE_ADDKEY, DISPATCH_METHOD, &dispparams); TerminateDISPPARAMS(VARIANT_FALSE, &dispparams); if (FAILED(hr)) goto ERROR_ENCOUNTERED; } // Notify if (bShouldNotify == VARIANT_TRUE) { // notify client/server and world of property change if (m_pParent) { hr = m_pParent->NotifyObjectPropertyChanged(this, profileAddKey, CComVariant(bstrKey)); if (FAILED(hr)) goto ERROR_ENCOUNTERED; } } ERROR_ENCOUNTERED: SAFERELEASE(pOwner); SAFERELEASE(pUser); SAFERELEASE(pCaller); SAFERELEASE(pProfileData); return hr; }
static int cmdfunc_ctrlcmd( int cmd ) { // cmdfunc : TYPE_DLLCTRL // (拡張DLLコントロールコマンド) // code_next(); // 次のコードを取得(最初に必ず必要です) if ( cmd >= TYPE_OFFSET_COMOBJ ) { #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else // COM インターフェースメソッドの呼び出し STRUCTDAT *st; st = GetPRM( cmd - TYPE_OFFSET_COMOBJ ); hspctx->stat = code_expand_and_call( st ); return RUNMODE_RUN; #endif } switch( cmd ) { // サブコマンドごとの分岐 case 0x00: // newcom #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval; APTR aptr; IUnknown **ppunkNew, *punkDef; CLSID clsid; char *clsid_name; const IID *piid, *piid2; void *iptr; LIBDAT *lib; STRUCTDAT *st; int inimode; // 第1パラメータ:新しいインターフェースポインタを格納する変数 // (変数にNULLポインタを格納) aptr = code_getva( &pval ); iptr = NULL; code_setva( pval, aptr, TYPE_COMOBJ, &iptr ); ppunkNew = (IUnknown **)HspVarCorePtrAPTR( pval, aptr ); // CLSID / IID 情報を取得 if ( !code_getexflg() && *type == TYPE_DLLCTRL ) { // 第2パラメータ:#usecom 登録情報 st = code_getcomst(); if ( st->otindex != -1 ) throw HSPERR_TYPE_MISMATCH; lib = &hspctx->mem_linfo[ st->index ]; if ( lib->clsid == -1 ) throw HSPERR_INVALID_PARAMETER; clsid_name = strp(lib->clsid); piid = (IID *)strp( lib->nameidx ); piid2 = NULL; } else { // 第2パラメータ:文字列 CLSID // (IID はデフォルトで IID_IDispatch, サポートされていなければ IID_IUnknown ) clsid_name = code_getds(""); piid = &IID_IDispatch; piid2 = &IID_IUnknown; } inimode = code_getdi(0); // 初期化モード punkDef = (IUnknown *)code_getdi(0); // デフォルトオブジェクト // 新規CLSIDからインスタンスを作成 hspctx->stat = 0; switch ( inimode ) { case 0: // 新規にロード if ( clsid_name[0]!='\0' ) { if ( GetIIDFromString(&clsid,clsid_name,true) != FALSE && SUCCEEDED( CoCreateInstance( clsid, NULL, CLSCTX_SERVER, *piid, (void**)ppunkNew )) && *ppunkNew != NULL ) { break; } if ( piid2 != NULL && SUCCEEDED( CoCreateInstance( clsid, NULL, CLSCTX_SERVER, *piid2, (void**)ppunkNew )) && *ppunkNew != NULL ) { break; } hspctx->stat = 1; } break; case -2: // オブジェクトを明示的に指定する場合 ( AddRef() あり) if ( punkDef != NULL ) punkDef->AddRef(); case -1: // オブジェクトを明示的に指定する場合 ( AddRef() なし) *ppunkNew = punkDef; break; default: throw HSPERR_UNSUPPORTED_FUNCTION; } #ifdef HSP_COMOBJ_DEBUG COM_DBG_MSG( "newcom : pObj=%p : &pObj=%p\n", *ppunkNew, ppunkNew); #endif break; } #endif // HSP_COM_UNSUPPORTED case 0x01: // querycom #ifdef HSP_COM_UNSUPPORTED throw HSPERR_UNSUPPORTED_FUNCTION; #else { PVal *pval, *pvalNew; APTR aptr, aptrNew; IUnknown **ppunkDst, **ppunkSrc; IID iid; const IID *piid; void *iptr; STRUCTDAT *st; LIBDAT *lib; // 第1パラメータ:新しいインターフェースポインタを格納する変数 aptrNew = code_getva( &pvalNew ); // 第2パラメータ:既存のCOMオブジェクト aptr = code_getva( &pval ); if ( pval->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH ); ppunkSrc = (IUnknown **)HspVarCorePtrAPTR( pval, aptr ); if ( ! IsVaridComPtr(ppunkSrc) ) throw ( HSPERR_COMDLL_ERROR ); // IID 情報を取得 if ( *type == TYPE_DLLCTRL ) { // 第3パラメータ:#usecom 登録情報 st = code_getcomst(); if ( st->otindex != -1 ) throw ( HSPERR_TYPE_MISMATCH ); lib = &hspctx->mem_linfo[ st->index ]; piid = (IID *)strp( lib->nameidx ); } else { // 第3パラメータ:文字列 IID GetIIDFromString( &iid, code_gets() ); piid = &iid; } if ( pvalNew->flag != TYPE_COMOBJ ) { // 代入により型変換 iptr = NULL; code_setva( pvalNew, aptrNew, TYPE_COMOBJ, &iptr ); } ppunkDst = (IUnknown **)HspVarCorePtrAPTR( pvalNew, aptrNew ); // query によりインスタンスを得る QueryComPtr( ppunkDst, *ppunkSrc, piid ); if ( IsVaridComPtr(ppunkSrc) ) hspctx->stat = 0; else hspctx->stat = 1; break; } #endif // HSP_COM_UNSUPPORTED case 0x02: // delcom #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval; APTR aptr; IUnknown **ppunk; VARIANT *var; void *ptr; // 第1パラメータ:解放するCOMオブジェクト変数 aptr = code_getva( &pval ); ptr = HspVarCorePtrAPTR( pval, aptr ); switch ( pval->flag ) { case TYPE_COMOBJ: ppunk = (IUnknown **)ptr; ReleaseComPtr( ppunk ); break; case TYPE_VARIANT: var = (VARIANT *)ptr; VariantClear( var ); break; default: throw HSPERR_TYPE_MISMATCH; } // このタイミングで一時オブジェクトも削除しちゃう if ( comconv_var.vt != VT_EMPTY ) VariantClear( &comconv_var ); break; } #endif // HSP_COM_UNSUPPORTED case 0x03: // cnvstow { PVal *pval; char *ptr; char *ps; int size; ptr = code_getvptr( &pval, &size ); ps = code_gets(); cnvwstr( ptr, ps, size/2 ); break; } case 0x04: // comres #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else if ( code_getexflg() ) { comres_pval = NULL; comres_aptr = 0; } else { comres_aptr = code_getva( &comres_pval ); } break; #endif // HSP_COM_UNSUPPORTED case 0x05: // axobj #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval; APTR aptr; const IID *piid; void *iptr; BMSCR *bm; HWND hwnd; int id,sx,sy; char clsid_name[1024]; IUnknown **ppunk, *punkObj, *punkObj2; STRUCTDAT *st; LIBDAT *lib; HRESULT hr; bm = GetBMSCR(); // 第1パラメータ:新しいインターフェースポインタを格納する変数 // (あらかじめ変数にNULLを格納) aptr = code_getva( &pval ); iptr = NULL; code_setva( pval, aptr, TYPE_COMOBJ, &iptr ); ppunk = (IUnknown **)HspVarCorePtrAPTR( pval, aptr ); // オブジェクトの CLSID, ProgID, etc. if ( *type == TYPE_DLLCTRL ) { // 第2パラメータ:#usecom 登録情報から取得 st = code_getcomst(); if ( st->otindex != -1 ) throw ( HSPERR_TYPE_MISMATCH ); lib = &hspctx->mem_linfo[ st->index ]; piid = (IID *)strp( lib->nameidx ); if ( lib->clsid == -1 ) throw ( HSPERR_INVALID_PARAMETER ); strncpy( clsid_name, strp(lib->clsid), sizeof(clsid_name)-1 ); } else { // 第2パラメータ:文字列 CLSID or ProgID を取得 (IID は IDispatch) piid = &IID_IDispatch; strncpy( clsid_name, code_gets(), sizeof(clsid_name)-1 ); } // コントロールのサイズ sx = code_getdi( bm->sx ); sy = code_getdi( bm->sy ); // ActiveXとしてロード // if ( fn_atxinit == NULL ) throw ( HSPERR_UNSUPPORTED_FUNCTION ); hwnd = CreateWindow( atxwndclass, clsid_name, WS_CHILD, // 最初は WS_VISIBLE なし (後で ShowWindow() ) bm->cx, bm->cy, sx, sy, bm->hwnd, (HMENU)0, (HINSTANCE)hspctx->instance, NULL ); punkObj2 = NULL; if ( hwnd ) { punkObj = NULL; fn_atxgetctrl( hwnd, (void**)&punkObj ); if ( punkObj ) { // 指定 IID が存在するかどうか hr = punkObj->QueryInterface( *piid, (void**)&punkObj2 ); punkObj->Release(); } } if ( punkObj2 == NULL ) { // 目的オブジェクトではないときコントロールを削除 if (hwnd) { DestroyWindow( hwnd ); } hspctx->stat = -1; break; } // COM 型変数に格納 *ppunk = punkObj2; // HSPのウインドゥオブジェクトとして登録する ShowWindow( hwnd, SW_SHOW ); id = AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, sy ); #ifdef HSP_COMOBJ_DEBUG Alertf( "axobj : pObj=%p : &pObj=%p\n", *ppunk, ppunk); #endif break; } #endif // HSP_COM_UNSUPPORTED case 0x06: // winobj { #ifdef HSPDISH throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else char clsname[1024]; char winname[1024]; HWND hwnd; char *ps; BMSCR *bm; int i; int prm[6]; ps = code_gets(); strncpy( clsname, ps, 1023 ); ps = code_gets(); strncpy( winname, ps, 1023 ); bm = GetBMSCR(); for(i=0;i<6;i++) { prm[i] = code_getdi(0); } if ( prm[2] <= 0 ) prm[2] = bm->ox; if ( prm[3] <= 0 ) prm[3] = bm->oy; hwnd = CreateWindowEx( (DWORD) prm[0], // 拡張ウィンドウスタイル clsname, // ウィンドウクラス名 winname, // ウィンドウ名 (DWORD) prm[1], // ウィンドウスタイル bm->cx, bm->cy, prm[2], prm[3], // X,Y,SIZEX,SIZEY bm->hwnd, // 親ウィンドウのハンドル (HMENU) prm[4], // メニューハンドルまたは子ウィンドウID bm->hInst, // インスタンスハンドル (PVOID) prm[5] // ウィンドウ作成データ ); // AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, prm[3], NULL, 0 ); // HSPのウインドゥオブジェクトとして登録する AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, prm[3] ); break; #endif // HSPDISH } case 0x07: // sendmsg { int hw,p1,p2,p3,p4,fl,sz; char *vptr; hw = code_getdi(0); p1 = code_getdi(0); vptr = code_getsptr( &fl ); if ( fl == TYPE_STRING ) { p2 = (int)code_stmpstr( vptr ); } else { p2 = *(int *)vptr; } vptr = code_getsptr( &fl ); if ( fl == TYPE_STRING ) { p3 = (int)vptr; } else { p3 = *(int *)vptr; } //Alertf( "SEND[%x][%x][%x]",p1,p2,p3 ); hspctx->stat = (int)SendMessage( (HWND)hw, p1, p2, p3 ); break; } case 0x08: // comevent #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval; APTR aptr; void* iptr; char *ps; IID iid, *piid; unsigned short *subr; IUnknown **ppunk, **ppunkEvent; // 第1パラメータ:イベントハンドラオブジェクト (IEventHandler) を格納する変数 // (あらかじめ NULL で初期化) aptr = code_getva( &pval ); iptr = NULL; code_setva( pval, aptr, TYPE_COMOBJ, &iptr ); ppunkEvent = (IUnknown **)HspVarCorePtrAPTR( pval, aptr ); // 第2パラメータ:COMオブジェクトを格納した変数 aptr = code_getva( &pval ); if ( pval->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH ); ppunk = (IUnknown **)HspVarCorePtrAPTR( pval, aptr ); if ( ! IsVaridComPtr(ppunk) ) throw ( HSPERR_COMDLL_ERROR ); // 第3パラメータ:コネクションポイントIID (文字列形式) ps = code_getds(""); if ( ps[0] != '\0' ) { piid = &iid; GetIIDFromString( piid, ps ); } else { piid = NULL; // NULL のときデフォルトIID が自動的に取得される } // 第4パラメータ:コールバック用のサブルーチンラベル subr = code_getlb2(); // イベントハンドラ作成・接続 SetComEvent( ppunkEvent, ppunk, piid, subr ); #ifdef HSP_COMOBJ_DEBUG COM_DBG_MSG( "comevent : pEvent=%p : pObj=%p\n", *ppunkEvent, *ppunk); #endif break; } #endif // HSP_COM_UNSUPPORTED case 0x09: // comevarg #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval, *pval2; APTR aptr, aptr2; VARIANT *v; void *ptr; int p1,p2; int res; IUnknown **ppunk; VARIANT varTemp; // 第1パラメータ:イベントのパラメータを格納する変数 aptr = code_getva( &pval ); // 第2パラメータ:イベントハンドラオブジェクト変数 aptr2 = code_getva( &pval2 ); if ( pval2->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH ); ppunk = (IUnknown **)HspVarCorePtrAPTR( pval2, aptr2 ); if ( ! IsVaridComPtr(ppunk) ) throw ( HSPERR_COMDLL_ERROR ); // 第3パラメータ:パラメータインデックス p1 = code_getdi(0); // 第4パラメータ:文字列変換フラグ p2 = code_getdi(0); // イベントのパラメータ取得 v = GetEventArg( *ppunk, p1 ); if ( v == NULL ) throw ( HSPERR_ILLEGAL_FUNCTION ); switch ( p2 ) { case 0: VariantInit( &varTemp ); VariantCopyInd( &varTemp, v ); ptr = comget_variant( &varTemp, &res ); VariantClear( &varTemp ); break; case 1: VariantInit( &varTemp ); if FAILED( VariantChangeType( &varTemp, v, VARIANT_ALPHABOOL, VT_BSTR ) ) throw ( HSPERR_TYPE_INITALIZATION_FAILED ); ptr = comget_variant( &varTemp, &res ); VariantClear( &varTemp ); break; case 2: ptr = v; res = HSPVAR_FLAG_VARIANT; break; default: throw ( HSPERR_ILLEGAL_FUNCTION ); } code_setva( pval, aptr, res, ptr ); hspctx->stat = res; break; } #endif // HSP_COM_UNSUPPORTED case 0x0a: // sarrayconv #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval1, *pval2; APTR aptr1, aptr2; int convdir, size; VARIANT *variant, varTemp; VARTYPE vt; SAFEARRAY *psa; long lbound, ubound; HRESULT hr; aptr1 = code_getva( &pval1 ); aptr2 = code_getva( &pval2 ); convdir = code_getdi(0); size = code_getdi(0); switch ( convdir ) { case 0: case 2: case 4: // 配列変数から SafeArray に変換 VariantInit( &varTemp ); code_setva( pval1, aptr1, HSPVAR_FLAG_VARIANT, &varTemp ); variant = (VARIANT *)HspVarCorePtrAPTR( pval1, aptr1 ); VariantClear( variant ); // 一応 if ( convdir == 2 ) { // バイナリデータ(一次元のみ) void *ptr = HspVarCorePtrAPTR( pval2, aptr2 ); psa = CreateBinarySafeArray( ptr, size, &vt ); } else { BOOL bVariant = ( convdir == 4 ); psa = ConvVar2SafeArray( pval2, bVariant, &vt ); } variant->vt = vt | VT_ARRAY; variant->parray = psa; break; case 1: case 3: // SafeArray から配列変数に変換 if ( pval2->flag != HSPVAR_FLAG_VARIANT ) throw HSPERR_INVALID_TYPE; variant = (VARIANT *)HspVarCorePtrAPTR( pval2, aptr2 ); if ( (variant->vt & VT_ARRAY) == 0 ) throw HSPERR_INVALID_TYPE; psa = variant->parray; if ( psa == NULL ) throw HSPERR_ARRAY_OVERFLOW; vt = variant->vt & VT_TYPEMASK; if ( vt == VT_EMPTY ) { hr = SafeArrayGetVartype( psa, &vt ); if ( FAILED(hr) || vt == VT_EMPTY ) throw HSPERR_INVALID_ARRAYSTORE; } if ( convdir == 1 ) { ConvSafeArray2Var( pval1, psa, vt ); } else { // バイナリデータ(一次元のみ) int varsize; void *ptr = HspVarCorePtrAPTR( pval1, aptr1 ); if ( vt != VT_UI1 && vt != VT_I1 ) throw HSPERR_INVALID_TYPE; SafeArrayGetLBound( psa, 1, &lbound ); hr = SafeArrayGetUBound( psa, 1, &ubound ); if ( FAILED(hr) ) throw HSPERR_ARRAY_OVERFLOW; size = ubound - lbound + 1; HspVarCoreGetBlockSize( pval1, (PDAT*)ptr, &varsize ); if ( varsize < size ) throw HSPERR_BUFFER_OVERFLOW; GetBinarySafeArray( ptr, size, psa ); } break; default: throw ( HSPERR_UNSUPPORTED_FUNCTION ); } break; } #endif // HSP_COM_UNSUPPORTED default: throw ( HSPERR_SYNTAX ); } return RUNMODE_RUN; }
void *comget_variant( VARIANT *var, int *restype, BOOL fvariantret /* = FALSE*/ ) { // VARIANT型→HSPの型に変換する // int size; BSTR bstr; /* rev 43 mingw : warning : 定数へのポインタを非定数へのポインタに代入 に対処 */ void const *ptr; if ( fvariantret ) { VariantCopy( &comconv_var, var ); *restype = HSPVAR_FLAG_VARIANT; return &comconv_var; } VariantCopyInd( &comconv_var, var ); switch ( comconv_var.vt ) { case VT_R4: VariantChangeType( &comconv_var, &comconv_var, VARIANT_NOVALUEPROP, VT_R8 ); case VT_R8: *restype = HSPVAR_FLAG_DOUBLE; return &comconv_var.dblVal; case VT_BSTR: // 文字列全体を返すため、ANSI文字列をバイナリデータBSTRとして格納 ptr = comconv_var.bstrVal; if ( ptr == NULL ) ptr = L""; size = cnvsjis( NULL, (char *)ptr, 0 ); bstr = SysAllocStringByteLen( NULL, size ); if ( bstr == NULL ) throw HSPERR_OUT_OF_MEMORY; cnvsjis( (char *)bstr, (char *)ptr, size ); SysFreeString( comconv_var.bstrVal ); comconv_var.bstrVal = bstr; *restype = HSPVAR_FLAG_STR; return comconv_var.bstrVal; case VT_DISPATCH: case VT_UNKNOWN: *restype = HSPVAR_FLAG_COMSTRUCT; return &comconv_var.punkVal; case VT_I2: case VT_UI2: case VT_I1: case VT_UI1: case VT_I8: case VT_UI8: case VT_BOOL: VariantChangeType( &comconv_var, &comconv_var, VARIANT_NOVALUEPROP, VT_I4 ); case VT_I4: case VT_UI4: case VT_ERROR: case VT_INT: case VT_UINT: *restype = HSPVAR_FLAG_INT; return &comconv_var.lVal; default: if ( comconv_var.vt & VT_ARRAY ) { *restype = HSPVAR_FLAG_VARIANT; // SafeArray は Variant 型変数で扱う return &comconv_var; } throw HSPERR_INVALID_TYPE; } }
STDMETHODIMP CBDictionary::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { if((dispIdMember & 0xff000000) != 0x65000000) return CBDispatch<IVariantDictionary>::g_typeinfo.Invoke((IVariantDictionary*)this, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); dispIdMember &= 0xffffff; CBLock l(&m_cs); if(dispIdMember < (int)m_posArray.GetCount()) { if((wFlags & (DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF)) && pDispParams->cArgs == 1) { VARIANT* pvar = pDispParams->rgvarg; while(pvar->vt == (VT_VARIANT | VT_BYREF)) pvar = pvar->pvarVal; if(!(wFlags & DISPATCH_PROPERTYPUTREF) && (pvar->vt == VT_UNKNOWN || pvar->vt == VT_DISPATCH)) { l.Unlock(); if(pvar->punkVal == NULL) return DISP_E_UNKNOWNINTERFACE; CBDispatchPtr pDisp; CComVariant var; HRESULT hr = pvar->punkVal->QueryInterface(&pDisp); if(FAILED(hr))return hr; hr = pDisp.GetProperty(0, &var); if(FAILED(hr))return hr; l.Lock(); if(dispIdMember < (int)m_posArray.GetCount()) { var.Detach(&m_posArray[dispIdMember]->m_value); return S_OK; }else return DISP_E_MEMBERNOTFOUND; }else return VariantCopyInd(&m_posArray[dispIdMember]->m_value, pvar); }else if(pDispParams->cArgs == 0) { if(pVarResult != NULL) return VariantCopy(pVarResult, &m_posArray[dispIdMember]->m_value); return S_OK; } VARIANT *pvar = &m_posArray[dispIdMember]->m_value; if(pvar->vt == VT_UNKNOWN || pvar->vt == VT_DISPATCH) { CBDispatchPtr pDisp; HRESULT hr = pvar->punkVal->QueryInterface(&pDisp); if(FAILED(hr)) return DISP_E_BADPARAMCOUNT; l.Unlock(); return pDisp->Invoke(0, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); } return DISP_E_BADPARAMCOUNT; }else return DISP_E_MEMBERNOTFOUND; return S_OK; }