Запуск события onChange из C++ IHTMLInputElement



У меня есть html-страница, загруженная в CDialog в приложении MFC, использующем движок IE8, и экземпляр CDHtmlDialog. Html-страница содержит элементы <input> и включает в себя jQuery. В упомянутом jQuery у меня есть такой код:



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


, который по существу просто сохраняет некоторые входы и выбирает (выбранный по соглашению id) отключенным или включенным, основываясь на флажке с идентификатором #Left.



Проблема заключается в следующем: Когда я изменяю флажок из кода C++ следующим образом:



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


Затем событие change не запускает (возможно, чтобы избежать бесконечной рекурсии), и другие входные данные никогда не обновляются. Есть ли способ, которым я могу запустить событие изменения явно из моего C++? Я бы предпочел не требовать, чтобы все флажки имели определенный html-код (например, явный onchange="..."), поскольку это было бы непрактично для технического обслуживания.

588   4  

4 ответов:

В IE8 событие создается с помощью IHTCDefaultDispatch::createEventObject и запускается с помощью IHTMLElement3::fireEvent.

Для IE9 событие создается с помощью IDocumentEvent:: createEvent и запускается с помощью IEventTarget:: dispatchEvent.

Так что, благодаря Амадею, я все понял. Это код, который работает, так что все остальные могут просто скопировать и вставить его, если им это нужно.

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="..."

Возможно, вы можете использовать метод onchange (см. http://msdn.microsoft.com/en-us/library/aa703817 (v=против 85).aspx )?

Обновление:

Нет этот метод, вероятно, не поможет : (он устанавливает свой собственный обработчик для события onchange.

Обновление 2:

Попробуйте дождаться полной загрузки документа, прежде чем запускать какие-либо события ( код можно найти по адресу http://www.codeproject.com/KB/shell/iehelper.aspx?msg=704899 )

Ну, есть более простой способ. Привязать к обработчику щелчка на стороне 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();

Не проверял, но для checkbox это, вероятно, даже сработает onchange.

Comments

    Ничего не найдено.