BHO обрабатывает событие OnSubmit

По сути, я хочу разработать BHO, который проверяет определенные поля в форме и автоматически размещает одноразовые электронные письма в соответствующих полях (больше для моих собственных знаний). Итак, в событии DOCUMENTCOMPLETE у меня есть это:

for(long i = 0; i < *len; i++)
{
    VARIANT* name = new VARIANT();
    name->vt = VT_I4;
    name->intVal = i;
    VARIANT* id = new VARIANT();
    id->vt = VT_I4;
    id->intVal = 0;
    IDispatch* disp = 0;
    IHTMLFormElement* form = 0;
    HRESULT r = forms->item(*name,*id,&disp);
    if(S_OK != r)
    {
        MessageBox(0,L"Failed to get form dispatch",L"",0);// debug only
        continue;
    }
    disp->QueryInterface(IID_IHTMLFormElement2,(void**)&form);
    if(form == 0)
    {
        MessageBox(0,L"Failed to get form element from dispatch",L"",0);// debug only
        continue;
    }

    // Code to listen for onsubmit events here...         
}

Как мне использовать интерфейс IHTMLFormElement для прослушивания события onsubmit?


person Christopher Tarquini    schedule 13.09.2009    source источник
comment
В вашем коде есть куча вещей, которые я бы изменил. Во-первых: не создавайте новые ВАРИАНТЫ, просто объявите их в стеке и передайте в обычном режиме. В любом случае, убедитесь, что вы вызываете VariantClear() для них, когда вы закончите с ними, чтобы они были освобождены должным образом. Кроме того, рассмотрите возможность использования SUCCEEDED(hr) вместо S_OK != r...   -  person i_am_jorf    schedule 13.09.2009


Ответы (1)


Когда у вас есть указатель на элемент, для которого вы хотите получать события, вы должны QueryInterface() использовать его для IConnectionPointContainer, а затем подключиться к нему:

REFIID riid = DIID_HTMLFormElementEvents2;
CComPtr<IConnectionPointContainer> spcpc;
HRESULT hr = form->QueryInterface(IID_IConnectionPointContainer, (void**)&spcpc);
if (SUCCEEDED(hr))
{
    CComPtr<IConnectionPoint> spcp;
    hr = spcpc->FindConnectionPoint(riid, &spcp);
    if (SUCCEEDED(hr))
    {
        DWORD dwCookie;
        hr = pcp->Advise((IDispatch *)this, &dwCookie);
    }
}

Некоторые примечания:

  1. Вероятно, вы захотите кэшировать dwCookie и cpc, так как они понадобятся вам позже, когда вы вызовете pcp->Unadvise() для отключения приемника.
  2. В вызове pcp->Advise() выше я передаю это. Вы можете использовать любой имеющийся у вас объект, который реализует IDispatch, который может быть или не быть этим объектом. Дизайн остается за вами.
  3. riid будет интерфейсом отправки событий, который вы хотите поглотить. В этом случае вы, вероятно, хотите DIID_HTMLFormElementEvents2.

Вот как отключить:

pcp->Unadvise(dwCookie);

Дайте мне знать, если у вас есть дополнительные вопросы.

Редактировать-1:

Да, этот DIID был неправ. Должно быть: DIID_HTMLFormElementEvents2.

Вот как я это нашел:

C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK>findstr /spin /c:"Events2" *.h | findstr /i /c:"form"
person i_am_jorf    schedule 13.09.2009
comment
Большое спасибо! Единственная проблема, с которой я столкнулся, это то, что DIID_HTMLFormEvents2 нигде не объявлен. Я пробовал искать в гугле, но он ничего не выдал. Любые идеи, как это исправить? - person Christopher Tarquini; 13.09.2009