从C ++ IHTMLInputElement触发onChange事件

时间:2012-01-13 10:37:58

标签: javascript jquery c++

我在MFC应用程序的CDialog中加载了html页面,使用IE8引擎和CDHtmlDialog实例。 html页面包含<input>个元素,并包含jQuery。在jQuery中,我有这段代码:

$(function()
{$
  $('#Left').change(function()
  {
     $('[id$=left]').prop('disabled', ! $(this).is(':checked') );
  }).change();
});

基于ID为#Left的复选框,基本上只保留一些输入和选择(由id约定选择)禁用或启用。

问题是:当我从C ++代码中更改复选框时,如下所示:

// Get pElements checkbox through doc->getElementsByTagName("input")
CComQIPtr<IHTMLInputElement> spInputElement(pElement);
spInputElement->put_checked(true);

然后更改事件不会触发(可能是为了避免无限递归),其他输入永远不会更新。有没有一种方法可以从我的C ++中明确地触发change-event?我更喜欢不要求所有复选框都有特定的html代码(例如显式的onchange =“...”),因为这对维护来说是不切实际的。

4 个答案:

答案 0 :(得分:2)

在IE8中,使用IHTCDefaultDispatch::createEventObject创建了一个事件,并使用IHTMLElement3::fireEvent触发了该事件。

对于IE9,使用IDocumentEvent :: createEvent创建一个事件,并使用IEventTarget :: dispatchEvent触发。

答案 1 :(得分:2)

所以,感谢amadeus,我明白了。这是可行的代码,因此其他人只要需要就可以复制粘贴它。

void fireOnChangeEvent(IHTMLElement* pElement)
{
    // Create a new event-object
    IHTMLEventObj* eventObject;
    IDispatch* dispatch;
    pElement->get_document(&dispatch);
    CComQIPtr<IHTMLDocument4, &__uuidof(IHTMLDocument4)> doc = dispatch;
    dispatch->Release();
    VARIANT empty;
    VariantInit(&empty);
    doc->createEventObject(&empty, &eventObject);

    // fire event
    VARIANT eventref;
    VariantInit(&eventref);
    V_VT(&eventref) = VT_DISPATCH;
    V_DISPATCH(&eventref) = eventObject;

    VARIANT_BOOL cancellable;

    CComQIPtr<IHTMLElement3, &__uuidof(IHTMLElement3)> element3 = pElement;
    BSTR bstrChange = SysAllocString(L"onchange");
    element3->fireEvent(bstrChange, &eventref, &cancellable);
    SysFreeString(bstrChange);
}

请注意,这不会触发JQuery中描述的任何事件,但它会将所有直接在html中声明的事件作为onchange="..."

答案 2 :(得分:0)

也许你可以使用 onchange 方法(参见http://msdn.microsoft.com/en-us/library/aa703817(v=vs.85).aspx)?

<强>更新

没有这种方法可能无济于事:(它为onchange事件设置了自己的处理程序。

更新2:

尝试等到文档完全加载后再触发任何事件(代码可以在http://www.codeproject.com/KB/shell/iehelper.aspx?msg=704899找到)

答案 3 :(得分:-1)

那么有一种更简单的方法。绑定到JS端的单击处理程序,在C ++中执行以下操作:

IHTMLElement *pElement;
GetElement(L"whateverInputId", &pElement);
CString value = _T("123");
COleVariant vValue(value);
pElement->setAttribute(L"value", vValue);
pElement->click();

我在上面设置了一个值(我有一个文本输入),但是对于你的复选框,如果你知道它没有被检查,你可能只是这样做:

IHTMLElement *pElement;
GetElement(L"whateverInputId", &pElement);
pElement->click();

尚未选中,但对于复选框,这甚至可能会触发onchange