diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c
index a29cd76ba65..56ec3cf1eb1 100644
--- a/dlls/mshtml/htmlimg.c
+++ b/dlls/mshtml/htmlimg.c
@@ -611,3 +611,126 @@ HTMLElement *HTMLImgElement_Create(nsIDOMHTMLElement *nselem)
return &ret->element;
}
+
+#define HTMLIMGFACTORY_THIS(iface) DEFINE_THIS(HTMLImageElementFactory, HTMLImageElementFactory, iface)
+
+static HRESULT WINAPI HTMLImageElementFactory_QueryInterface(IHTMLImageElementFactory *iface,
+ REFIID riid, void **ppv)
+{
+ HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface);
+
+ *ppv = NULL;
+
+ if(IsEqualGUID(&IID_IUnknown, riid)) {
+ TRACE("(%p)->(IID_Unknown %p)\n", This, ppv);
+ *ppv = HTMLIMGFACTORY(This);
+ }else if(IsEqualGUID(&IID_IDispatch, riid)) {
+ TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
+ *ppv = HTMLIMGFACTORY(This);
+ }else if(IsEqualGUID(&IID_IHTMLImageElementFactory, riid)) {
+ TRACE("(%p)->(IID_IHTMLImageElementFactory %p)\n", This, ppv);
+ *ppv = HTMLIMGFACTORY(This);
+ }
+
+ if(*ppv) {
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+ }
+
+ WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI HTMLImageElementFactory_AddRef(IHTMLImageElementFactory *iface)
+{
+ HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface);
+ LONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI HTMLImageElementFactory_Release(IHTMLImageElementFactory *iface)
+{
+ HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface);
+ LONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ if(!ref)
+ heap_free(This);
+
+ return ref;
+}
+
+static HRESULT WINAPI HTMLImageElementFactory_GetTypeInfoCount(IHTMLImageElementFactory *iface,
+ UINT *pctinfo)
+{
+ HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface);
+ FIXME("(%p)->(%p)\n", This, pctinfo);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLImageElementFactory_GetTypeInfo(IHTMLImageElementFactory *iface,
+ UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
+{
+ HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface);
+ FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLImageElementFactory_GetIDsOfNames(IHTMLImageElementFactory *iface,
+ REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
+ DISPID *rgDispId)
+{
+ HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface);
+ FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames,
+ cNames, lcid, rgDispId);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLImageElementFactory_Invoke(IHTMLImageElementFactory *iface,
+ DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
+ DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
+ UINT *puArgErr)
+{
+ HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface);
+ FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
+ lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLImageElementFactory_create(IHTMLImageElementFactory *iface,
+ VARIANT width, VARIANT height, IHTMLImgElement **elem)
+{
+ HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface);
+ FIXME("(%p)->(%s %s %p)\n", This, debugstr_variant(&width), debugstr_variant(&height), elem);
+ return E_NOTIMPL;
+}
+
+#undef HTMLIMGFACTORY_THIS
+
+static const IHTMLImageElementFactoryVtbl HTMLImageElementFactoryVtbl = {
+ HTMLImageElementFactory_QueryInterface,
+ HTMLImageElementFactory_AddRef,
+ HTMLImageElementFactory_Release,
+ HTMLImageElementFactory_GetTypeInfoCount,
+ HTMLImageElementFactory_GetTypeInfo,
+ HTMLImageElementFactory_GetIDsOfNames,
+ HTMLImageElementFactory_Invoke,
+ HTMLImageElementFactory_create
+};
+
+HTMLImageElementFactory *HTMLImageElementFactory_Create(HTMLWindow *window)
+{
+ HTMLImageElementFactory *ret;
+
+ ret = heap_alloc(sizeof(HTMLImageElementFactory));
+
+ ret->lpHTMLImageElementFactoryVtbl = &HTMLImageElementFactoryVtbl;
+ ret->ref = 1;
+ ret->window = window;
+
+ return ret;
+}
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c
index 40df40c9979..fe7444af50d 100644
--- a/dlls/mshtml/htmlwindow.c
+++ b/dlls/mshtml/htmlwindow.c
@@ -113,6 +113,11 @@ static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
IHTMLOptionElementFactory_Release(HTMLOPTFACTORY(This->option_factory));
}
+ if(This->image_factory) {
+ This->image_factory->window = NULL;
+ IHTMLImageElementFactory_Release(HTMLIMGFACTORY(This->image_factory));
+ }
+
if(This->location) {
This->location->window = NULL;
IHTMLLocation_Release(HTMLLOCATION(This->location));
@@ -392,8 +397,16 @@ static HRESULT WINAPI HTMLWindow2_prompt(IHTMLWindow2 *iface, BSTR message,
static HRESULT WINAPI HTMLWindow2_get_Image(IHTMLWindow2 *iface, IHTMLImageElementFactory **p)
{
HTMLWindow *This = HTMLWINDOW2_THIS(iface);
- FIXME("(%p)->(%p)\n", This, p);
- return E_NOTIMPL;
+
+ TRACE("(%p)->(%p)\n", This, p);
+
+ if(!This->image_factory)
+ This->image_factory = HTMLImageElementFactory_Create(This);
+
+ *p = HTMLIMGFACTORY(This->image_factory);
+ IHTMLImageElementFactory_AddRef(*p);
+
+ return S_OK;
}
static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocation **p)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 6fa6ec4b9ef..5111eb7475f 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -181,6 +181,14 @@ typedef struct {
HTMLWindow *window;
} HTMLOptionElementFactory;
+typedef struct {
+ const IHTMLImageElementFactoryVtbl *lpHTMLImageElementFactoryVtbl;
+
+ LONG ref;
+
+ HTMLWindow *window;
+} HTMLImageElementFactory;
+
struct HTMLLocation {
DispatchEx dispex;
const IHTMLLocationVtbl *lpHTMLLocationVtbl;
@@ -210,6 +218,7 @@ struct HTMLWindow {
struct list script_hosts;
HTMLOptionElementFactory *option_factory;
+ HTMLImageElementFactory *image_factory;
HTMLLocation *location;
global_prop_t *global_props;
@@ -545,6 +554,7 @@ struct HTMLDocumentNode {
#define HTMLTEXTCONT(x) ((IHTMLTextContainer*) &(x)->lpHTMLTextContainerVtbl)
#define HTMLOPTFACTORY(x) ((IHTMLOptionElementFactory*) &(x)->lpHTMLOptionElementFactoryVtbl)
+#define HTMLIMGFACTORY(x) ((IHTMLImageElementFactory*) &(x)->lpHTMLImageElementFactoryVtbl)
#define HTMLLOCATION(x) ((IHTMLLocation*) &(x)->lpHTMLLocationVtbl)
#define DISPATCHEX(x) ((IDispatchEx*) &(x)->lpIDispatchExVtbl)
@@ -564,6 +574,7 @@ HRESULT HTMLWindow_Create(HTMLDocumentObj*,nsIDOMWindow*,HTMLWindow**);
void window_set_docnode(HTMLWindow*,HTMLDocumentNode*);
HTMLWindow *nswindow_to_window(const nsIDOMWindow*);
HTMLOptionElementFactory *HTMLOptionElementFactory_Create(HTMLWindow*);
+HTMLImageElementFactory *HTMLImageElementFactory_Create(HTMLWindow*);
HRESULT HTMLLocation_Create(HTMLWindow*,HTMLLocation**);
IOmNavigator *OmNavigator_Create(void);
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index d319c0364fa..18f70eca357 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -1056,6 +1056,102 @@ static IHTMLOptionElement *_create_option_elem(unsigned line, IHTMLDocument2 *do
return option;
}
+#define test_img_width(o,w) _test_img_width(__LINE__,o,w)
+static void _test_img_width(unsigned line, IHTMLImgElement *img, const long exp)
+{
+ LONG found = -1;
+ HRESULT hres;
+
+ hres = IHTMLImgElement_get_width(img, &found);
+ todo_wine ok_(__FILE__,line) (hres == S_OK, "get_width failed: %08x\n", hres);
+ todo_wine ok_(__FILE__,line) (found == exp, "width=%d\n", found);
+}
+
+#define test_img_put_width(o,w) _test_img_put_width(__LINE__,o,w)
+static void _test_img_put_width(unsigned line, IHTMLImgElement *img, const long width)
+{
+ HRESULT hres;
+
+ hres = IHTMLImgElement_put_width(img, width);
+ todo_wine ok(hres == S_OK, "put_width failed: %08x\n", hres);
+
+ _test_img_width(line, img, width);
+}
+
+#define test_img_height(o,h) _test_img_height(__LINE__,o,h)
+static void _test_img_height(unsigned line, IHTMLImgElement *img, const long exp)
+{
+ LONG found = -1;
+ HRESULT hres;
+
+ hres = IHTMLImgElement_get_height(img, &found);
+ todo_wine ok_(__FILE__,line) (hres == S_OK, "get_height failed: %08x\n", hres);
+ todo_wine ok_(__FILE__,line) (found == exp, "height=%d\n", found);
+}
+
+#define test_img_put_height(o,w) _test_img_put_height(__LINE__,o,w)
+static void _test_img_put_height(unsigned line, IHTMLImgElement *img, const long height)
+{
+ HRESULT hres;
+
+ hres = IHTMLImgElement_put_height(img, height);
+ todo_wine ok(hres == S_OK, "put_height failed: %08x\n", hres);
+
+ _test_img_height(line, img, height);
+}
+
+#define create_img_elem(d,t,v) _create_img_elem(__LINE__,d,t,v)
+static IHTMLImgElement *_create_img_elem(unsigned line, IHTMLDocument2 *doc,
+ LONG wdth, LONG hght)
+{
+ IHTMLImageElementFactory *factory;
+ IHTMLImgElement *img;
+ IHTMLWindow2 *window;
+ VARIANT width, height;
+ char buf[16];
+ HRESULT hres;
+
+ hres = IHTMLDocument2_get_parentWindow(doc, &window);
+ ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
+
+ hres = IHTMLWindow2_get_Image(window, &factory);
+ IHTMLWindow2_Release(window);
+ ok_(__FILE__,line) (hres == S_OK, "get_Image failed: %08x\n", hres);
+
+ if(wdth >= 0){
+ snprintf(buf, 16, "%d", wdth);
+ V_VT(&width) = VT_BSTR;
+ V_BSTR(&width) = a2bstr(buf);
+ }else{
+ V_VT(&width) = VT_EMPTY;
+ wdth = 0;
+ }
+
+ if(hght >= 0){
+ snprintf(buf, 16, "%d", hght);
+ V_VT(&height) = VT_BSTR;
+ V_BSTR(&height) = a2bstr(buf);
+ }else{
+ V_VT(&height) = VT_EMPTY;
+ hght = 0;
+ }
+
+ hres = IHTMLImageElementFactory_create(factory, width, height, &img);
+ todo_wine ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
+
+ IHTMLImageElementFactory_Release(factory);
+ VariantClear(&width);
+ VariantClear(&height);
+
+ if(SUCCEEDED(hres)) {
+ _test_img_width(line, img, wdth);
+ _test_img_height(line, img, hght);
+ return img;
+ }
+
+ return NULL;
+}
+
#define test_select_length(s,l) _test_select_length(__LINE__,s,l)
static void _test_select_length(unsigned line, IHTMLSelectElement *select, LONG length)
{
@@ -2432,6 +2528,30 @@ static void test_create_option_elem(IHTMLDocument2 *doc)
IHTMLOptionElement_Release(option);
}
+static void test_create_img_elem(IHTMLDocument2 *doc)
+{
+ IHTMLImgElement *img;
+
+ img = create_img_elem(doc, 10, 15);
+
+ if(img){
+ test_img_put_width(img, 5);
+ test_img_put_height(img, 20);
+
+ IHTMLImgElement_Release(img);
+ img = NULL;
+ }
+
+ img = create_img_elem(doc, -1, -1);
+
+ if(img){
+ test_img_put_width(img, 5);
+ test_img_put_height(img, 20);
+
+ IHTMLImgElement_Release(img);
+ }
+}
+
static IHTMLTxtRange *test_create_body_range(IHTMLDocument2 *doc)
{
IHTMLBodyElement *body;
@@ -5158,6 +5278,7 @@ static void test_elems(IHTMLDocument2 *doc)
test_stylesheets(doc);
test_create_option_elem(doc);
+ test_create_img_elem(doc);
elem = get_doc_elem_by_id(doc, "tbl");
ok(elem != NULL, "elem = NULL\n");