Reactos
at master 729 lines 22 kB view raw
1/* 2 * Copyright 2006 Jacek Caban for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19#include "mshtml_private.h" 20 21typedef struct { 22 HTMLElement element; 23 24 IHTMLSelectElement IHTMLSelectElement_iface; 25 26 nsIDOMHTMLSelectElement *nsselect; 27} HTMLSelectElement; 28 29static inline HTMLSelectElement *impl_from_IHTMLSelectElement(IHTMLSelectElement *iface) 30{ 31 return CONTAINING_RECORD(iface, HTMLSelectElement, IHTMLSelectElement_iface); 32} 33 34static HRESULT htmlselect_item(HTMLSelectElement *This, int i, IDispatch **ret) 35{ 36 nsIDOMHTMLOptionsCollection *nscol; 37 nsIDOMNode *nsnode; 38 nsresult nsres; 39 HRESULT hres; 40 41 nsres = nsIDOMHTMLSelectElement_GetOptions(This->nsselect, &nscol); 42 if(NS_FAILED(nsres)) { 43 ERR("GetOptions failed: %08x\n", nsres); 44 return E_FAIL; 45 } 46 47 nsres = nsIDOMHTMLOptionsCollection_Item(nscol, i, &nsnode); 48 nsIDOMHTMLOptionsCollection_Release(nscol); 49 if(NS_FAILED(nsres)) { 50 ERR("Item failed: %08x\n", nsres); 51 return E_FAIL; 52 } 53 54 if(nsnode) { 55 HTMLDOMNode *node; 56 57 hres = get_node(This->element.node.doc, nsnode, TRUE, &node); 58 nsIDOMNode_Release(nsnode); 59 if(FAILED(hres)) 60 return hres; 61 62 *ret = (IDispatch*)&node->IHTMLDOMNode_iface; 63 }else { 64 *ret = NULL; 65 } 66 return S_OK; 67} 68 69static HRESULT WINAPI HTMLSelectElement_QueryInterface(IHTMLSelectElement *iface, 70 REFIID riid, void **ppv) 71{ 72 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 73 74 return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv); 75} 76 77static ULONG WINAPI HTMLSelectElement_AddRef(IHTMLSelectElement *iface) 78{ 79 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 80 81 return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface); 82} 83 84static ULONG WINAPI HTMLSelectElement_Release(IHTMLSelectElement *iface) 85{ 86 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 87 88 return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface); 89} 90 91static HRESULT WINAPI HTMLSelectElement_GetTypeInfoCount(IHTMLSelectElement *iface, UINT *pctinfo) 92{ 93 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 94 95 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo); 96} 97 98static HRESULT WINAPI HTMLSelectElement_GetTypeInfo(IHTMLSelectElement *iface, UINT iTInfo, 99 LCID lcid, ITypeInfo **ppTInfo) 100{ 101 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 102 103 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid, 104 ppTInfo); 105} 106 107static HRESULT WINAPI HTMLSelectElement_GetIDsOfNames(IHTMLSelectElement *iface, REFIID riid, 108 LPOLESTR *rgszNames, UINT cNames, 109 LCID lcid, DISPID *rgDispId) 110{ 111 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 112 113 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames, 114 cNames, lcid, rgDispId); 115} 116 117static HRESULT WINAPI HTMLSelectElement_Invoke(IHTMLSelectElement *iface, DISPID dispIdMember, 118 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 119 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 120{ 121 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 122 123 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid, 124 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 125} 126 127static HRESULT WINAPI HTMLSelectElement_put_size(IHTMLSelectElement *iface, LONG v) 128{ 129 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 130 nsresult nsres; 131 132 TRACE("(%p)->(%d)\n", This, v); 133 if(v < 0) 134 return CTL_E_INVALIDPROPERTYVALUE; 135 136 nsres = nsIDOMHTMLSelectElement_SetSize(This->nsselect, v); 137 if(NS_FAILED(nsres)) { 138 ERR("SetSize failed: %08x\n", nsres); 139 return E_FAIL; 140 } 141 return S_OK; 142} 143 144static HRESULT WINAPI HTMLSelectElement_get_size(IHTMLSelectElement *iface, LONG *p) 145{ 146 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 147 DWORD val; 148 nsresult nsres; 149 150 TRACE("(%p)->(%p)\n", This, p); 151 if(!p) 152 return E_INVALIDARG; 153 154 nsres = nsIDOMHTMLSelectElement_GetSize(This->nsselect, &val); 155 if(NS_FAILED(nsres)) { 156 ERR("GetSize failed: %08x\n", nsres); 157 return E_FAIL; 158 } 159 *p = val; 160 return S_OK; 161} 162 163static HRESULT WINAPI HTMLSelectElement_put_multiple(IHTMLSelectElement *iface, VARIANT_BOOL v) 164{ 165 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 166 nsresult nsres; 167 168 TRACE("(%p)->(%x)\n", This, v); 169 170 nsres = nsIDOMHTMLSelectElement_SetMultiple(This->nsselect, !!v); 171 assert(nsres == NS_OK); 172 return S_OK; 173} 174 175static HRESULT WINAPI HTMLSelectElement_get_multiple(IHTMLSelectElement *iface, VARIANT_BOOL *p) 176{ 177 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 178 cpp_bool val; 179 nsresult nsres; 180 181 TRACE("(%p)->(%p)\n", This, p); 182 183 nsres = nsIDOMHTMLSelectElement_GetMultiple(This->nsselect, &val); 184 assert(nsres == NS_OK); 185 186 *p = val ? VARIANT_TRUE : VARIANT_FALSE; 187 return S_OK; 188} 189 190static HRESULT WINAPI HTMLSelectElement_put_name(IHTMLSelectElement *iface, BSTR v) 191{ 192 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 193 nsAString str; 194 nsresult nsres; 195 196 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 197 nsAString_InitDepend(&str, v); 198 nsres = nsIDOMHTMLSelectElement_SetName(This->nsselect, &str); 199 nsAString_Finish(&str); 200 201 if(NS_FAILED(nsres)) { 202 ERR("SetName failed: %08x\n", nsres); 203 return E_FAIL; 204 } 205 return S_OK; 206} 207 208static HRESULT WINAPI HTMLSelectElement_get_name(IHTMLSelectElement *iface, BSTR *p) 209{ 210 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 211 nsAString name_str; 212 nsresult nsres; 213 214 TRACE("(%p)->(%p)\n", This, p); 215 216 nsAString_Init(&name_str, NULL); 217 nsres = nsIDOMHTMLSelectElement_GetName(This->nsselect, &name_str); 218 219 return return_nsstr(nsres, &name_str, p); 220} 221 222static HRESULT WINAPI HTMLSelectElement_get_options(IHTMLSelectElement *iface, IDispatch **p) 223{ 224 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 225 226 TRACE("(%p)->(%p)\n", This, p); 227 228 *p = (IDispatch*)&This->IHTMLSelectElement_iface; 229 IDispatch_AddRef(*p); 230 return S_OK; 231} 232 233static HRESULT WINAPI HTMLSelectElement_put_onchange(IHTMLSelectElement *iface, VARIANT v) 234{ 235 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 236 237 TRACE("(%p)->()\n", This); 238 239 return set_node_event(&This->element.node, EVENTID_CHANGE, &v); 240} 241 242static HRESULT WINAPI HTMLSelectElement_get_onchange(IHTMLSelectElement *iface, VARIANT *p) 243{ 244 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 245 FIXME("(%p)->(%p)\n", This, p); 246 return E_NOTIMPL; 247} 248 249static HRESULT WINAPI HTMLSelectElement_put_selectedIndex(IHTMLSelectElement *iface, LONG v) 250{ 251 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 252 nsresult nsres; 253 254 TRACE("(%p)->(%d)\n", This, v); 255 256 nsres = nsIDOMHTMLSelectElement_SetSelectedIndex(This->nsselect, v); 257 if(NS_FAILED(nsres)) 258 ERR("SetSelectedIndex failed: %08x\n", nsres); 259 260 return S_OK; 261} 262 263static HRESULT WINAPI HTMLSelectElement_get_selectedIndex(IHTMLSelectElement *iface, LONG *p) 264{ 265 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 266 nsresult nsres; 267 268 TRACE("(%p)->(%p)\n", This, p); 269 270 nsres = nsIDOMHTMLSelectElement_GetSelectedIndex(This->nsselect, p); 271 if(NS_FAILED(nsres)) { 272 ERR("GetSelectedIndex failed: %08x\n", nsres); 273 return E_FAIL; 274 } 275 276 return S_OK; 277} 278 279static HRESULT WINAPI HTMLSelectElement_get_type(IHTMLSelectElement *iface, BSTR *p) 280{ 281 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 282 nsAString type_str; 283 nsresult nsres; 284 285 TRACE("(%p)->(%p)\n", This, p); 286 287 nsAString_Init(&type_str, NULL); 288 nsres = nsIDOMHTMLSelectElement_GetType(This->nsselect, &type_str); 289 return return_nsstr(nsres, &type_str, p); 290} 291 292static HRESULT WINAPI HTMLSelectElement_put_value(IHTMLSelectElement *iface, BSTR v) 293{ 294 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 295 nsAString value_str; 296 nsresult nsres; 297 298 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 299 300 nsAString_InitDepend(&value_str, v); 301 nsres = nsIDOMHTMLSelectElement_SetValue(This->nsselect, &value_str); 302 nsAString_Finish(&value_str); 303 if(NS_FAILED(nsres)) 304 ERR("SetValue failed: %08x\n", nsres); 305 306 return S_OK; 307} 308 309static HRESULT WINAPI HTMLSelectElement_get_value(IHTMLSelectElement *iface, BSTR *p) 310{ 311 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 312 nsAString value_str; 313 nsresult nsres; 314 315 TRACE("(%p)->(%p)\n", This, p); 316 317 nsAString_Init(&value_str, NULL); 318 nsres = nsIDOMHTMLSelectElement_GetValue(This->nsselect, &value_str); 319 return return_nsstr(nsres, &value_str, p); 320} 321 322static HRESULT WINAPI HTMLSelectElement_put_disabled(IHTMLSelectElement *iface, VARIANT_BOOL v) 323{ 324 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 325 nsresult nsres; 326 327 TRACE("(%p)->(%x)\n", This, v); 328 329 nsres = nsIDOMHTMLSelectElement_SetDisabled(This->nsselect, v != VARIANT_FALSE); 330 if(NS_FAILED(nsres)) { 331 ERR("SetDisabled failed: %08x\n", nsres); 332 return E_FAIL; 333 } 334 335 return S_OK; 336} 337 338static HRESULT WINAPI HTMLSelectElement_get_disabled(IHTMLSelectElement *iface, VARIANT_BOOL *p) 339{ 340 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 341 cpp_bool disabled = FALSE; 342 nsresult nsres; 343 344 TRACE("(%p)->(%p)\n", This, p); 345 346 nsres = nsIDOMHTMLSelectElement_GetDisabled(This->nsselect, &disabled); 347 if(NS_FAILED(nsres)) { 348 ERR("GetDisabled failed: %08x\n", nsres); 349 return E_FAIL; 350 } 351 352 *p = disabled ? VARIANT_TRUE : VARIANT_FALSE; 353 return S_OK; 354} 355 356static HRESULT WINAPI HTMLSelectElement_get_form(IHTMLSelectElement *iface, IHTMLFormElement **p) 357{ 358 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 359 nsIDOMHTMLFormElement *nsform; 360 nsIDOMNode *form_node; 361 HTMLDOMNode *node; 362 HRESULT hres; 363 nsresult nsres; 364 365 TRACE("(%p)->(%p)\n", This, p); 366 367 if(!p) 368 return E_POINTER; 369 370 nsres = nsIDOMHTMLSelectElement_GetForm(This->nsselect, &nsform); 371 if (NS_FAILED(nsres)) { 372 ERR("GetForm failed: %08x, nsform: %p\n", nsres, nsform); 373 *p = NULL; 374 return E_FAIL; 375 } 376 if (nsform == NULL) { 377 TRACE("nsform not found\n"); 378 *p = NULL; 379 return S_OK; 380 } 381 382 nsres = nsIDOMHTMLFormElement_QueryInterface(nsform, &IID_nsIDOMNode, (void**)&form_node); 383 nsIDOMHTMLFormElement_Release(nsform); 384 assert(nsres == NS_OK); 385 386 hres = get_node(This->element.node.doc, form_node, TRUE, &node); 387 nsIDOMNode_Release(form_node); 388 if (FAILED(hres)) 389 return hres; 390 391 hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)p); 392 393 node_release(node); 394 return hres; 395} 396 397static HRESULT WINAPI HTMLSelectElement_add(IHTMLSelectElement *iface, IHTMLElement *element, 398 VARIANT before) 399{ 400 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 401 nsIWritableVariant *nsvariant; 402 HTMLElement *element_obj; 403 nsresult nsres; 404 405 TRACE("(%p)->(%p %s)\n", This, element, debugstr_variant(&before)); 406 407 element_obj = unsafe_impl_from_IHTMLElement(element); 408 if(!element_obj) { 409 FIXME("External IHTMLElement implementation?\n"); 410 return E_INVALIDARG; 411 } 412 413 nsvariant = create_nsvariant(); 414 if(!nsvariant) 415 return E_FAIL; 416 417 switch(V_VT(&before)) { 418 case VT_EMPTY: 419 case VT_ERROR: 420 nsres = nsIWritableVariant_SetAsEmpty(nsvariant); 421 break; 422 case VT_I2: 423 nsres = nsIWritableVariant_SetAsInt16(nsvariant, V_I2(&before)); 424 break; 425 default: 426 FIXME("unhandled before %s\n", debugstr_variant(&before)); 427 nsIWritableVariant_Release(nsvariant); 428 return E_NOTIMPL; 429 } 430 431 if(NS_SUCCEEDED(nsres)) 432 nsres = nsIDOMHTMLSelectElement_Add(This->nsselect, element_obj->nselem, (nsIVariant*)nsvariant); 433 nsIWritableVariant_Release(nsvariant); 434 if(NS_FAILED(nsres)) { 435 ERR("Add failed: %08x\n", nsres); 436 return E_FAIL; 437 } 438 439 return S_OK; 440} 441 442static HRESULT WINAPI HTMLSelectElement_remove(IHTMLSelectElement *iface, LONG index) 443{ 444 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 445 nsresult nsres; 446 TRACE("(%p)->(%d)\n", This, index); 447 if(index < 0) 448 return E_INVALIDARG; 449 450 nsres = nsIDOMHTMLSelectElement_select_Remove(This->nsselect, index); 451 if(NS_FAILED(nsres)) { 452 ERR("Remove failed: %08x\n", nsres); 453 return E_FAIL; 454 } 455 return S_OK; 456} 457 458static HRESULT WINAPI HTMLSelectElement_put_length(IHTMLSelectElement *iface, LONG v) 459{ 460 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 461 nsresult nsres; 462 463 TRACE("(%p)->(%d)\n", This, v); 464 465 nsres = nsIDOMHTMLSelectElement_SetLength(This->nsselect, v); 466 if(NS_FAILED(nsres)) 467 ERR("SetLength failed: %08x\n", nsres); 468 469 return S_OK; 470} 471 472static HRESULT WINAPI HTMLSelectElement_get_length(IHTMLSelectElement *iface, LONG *p) 473{ 474 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 475 UINT32 length = 0; 476 nsresult nsres; 477 478 TRACE("(%p)->(%p)\n", This, p); 479 480 nsres = nsIDOMHTMLSelectElement_GetLength(This->nsselect, &length); 481 if(NS_FAILED(nsres)) 482 ERR("GetLength failed: %08x\n", nsres); 483 484 *p = length; 485 486 TRACE("ret %d\n", *p); 487 return S_OK; 488} 489 490static HRESULT WINAPI HTMLSelectElement_get__newEnum(IHTMLSelectElement *iface, IUnknown **p) 491{ 492 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 493 FIXME("(%p)->(%p)\n", This, p); 494 return E_NOTIMPL; 495} 496 497static HRESULT WINAPI HTMLSelectElement_item(IHTMLSelectElement *iface, VARIANT name, 498 VARIANT index, IDispatch **pdisp) 499{ 500 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 501 502 TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&name), debugstr_variant(&index), pdisp); 503 504 if(!pdisp) 505 return E_POINTER; 506 *pdisp = NULL; 507 508 if(V_VT(&name) == VT_I4) { 509 if(V_I4(&name) < 0) 510 return E_INVALIDARG; 511 return htmlselect_item(This, V_I4(&name), pdisp); 512 } 513 514 FIXME("Unsupported args\n"); 515 return E_NOTIMPL; 516} 517 518static HRESULT WINAPI HTMLSelectElement_tags(IHTMLSelectElement *iface, VARIANT tagName, 519 IDispatch **pdisp) 520{ 521 HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); 522 FIXME("(%p)->(v %p)\n", This, pdisp); 523 return E_NOTIMPL; 524} 525 526static const IHTMLSelectElementVtbl HTMLSelectElementVtbl = { 527 HTMLSelectElement_QueryInterface, 528 HTMLSelectElement_AddRef, 529 HTMLSelectElement_Release, 530 HTMLSelectElement_GetTypeInfoCount, 531 HTMLSelectElement_GetTypeInfo, 532 HTMLSelectElement_GetIDsOfNames, 533 HTMLSelectElement_Invoke, 534 HTMLSelectElement_put_size, 535 HTMLSelectElement_get_size, 536 HTMLSelectElement_put_multiple, 537 HTMLSelectElement_get_multiple, 538 HTMLSelectElement_put_name, 539 HTMLSelectElement_get_name, 540 HTMLSelectElement_get_options, 541 HTMLSelectElement_put_onchange, 542 HTMLSelectElement_get_onchange, 543 HTMLSelectElement_put_selectedIndex, 544 HTMLSelectElement_get_selectedIndex, 545 HTMLSelectElement_get_type, 546 HTMLSelectElement_put_value, 547 HTMLSelectElement_get_value, 548 HTMLSelectElement_put_disabled, 549 HTMLSelectElement_get_disabled, 550 HTMLSelectElement_get_form, 551 HTMLSelectElement_add, 552 HTMLSelectElement_remove, 553 HTMLSelectElement_put_length, 554 HTMLSelectElement_get_length, 555 HTMLSelectElement_get__newEnum, 556 HTMLSelectElement_item, 557 HTMLSelectElement_tags 558}; 559 560static inline HTMLSelectElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface) 561{ 562 return CONTAINING_RECORD(iface, HTMLSelectElement, element.node); 563} 564 565static HRESULT HTMLSelectElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) 566{ 567 HTMLSelectElement *This = impl_from_HTMLDOMNode(iface); 568 569 *ppv = NULL; 570 571 if(IsEqualGUID(&IID_IUnknown, riid)) { 572 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); 573 *ppv = &This->IHTMLSelectElement_iface; 574 }else if(IsEqualGUID(&IID_IDispatch, riid)) { 575 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv); 576 *ppv = &This->IHTMLSelectElement_iface; 577 }else if(IsEqualGUID(&IID_IHTMLSelectElement, riid)) { 578 TRACE("(%p)->(IID_IHTMLSelectElement %p)\n", This, ppv); 579 *ppv = &This->IHTMLSelectElement_iface; 580 } 581 582 if(*ppv) { 583 IUnknown_AddRef((IUnknown*)*ppv); 584 return S_OK; 585 } 586 587 return HTMLElement_QI(&This->element.node, riid, ppv); 588} 589 590static HRESULT HTMLSelectElementImpl_put_disabled(HTMLDOMNode *iface, VARIANT_BOOL v) 591{ 592 HTMLSelectElement *This = impl_from_HTMLDOMNode(iface); 593 return IHTMLSelectElement_put_disabled(&This->IHTMLSelectElement_iface, v); 594} 595 596static HRESULT HTMLSelectElementImpl_get_disabled(HTMLDOMNode *iface, VARIANT_BOOL *p) 597{ 598 HTMLSelectElement *This = impl_from_HTMLDOMNode(iface); 599 return IHTMLSelectElement_get_disabled(&This->IHTMLSelectElement_iface, p); 600} 601 602#define DISPID_OPTIONCOL_0 MSHTML_DISPID_CUSTOM_MIN 603 604static HRESULT HTMLSelectElement_get_dispid(HTMLDOMNode *iface, BSTR name, DWORD flags, DISPID *dispid) 605{ 606 const WCHAR *ptr; 607 DWORD idx = 0; 608 609 for(ptr = name; *ptr && isdigitW(*ptr); ptr++) { 610 idx = idx*10 + (*ptr-'0'); 611 if(idx > MSHTML_CUSTOM_DISPID_CNT) { 612 WARN("too big idx\n"); 613 return DISP_E_UNKNOWNNAME; 614 } 615 } 616 if(*ptr) 617 return DISP_E_UNKNOWNNAME; 618 619 *dispid = DISPID_OPTIONCOL_0 + idx; 620 return S_OK; 621} 622 623static HRESULT HTMLSelectElement_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, 624 VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) 625{ 626 HTMLSelectElement *This = impl_from_HTMLDOMNode(iface); 627 628 TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller); 629 630 switch(flags) { 631 case DISPATCH_PROPERTYGET: { 632 IDispatch *ret; 633 HRESULT hres; 634 635 hres = htmlselect_item(This, id-DISPID_OPTIONCOL_0, &ret); 636 if(FAILED(hres)) 637 return hres; 638 639 if(ret) { 640 V_VT(res) = VT_DISPATCH; 641 V_DISPATCH(res) = ret; 642 }else { 643 V_VT(res) = VT_NULL; 644 } 645 break; 646 } 647 648 default: 649 FIXME("unimplemented flags %x\n", flags); 650 return E_NOTIMPL; 651 } 652 653 return S_OK; 654} 655 656static void HTMLSelectElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb) 657{ 658 HTMLSelectElement *This = impl_from_HTMLDOMNode(iface); 659 660 if(This->nsselect) 661 note_cc_edge((nsISupports*)This->nsselect, "This->nsselect", cb); 662} 663 664static void HTMLSelectElement_unlink(HTMLDOMNode *iface) 665{ 666 HTMLSelectElement *This = impl_from_HTMLDOMNode(iface); 667 668 if(This->nsselect) { 669 nsIDOMHTMLSelectElement *nsselect = This->nsselect; 670 671 This->nsselect = NULL; 672 nsIDOMHTMLSelectElement_Release(nsselect); 673 } 674} 675 676static const NodeImplVtbl HTMLSelectElementImplVtbl = { 677 HTMLSelectElement_QI, 678 HTMLElement_destructor, 679 HTMLElement_cpc, 680 HTMLElement_clone, 681 HTMLElement_handle_event, 682 HTMLElement_get_attr_col, 683 NULL, 684 NULL, 685 HTMLSelectElementImpl_put_disabled, 686 HTMLSelectElementImpl_get_disabled, 687 NULL, 688 NULL, 689 HTMLSelectElement_get_dispid, 690 HTMLSelectElement_invoke, 691 NULL, 692 HTMLSelectElement_traverse, 693 HTMLSelectElement_unlink 694}; 695 696static const tid_t HTMLSelectElement_tids[] = { 697 HTMLELEMENT_TIDS, 698 IHTMLSelectElement_tid, 699 0 700}; 701 702static dispex_static_data_t HTMLSelectElement_dispex = { 703 NULL, 704 DispHTMLSelectElement_tid, 705 NULL, 706 HTMLSelectElement_tids 707}; 708 709HRESULT HTMLSelectElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem) 710{ 711 HTMLSelectElement *ret; 712 nsresult nsres; 713 714 ret = heap_alloc_zero(sizeof(HTMLSelectElement)); 715 if(!ret) 716 return E_OUTOFMEMORY; 717 718 ret->IHTMLSelectElement_iface.lpVtbl = &HTMLSelectElementVtbl; 719 ret->element.node.vtbl = &HTMLSelectElementImplVtbl; 720 721 HTMLElement_Init(&ret->element, doc, nselem, &HTMLSelectElement_dispex); 722 723 nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLSelectElement, 724 (void**)&ret->nsselect); 725 assert(nsres == NS_OK); 726 727 *elem = &ret->element; 728 return S_OK; 729}