Баран у новых ворот... :-(((
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 12.06.03 16:42
Оценка:
В общем, решил побаловаться написанием своего Browser Helper Object. Откопал в сети пример, который реализует простенький BHO, который подключается к событиям браузера. Все работает.

Решил повторить чужой опыт Создал ATL-проект, добавил Simple Object. Реализовал IObjectWithSite::SetSite и IDispatch::Invoke (этот для отслеживания событий)... Прописал в реестр ключик. Объект вызывается IE (что видно по MessageBox, предусмотрительно вписанным в код). IE вызывает SetSite, в котором я подписываюсь на события DWebBrowserEvents2.

События приходят в Invoke, но! Если щелкнуть на ссылке в браузере правой кнопой мыши и выбрать "Открыть ссылку в новом окне" — ничего не открывается ! Причем в том sample-проекте, который пробовал, такого недостатка нету... Перекопал настройки обоих проектов, сравнивал — ничего запредельно различного не нашел... В общем, хелп! Ниже приведены минимальные куски кода для понимания сути того, чего делается:

// Это описание класса

class ATL_NO_VTABLE CPopupKill : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CPopupKill, &CLSID_PopupKill>,
    public IObjectWithSiteImpl<CPopupKill>,
    public IDispatchImpl<IPopupKill, &IID_IPopupKill, &LIBID_IEPOPUPKILLERLib>

{
...

DECLARE_REGISTRY_RESOURCEID(IDR_POPUPKILL)
DECLARE_NOT_AGGREGATABLE(CPopupKill)

BEGIN_COM_MAP(CPopupKill)
    COM_INTERFACE_ENTRY(IPopupKill)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY_IMPL(IObjectWithSite)
END_COM_MAP()

public:

       STDMETHOD(Invoke)(DISPID dispidMember,REFIID riid, LCID lcid, WORD wFlags,
                     DISPPARAMS * pdispparams, VARIANT * pvarResult,
                     EXCEPINFO * pexcepinfo, UINT * puArgErr);

   //
   // IOleObjectWithSite Methods
   //
    STDMETHOD(SetSite)(IUnknown *pUnkSite);

private:
 
   DWORD m_dwCookie;   // Connection Token - used for Advise and Unadvise
   CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> m_spWebBrowser2;

   enum ConnectType { Advise, Unadvise };   // What to do when managing the connection

   BOOL ManageConnection(enum ConnectType eConnectType);

};


Далее, как я подписываюсь на события:

STDMETHODIMP CPopupKill::SetSite(IUnknown *pUnkSite)
{

  ::MessageBox(NULL,"IE call SetSite", NULL,MB_OK);

   if (!pUnkSite)
      ATLTRACE("\nSetSite(): pUnkSite is NULL\n\n");
   else
   {
      // Query pUnkSite for the IWebBrowser2 interface.
      m_spWebBrowser2 = pUnkSite;

      if (m_spWebBrowser2)
      {
         // Connect to the browser in order to handle events.
         if (!ManageConnection(Advise))
            ::MessageBox(NULL, _T("Failure sinking events from IWebBrowser2"), pszAppName, MB_OK);
      }
   }

   return S_OK;
}
//---------------------------------------------------------------------------
// код подписки на события...
BOOL CPopupKill::ManageConnection(enum ConnectType eConnectType)
{

  HRESULT hr;

   CComQIPtr<IConnectionPointContainer,
             &IID_IConnectionPointContainer> spCPContainer(m_spWebBrowser2);

   if (spCPContainer != NULL)
   {
      CComPtr<IConnectionPoint> spConnectionPoint;

      hr = spCPContainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &spConnectionPoint);
      if (SUCCEEDED(hr))
      {
         if (eConnectType == Advise)
         {
            //
            // Advise the client site of our desire to be handle events
            //
            hr = spConnectionPoint->Advise((IDispatch*)this, &m_dwCookie);
            if (FAILED(hr))
               ATLTRACE("\n%s: ManageConnection(): Failed to Advise\n\n", pszAppName);
         }
         else
         {
            // Remove us from the list of people interested...
            hr = spConnectionPoint->Unadvise(m_dwCookie);
            if (FAILED(hr))
               ATLTRACE("\npszAppName: ManageConnection(): Failed to Unadvise\n\n", pszAppName);
         }
      }
   }

   return (SUCCEEDED(hr));
}


Далее — код Invoke:

STDMETHODIMP CPopupKill::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
                                DISPPARAMS* pDispParams, VARIANT* pvarResult,
                                EXCEPINFO*  pExcepInfo,  UINT* puArgErr)
{

   switch (dispidMember)
   {

      case DISPID_NEWWINDOW2:
     ::MessageBox(NULL,"NewWindow2",NULL,MB_OK);
      break;

      case DISPID_QUIT:
         ManageConnection(Unadvise);
      break;
   }

 return S_OK;
}


В общем, я в полных непонятках... Чего делать? Мылить веревку?
Re: Баран у новых ворот... :-(((
От: Tom Россия http://www.RSDN.ru
Дата: 14.06.03 10:03
Оценка:
в смысле DISPID_NEWWINDOW2 не приходит?
... << RSDN@Home 1.0 beta 6a >>
Народная мудрось
всем все никому ничего(с).
Re: Баран у новых ворот... :-(((
От: bgv  
Дата: 29.11.03 20:45
Оценка:
Дай ссылку на тот пример или вышли пример, оччень нада!!!!!!!!

tangonew@mail.ru

Thanks!!!
Re[2]: Баран у новых ворот... :-(((
От: bgv  
Дата: 01.12.03 16:50
Оценка:
У меня то же самое...
А вроде все правильно...
И все молчат???
Re: Баран у новых ворот... :-(((
От: barsic  
Дата: 25.11.04 08:57
Оценка:
Здравствуйте, Flamer, Вы писали:

F>В общем, решил побаловаться написанием своего Browser Helper Object. Откопал в сети

F>Решил повторить чужой опыт Создал ATL-проект, добавил Simple Object. Реализовал F>События приходят в Invoke, но!

Вот просто выдержка из моего проекта, в котором нету такой проблемы. Мусор почисти сам.
STDMETHODIMP CIEHlprObj::Invoke(DISPID dispidMember, REFIID riid,
                                LCID lcid, WORD wFlags,
                                DISPPARAMS* pDispParams,
                                VARIANT* pvarResult,
                                EXCEPINFO*  pExcepInfo, UINT* puArgErr)
{

   USES_CONVERSION;
   strstream strEventInfo;

   if (!pDispParams)
      return E_INVALIDARG;

   //
   // Get the current URL.
   //  
   LPOLESTR lpURL = NULL;
   m_spWebBrowser2->get_LocationURL(&lpURL);

   switch (dispidMember)
   {
      //
      // The parameters for this DISPID are as follows:
      // [0]: Cancel flag  - VT_BYREF|VT_BOOL
      // [1]: HTTP headers - VT_BYREF|VT_VARIANT
      // [2]: Address of HTTP POST data  - VT_BYREF|VT_VARIANT 
      // [3]: Target frame name - VT_BYREF|VT_VARIANT 
      // [4]: Option flags - VT_BYREF|VT_VARIANT
      // [5]: URL to navigate to - VT_BYREF|VT_VARIANT
      // [6]: An object that evaluates to the top-level or frame
      //      WebBrowser object corresponding to the event 
      //
      case DISPID_BEFORENAVIGATE2:
         strEventInfo << "BeforeNavigate2: ";

         if (pDispParams->cArgs >= 5 &&
             pDispParams->rgvarg[5].vt == (VT_BYREF|VT_VARIANT))
         {
            CComVariant varURL(*pDispParams->rgvarg[5].pvarVal);
            varURL.ChangeType(VT_BSTR);

            strEventInfo << OLE2T(varURL.bstrVal);
         }
         else
            strEventInfo << "NULL";

         strEventInfo << ends;
         break;

      //
      // The parameters for this DISPID:
      // [0]: URL navigated to - VT_BYREF|VT_VARIANT
      // [1]: An object that evaluates to the top-level or frame
      //      WebBrowser object corresponding to the event 
      //
      case DISPID_NAVIGATECOMPLETE2:
         if (pDispParams->rgvarg[0].vt == (VT_BYREF|VT_VARIANT))
         {
            CComVariant varURL(*pDispParams->rgvarg[0].pvarVal);
            varURL.ChangeType(VT_BSTR);
  
            strEventInfo << "NavigateComplete2: "
                         << OLE2T(varURL.bstrVal)
                         << ends;
         }
         break;

      //
      // The parameters for this DISPID:
      // [0]: New status bar text - VT_BSTR
      //
      case DISPID_STATUSTEXTCHANGE:
         LPOLESTR lpStatusText;

         m_spWebBrowser2->get_StatusText(&lpStatusText);
         strEventInfo << "StatusTextChange: ";

         if (!strcmp(OLE2T(lpStatusText), ""))
            strEventInfo << "NULL";
         else
            strEventInfo << OLE2T(lpStatusText);

         strEventInfo << ends;
         break;

      //
      // The parameters for this DISPID:
      // [0]: Maximum progress - VT_I4
      // [1]: Amount of total progress - VT_I4
      //
      case DISPID_PROGRESSCHANGE:
         strEventInfo << "ProgressChange: ";

         if (pDispParams->cArgs == 0)
            strEventInfo << "NULL";
         else
         {
            if (pDispParams->rgvarg[0].vt == VT_I4)
               strEventInfo << pDispParams->rgvarg[0].lVal;

            if (pDispParams->cArgs > 1 &&
                pDispParams->rgvarg[1].vt == VT_I4)
            {
               strEventInfo << ", " << pDispParams->rgvarg[1].lVal;
            }
         }

         strEventInfo << ends;
         break;

      case DISPID_DOCUMENTCOMPLETE:
         strEventInfo << "DocumentComplete" << ends;
         break;

      case DISPID_DOWNLOADBEGIN:
         strEventInfo << "DownloadBegin" << ends;
         break;

      case DISPID_DOWNLOADCOMPLETE:
         strEventInfo << "DownloadComplete" << ends;
         break;

      //
      // The parameters for this DISPID:
      // [0]: Enabled state - VT_BOOL
      // [1]: Command identifier - VT_I4
      //
      case DISPID_COMMANDSTATECHANGE:
         strEventInfo << "CommandStateChange: ";

         if (pDispParams->cArgs == 0)
            strEventInfo << "NULL";
         else
         {
            if (pDispParams->rgvarg[0].vt == VT_BOOL)
            {
               strEventInfo << ((pDispParams->rgvarg[0].boolVal == 
                                 VARIANT_TRUE) ? "True" : "False");
            }

            if (pDispParams->cArgs > 1 &&
                pDispParams->rgvarg[1].vt == VT_I4)
            {
               strEventInfo << ", " << pDispParams->rgvarg[1].lVal;
            }
         }

         strEventInfo << ends;
         break;

      case DISPID_NEWWINDOW2:
         strEventInfo << "NewWindow2" << ends;
         break;

      //
      // The parameters for this DISPID:
      // [0]: Document title - VT_BSTR
      //
      case DISPID_TITLECHANGE:
         strEventInfo << "TitleChange: ";

         if (pDispParams->cArgs > 0 &&
             pDispParams->rgvarg[0].vt == VT_BSTR)
         {
            strEventInfo << OLE2T(pDispParams->rgvarg[0].bstrVal);
         }
         else
         {
            strEventInfo << "NULL";
         }

         strEventInfo << ends;
         break;

      //
      // The parameters for this DISPID:
      // [0]: Name of property that changed - VT_BSTR
      //
      case DISPID_PROPERTYCHANGE:
         strEventInfo << "PropertyChange: ";

         if (pDispParams->cArgs > 0 &&
             pDispParams->rgvarg[0].vt == VT_BSTR)
         {
            strEventInfo << OLE2T(pDispParams->rgvarg[0].bstrVal);
         }
         else
         {
            strEventInfo << "NULL";
         }

         strEventInfo << ends;
         break;

      //
      // The parameters for this DISPID:
      // [0]: Address of cancel flag - VT_BYREF|VT_BOOL
      //
      case DISPID_QUIT:
         strEventInfo << "Quit" << ends;
         //ManageConnection(Unadvise);
         //m_dlgEvents.DestroyWindow();
         break;

      default:
         strEventInfo << "Unknown Event" << dispidMember << ends;
         break;
   }

   //m_dlgEvents.AddEventToList(strEventInfo.str());

  return S_OK;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.