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 21 typedef struct { 22 HTMLElement element; 23 24 IHTMLSelectElement IHTMLSelectElement_iface; 25 26 nsIDOMHTMLSelectElement *nsselect; 27 } HTMLSelectElement; 28 29 static inline HTMLSelectElement *impl_from_IHTMLSelectElement(IHTMLSelectElement *iface) 30 { 31 return CONTAINING_RECORD(iface, HTMLSelectElement, IHTMLSelectElement_iface); 32 } 33 34 static 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 69 static 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 77 static 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 84 static 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 91 static 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 98 static 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 107 static 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 117 static 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 127 static 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 144 static 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 163 static 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 175 static 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 190 static 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 208 static 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 222 static 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 233 static 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 242 static 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 249 static 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 263 static 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 279 static 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 292 static 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 309 static 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 322 static 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 338 static 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 356 static 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 397 static 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 442 static 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 458 static 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 472 static 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 490 static 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 497 static 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 518 static 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 526 static 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 560 static inline HTMLSelectElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface) 561 { 562 return CONTAINING_RECORD(iface, HTMLSelectElement, element.node); 563 } 564 565 static 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 590 static 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 596 static 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 604 static 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 623 static 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 656 static 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 664 static 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 676 static 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 696 static const tid_t HTMLSelectElement_tids[] = { 697 HTMLELEMENT_TIDS, 698 IHTMLSelectElement_tid, 699 0 700 }; 701 702 static dispex_static_data_t HTMLSelectElement_dispex = { 703 NULL, 704 DispHTMLSelectElement_tid, 705 NULL, 706 HTMLSelectElement_tids 707 }; 708 709 HRESULT 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 } 730