mshtml: Added IPropertyBag::Read implementation.
This commit is contained in:
parent
9fa8afd095
commit
0849079287
|
@ -1685,6 +1685,23 @@ interface nsIDOMHTMLObjectElement : nsIDOMHTMLElement
|
|||
nsresult GetContentDocument(nsIDOMDocument **aContentDocument);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(a6cf90ad-15b3-11d2-932e-00805f8add32),
|
||||
local
|
||||
]
|
||||
interface nsIDOMHTMLParamElement : nsIDOMHTMLElement
|
||||
{
|
||||
nsresult GetName(nsAString *aName);
|
||||
nsresult SetName(const nsAString *aName);
|
||||
nsresult GetType(nsAString *aType);
|
||||
nsresult SetType(const nsAString *aType);
|
||||
nsresult GetValue(nsAString *aValue);
|
||||
nsresult SetValue(const nsAString *aValue);
|
||||
nsresult GetValueType(nsAString *aValueType);
|
||||
nsresult SetValueType(const nsAString *aValueType);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(94928ab3-8b63-11d3-989d-001083010e9b),
|
||||
|
|
|
@ -65,7 +65,7 @@ static void load_prop_bag(PluginHost *host, IPersistPropertyBag *persist_prop_ba
|
|||
IPropertyBag *prop_bag;
|
||||
HRESULT hres;
|
||||
|
||||
hres = create_param_prop_bag(&prop_bag);
|
||||
hres = create_param_prop_bag(host->element->element.nselem, &prop_bag);
|
||||
if(FAILED(hres))
|
||||
return;
|
||||
|
||||
|
|
|
@ -53,4 +53,4 @@ HRESULT create_plugin_host(HTMLDocumentNode*,nsIDOMElement*,IUnknown*,const CLSI
|
|||
void update_plugin_window(PluginHost*,HWND,const RECT*);
|
||||
void detach_plugin_hosts(HTMLDocumentNode*);
|
||||
|
||||
HRESULT create_param_prop_bag(IPropertyBag**);
|
||||
HRESULT create_param_prop_bag(nsIDOMHTMLElement*,IPropertyBag**);
|
||||
|
|
|
@ -41,8 +41,62 @@ typedef struct {
|
|||
IPropertyBag2 IPropertyBag2_iface;
|
||||
|
||||
LONG ref;
|
||||
|
||||
struct list props;
|
||||
} PropertyBag;
|
||||
|
||||
typedef struct {
|
||||
struct list entry;
|
||||
WCHAR *name;
|
||||
WCHAR *value;
|
||||
} param_prop_t;
|
||||
|
||||
static void free_prop(param_prop_t *prop)
|
||||
{
|
||||
list_remove(&prop->entry);
|
||||
|
||||
heap_free(prop->name);
|
||||
heap_free(prop->value);
|
||||
heap_free(prop);
|
||||
}
|
||||
|
||||
static param_prop_t *find_prop(PropertyBag *prop_bag, const WCHAR *name)
|
||||
{
|
||||
param_prop_t *iter;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(iter, &prop_bag->props, param_prop_t, entry) {
|
||||
if(!strcmpiW(iter->name, name))
|
||||
return iter;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HRESULT add_prop(PropertyBag *prop_bag, const WCHAR *name, const WCHAR *value)
|
||||
{
|
||||
param_prop_t *prop;
|
||||
|
||||
if(!name || !value)
|
||||
return S_OK;
|
||||
|
||||
TRACE("%p %s %s\n", prop_bag, debugstr_w(name), debugstr_w(value));
|
||||
|
||||
prop = heap_alloc(sizeof(*prop));
|
||||
if(!prop)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
prop->name = heap_strdupW(name);
|
||||
prop->value = heap_strdupW(value);
|
||||
if(!prop->name || !prop->value) {
|
||||
list_init(&prop->entry);
|
||||
free_prop(prop);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
list_add_tail(&prop_bag->props, &prop->entry);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static inline PropertyBag *impl_from_IPropertyBag(IPropertyBag *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, PropertyBag, IPropertyBag_iface);
|
||||
|
@ -88,8 +142,11 @@ static ULONG WINAPI PropertyBag_Release(IPropertyBag *iface)
|
|||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref)
|
||||
if(!ref) {
|
||||
while(!list_empty(&This->props))
|
||||
free_prop(LIST_ENTRY(This->props.next, param_prop_t, entry));
|
||||
heap_free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
@ -97,8 +154,32 @@ static ULONG WINAPI PropertyBag_Release(IPropertyBag *iface)
|
|||
static HRESULT WINAPI PropertyBag_Read(IPropertyBag *iface, LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog)
|
||||
{
|
||||
PropertyBag *This = impl_from_IPropertyBag(iface);
|
||||
FIXME("(%p)->(%s %p %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog);
|
||||
return E_NOTIMPL;
|
||||
param_prop_t *prop;
|
||||
VARIANT v;
|
||||
|
||||
TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog);
|
||||
|
||||
prop = find_prop(This, pszPropName);
|
||||
if(!prop) {
|
||||
TRACE("Not found\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
V_BSTR(&v) = SysAllocString(prop->value);
|
||||
if(!V_BSTR(&v))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if(V_VT(pVar) != VT_BSTR) {
|
||||
HRESULT hres;
|
||||
|
||||
V_VT(&v) = VT_BSTR;
|
||||
hres = VariantChangeType(pVar, &v, 0, V_VT(pVar));
|
||||
SysFreeString(V_BSTR(&v));
|
||||
return hres;
|
||||
}
|
||||
|
||||
V_BSTR(pVar) = V_BSTR(&v);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PropertyBag_Write(IPropertyBag *iface, LPCOLESTR pszPropName, VARIANT *pVar)
|
||||
|
@ -188,9 +269,75 @@ static const IPropertyBag2Vtbl PropertyBag2Vtbl = {
|
|||
PropertyBag2_LoadObject
|
||||
};
|
||||
|
||||
HRESULT create_param_prop_bag(IPropertyBag **ret)
|
||||
static HRESULT fill_props(nsIDOMHTMLElement *nselem, PropertyBag *prop_bag)
|
||||
{
|
||||
nsIDOMHTMLParamElement *nsparam;
|
||||
nsAString name_str, value_str;
|
||||
nsIDOMNodeList *params;
|
||||
PRUint32 length, i;
|
||||
nsIDOMNode *nsnode;
|
||||
nsresult nsres;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
static const PRUnichar paramW[] = {'p','a','r','a','m',0};
|
||||
|
||||
nsAString_InitDepend(&name_str, paramW);
|
||||
nsres = nsIDOMHTMLElement_GetElementsByTagName(nselem, &name_str, ¶ms);
|
||||
nsAString_Finish(&name_str);
|
||||
if(NS_FAILED(nsres))
|
||||
return E_FAIL;
|
||||
|
||||
nsres = nsIDOMNodeList_GetLength(params, &length);
|
||||
if(NS_FAILED(nsres))
|
||||
return S_OK;
|
||||
|
||||
for(i=0; i < length; i++) {
|
||||
nsres = nsIDOMNodeList_Item(params, i, &nsnode);
|
||||
if(NS_FAILED(nsres)) {
|
||||
hres = E_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMHTMLParamElement, (void**)&nsparam);
|
||||
nsIDOMNode_Release(nsnode);
|
||||
if(NS_FAILED(nsres)) {
|
||||
hres = E_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
nsAString_Init(&name_str, NULL);
|
||||
nsres = nsIDOMHTMLParamElement_GetName(nsparam, &name_str);
|
||||
if(NS_SUCCEEDED(nsres)) {
|
||||
nsAString_Init(&value_str, NULL);
|
||||
nsres = nsIDOMHTMLParamElement_GetValue(nsparam, &value_str);
|
||||
if(NS_SUCCEEDED(nsres)) {
|
||||
const PRUnichar *name, *value;
|
||||
|
||||
nsAString_GetData(&name_str, &name);
|
||||
nsAString_GetData(&value_str, &value);
|
||||
|
||||
hres = add_prop(prop_bag, name, value);
|
||||
}
|
||||
nsAString_Finish(&value_str);
|
||||
}
|
||||
|
||||
nsAString_Finish(&name_str);
|
||||
nsIDOMHTMLParamElement_Release(nsparam);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
if(NS_FAILED(nsres)) {
|
||||
hres = E_FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
HRESULT create_param_prop_bag(nsIDOMHTMLElement *nselem, IPropertyBag **ret)
|
||||
{
|
||||
PropertyBag *prop_bag;
|
||||
HRESULT hres;
|
||||
|
||||
prop_bag = heap_alloc(sizeof(*prop_bag));
|
||||
if(!prop_bag)
|
||||
|
@ -200,6 +347,14 @@ HRESULT create_param_prop_bag(IPropertyBag **ret)
|
|||
prop_bag->IPropertyBag2_iface.lpVtbl = &PropertyBag2Vtbl;
|
||||
prop_bag->ref = 1;
|
||||
|
||||
list_init(&prop_bag->props);
|
||||
hres = fill_props(nselem, prop_bag);
|
||||
if(FAILED(hres) || list_empty(&prop_bag->props)) {
|
||||
IPropertyBag_Release(&prop_bag->IPropertyBag_iface);
|
||||
*ret = NULL;
|
||||
return hres;
|
||||
}
|
||||
|
||||
*ret = &prop_bag->IPropertyBag_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ static const char object_ax_str[] =
|
|||
"<html><head></head><body>"
|
||||
"<object classid=\"clsid:" TESTACTIVEX_CLSID "\" width=\"300\" height=\"200\" id=\"objid\">"
|
||||
"<param name=\"param_name\" value=\"param_value\">"
|
||||
"<param name=\"num_param\" value=\"3\">"
|
||||
"</object>"
|
||||
"</body></html>";
|
||||
|
||||
|
@ -134,6 +135,13 @@ static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids)
|
|||
}
|
||||
}
|
||||
|
||||
static int strcmp_wa(LPCWSTR strw, const char *stra)
|
||||
{
|
||||
CHAR buf[512];
|
||||
WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
|
||||
return lstrcmpA(stra, buf);
|
||||
}
|
||||
|
||||
static HRESULT ax_qi(REFIID,void**);
|
||||
|
||||
static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
|
||||
|
@ -299,6 +307,13 @@ static HRESULT WINAPI PersistPropertyBag_InitNew(IPersistPropertyBag *face)
|
|||
|
||||
static HRESULT WINAPI PersistPropertyBag_Load(IPersistPropertyBag *face, IPropertyBag *pPropBag, IErrorLog *pErrorLog)
|
||||
{
|
||||
VARIANT v;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR param_nameW[] = {'p','a','r','a','m','_','n','a','m','e',0};
|
||||
static const WCHAR num_paramW[] = {'n','u','m','_','p','a','r','a','m',0};
|
||||
static const WCHAR no_paramW[] = {'n','o','_','p','a','r','a','m',0};
|
||||
|
||||
static const IID *propbag_ifaces[] = {
|
||||
&IID_IPropertyBag,
|
||||
&IID_IPropertyBag2,
|
||||
|
@ -312,6 +327,39 @@ static HRESULT WINAPI PersistPropertyBag_Load(IPersistPropertyBag *face, IProper
|
|||
|
||||
test_ifaces((IUnknown*)pPropBag, propbag_ifaces);
|
||||
|
||||
V_VT(&v) = VT_BSTR;
|
||||
hres = IPropertyBag_Read(pPropBag, param_nameW, &v, NULL);
|
||||
ok(hres == S_OK, "Read failed: %08x\n", hres);
|
||||
ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v));
|
||||
ok(!strcmp_wa(V_BSTR(&v), "param_value"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
|
||||
|
||||
V_VT(&v) = VT_I4;
|
||||
V_I4(&v) = 0xdeadbeef;
|
||||
hres = IPropertyBag_Read(pPropBag, param_nameW, &v, NULL);
|
||||
ok(hres == DISP_E_TYPEMISMATCH, "Read failed: %08x, expected DISP_E_TYPEMISMATCH\n", hres);
|
||||
ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
|
||||
ok(V_I4(&v) == 0xdeadbeef, "V_I4(v) = %x\n", V_I4(&v));
|
||||
|
||||
V_VT(&v) = VT_BSTR;
|
||||
hres = IPropertyBag_Read(pPropBag, num_paramW, &v, NULL);
|
||||
ok(hres == S_OK, "Read failed: %08x\n", hres);
|
||||
ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v));
|
||||
ok(!strcmp_wa(V_BSTR(&v), "3"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
|
||||
|
||||
V_VT(&v) = VT_I4;
|
||||
V_I4(&v) = 0xdeadbeef;
|
||||
hres = IPropertyBag_Read(pPropBag, num_paramW, &v, NULL);
|
||||
ok(hres == S_OK, "Read failed: %08x\n", hres);
|
||||
ok(V_VT(&v) == VT_I4, "V_VT(&v) = %d\n", V_VT(&v));
|
||||
ok(V_I4(&v) == 3, "V_I4(v) = %x\n", V_I4(&v));
|
||||
|
||||
V_VT(&v) = VT_BSTR;
|
||||
V_BSTR(&v) = (BSTR)0xdeadbeef;
|
||||
hres = IPropertyBag_Read(pPropBag, no_paramW, &v, NULL);
|
||||
ok(hres == E_INVALIDARG, "Read failed: %08x\n", hres);
|
||||
ok(V_VT(&v) == VT_BSTR, "V_VT(&v) = %d\n", V_VT(&v));
|
||||
ok(V_BSTR(&v) == (BSTR)0xdeadbeef, "V_BSTR(v) = %p\n", V_BSTR(&v));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue