Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
inet
active_desktop
active_scrptng
asp.components
asp.db
asp.general
comctl32
comp.packaging
components.dev
dbweb
dhtml_editing
docobjects
html_authoring
html_objmodel
iis
iis.ftp
iis.security
iis.smtp_nntp
indexserver
misc
mshtml_hosting
scripting.jscript
scripting.vbscript
sdk_setup
shell_objmodel
urlmonikers
webbrowser_ctl
wininet
  
 
date: Wed, 20 Apr 2005 09:43:56 -0400,    group: microsoft.public.inetsdk.programming.urlmonikers        back       


PassthroughAPP question   
Hi Igor,

Thank you for you PassthroughAPP. Yet another piece of the puzzle unlocked
by you.

I have an ATL dll control, hosting multiple webbrowser ctls which in turn
intercepts various events through implemented interfaces (IOleClientSite,
IOleInPlaceSite, IDispatch, IDocHostUIHandler, IDownloadManager,
IServiceProvider, IDocHostShowUI, IOleCommandTarget, IBindStatusCallback,
IHttpNegotiate, IInternetSecurityManager, ...) and fires events for any app
(like VB) hosting my control. I have successfully implemented your
PassthroughAPP and whenever activated, it works like a charm, OnResponse,
BeginningTransaction, ... functions are called. Afterwards, I tried to fire
events from the BeginningTransaction to see if the client app will receive
the events, very much like other events that are generated (42 of them).
Now, the strange thing is that, I am able to generate the event (traced it
back to the Fire_PassThroughAppOnBeginTransaction function, which is part of
dispinterface of my main class hosting the webbrowser control). But, the
client app never receives this event. Any ideas why
Fire_PassThroughAppOnBeginTransaction event is never received by client app?

I am using WinXP and the test app is a VB6 application.
And here is how I have implemented your PassthroughApp,
First I added these lines to the header file of my main ATL class

//////////////////////////////////////////////////////////////////
class WBPassthruSink :
 public PassthroughAPP::CInternetProtocolSinkWithSP<WBPassthruSink>,
 public IHttpNegotiate
{
 typedef PassthroughAPP::CInternetProtocolSinkWithSP<WBPassthruSink>
BaseClass;
public:

 BEGIN_COM_MAP(WBPassthruSink)
  COM_INTERFACE_ENTRY(IHttpNegotiate)
  COM_INTERFACE_ENTRY_CHAIN(BaseClass)
 END_COM_MAP()

 BEGIN_SERVICE_MAP(WBPassthruSink)
  SERVICE_ENTRY(IID_IHttpNegotiate)
 END_SERVICE_MAP()

 STDMETHODIMP BeginningTransaction(
  /* [in] */ LPCWSTR szURL,
  /* [in] */ LPCWSTR szHeaders,
  /* [in] */ DWORD dwReserved,
  /* [out] */ LPWSTR *pszAdditionalHeaders);

 STDMETHODIMP OnResponse(
  /* [in] */ DWORD dwResponseCode,
  /* [in] */ LPCWSTR szResponseHeaders,
  /* [in] */ LPCWSTR szRequestHeaders,
  /* [out] */ LPWSTR *pszAdditionalRequestHeaders);

 STDMETHODIMP ReportProgress(
  /* [in] */ ULONG ulStatusCode,
  /* [in] */ LPCWSTR szStatusText);
};

typedef PassthroughAPP::CustomSinkStartPolicy<WBPassthruSink>
 TestStartPolicy;

class WBPassthru :
 public PassthroughAPP::CInternetProtocol<TestStartPolicy>
{
};
///////////////////////////////////////////////////////////////////
//Then I added these lines to the cpp file (main ATL class),

typedef
PassthroughAPP::CMetaFactory<PassthroughAPP::CComClassFactoryProtocol,
 WBPassthru> MetaFactory;

//And here is the BeginningTransaction method
STDMETHODIMP WBPassthruSink::BeginningTransaction(LPCWSTR szURL, LPCWSTR
szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
{
 USES_CONVERSION;

 if (pszAdditionalHeaders)
 {
  *pszAdditionalHeaders = 0;
 }

 CComPtr<IHttpNegotiate> spHttpNegotiate;
 QueryServiceFromClient(&spHttpNegotiate);
 HRESULT hr = spHttpNegotiate ?
  spHttpNegotiate->BeginningTransaction(szURL, szHeaders,
   dwReserved, pszAdditionalHeaders) : S_OK;

 CComPtr<IWinInetHttpInfo> spWinInetHttpInfo;
 HRESULT hrTemp = m_spTargetProtocol->QueryInterface(IID_IWinInetHttpInfo,
  reinterpret_cast<void**>(&spWinInetHttpInfo));
 if(SUCCEEDED(hrTemp))
 {
  DWORD size = 0;
  DWORD flags = 0;
  hrTemp = spWinInetHttpInfo->QueryInfo(
   HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HEADERS,
   0, &size, &flags, 0);
  if(SUCCEEDED(hrTemp))
  {
   LPSTR pbuf = new char[size+1];
   pbuf[size] = '\0';
   hrTemp = spWinInetHttpInfo->QueryInfo(
    HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HEADERS,
    pbuf, &size, &flags, 0);
   if(SUCCEEDED(hrTemp))
   {
    VARIANT_BOOL bcancel = VARIANT_FALSE;
    //gpMyCtrl is a global pointer to my main ATL class
    //which is set when OnCreate event of the main ATL class is fired
    if(gpMyCtrl)
    {

gpMyCtrl->Fire_PassThruOnBeginTransaction(W2BSTR(szURL),A2BSTR(pbuf),&bcance
l);
     //Log(_T("Firing events"),_T("WBPassthruSink::BeginningTransaction"));
    }
    else
     //Log(_T("NO OBJECT for
gpMyCtrl"),_T("WBPassthruSink::BeginningTransaction"));
   }
   else
    //Log(_T("NO RAW HEADERS"),_T("WBPassthruSink::BeginningTransaction"));
  }
 }
 return hr;
}

////////////////////////////////////////////////////////////////////////////
/////
//Here is the Fire_PassThruOnBeginTransaction function taken from
CProxy_IxxxEvents
 VOID Fire_PassThruOnBeginTransaction(BSTR sURL, BSTR
sRequestHeaders,VARIANT_BOOL * Cancel)
 {
  T* pT = static_cast<T*>(this);
  int nConnectionIndex;
  CComVariant* pvars = new CComVariant[3];
  int nConnections = m_vec.GetSize();

  for (nConnectionIndex = 0; nConnectionIndex < nConnections;
nConnectionIndex++)
  {
   pT->Lock();
   CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
   pT->Unlock();
   IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
   if (pDispatch != NULL)
   {
    pvars[2] = sURL;
    pvars[1] = sRequestHeaders;
    pvars[0].vt = VT_BYREF|VT_BOOL;
    pvars[0].byref = Cancel;
    DISPPARAMS disp = { pvars, NULL, 3, 0 };
    pDispatch->Invoke(0x2a, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,
&disp, NULL, NULL, NULL);
    //Message box fires

//::MessageBox(GetDesktopWindow(),_T("Fire_PassThruOnBeginTransaction"),_T("
Fire_PassThruOnBeginTransaction"),MB_OK);
   }
  }
  delete[] pvars;

 }

Best Regards
MH
date: Wed, 20 Apr 2005 09:43:56 -0400   author:   MH

Re: PassthroughAPP question   
"MH"  wrote in message
news:euidnU5zb6wiwfvfRVn-rQ@rogers.com
> I have successfully implemented your
> PassthroughAPP and whenever activated, it works like a charm,
> OnResponse, BeginningTransaction, ... functions are called.
> Afterwards, I tried to fire events from the BeginningTransaction to
> see if the client app will receive the events, very much like other
> events that are generated (42 of them). Now, the strange thing is
> that, I am able to generate the event (traced it back to the
> Fire_PassThroughAppOnBeginTransaction function, which is part of
> dispinterface of my main class hosting the webbrowser control). But,
> the client app never receives this event. Any ideas why
> Fire_PassThroughAppOnBeginTransaction event is never received by
> client app?

Your code looks (almost) good to me. Have you traced into 
Fire_PassThruOnBeginTransaction? Does it reach Invoke call? Does the 
call succeed?

If the answers to these two questions are both "yes", the symptom looks 
surprisingly like that described in KB Article KB129733 "VB 4.0 Calls 
the FreezeEvents Method to Inform OLE Controls". Try and see if 
IOleControl::FreezeEvents is being called on your control in such a way 
that BeginningTransaction arrives inside the FreezeEvents bracket.

> gpMyCtrl->Fire_PassThruOnBeginTransaction(W2BSTR(szURL),A2BSTR(pbuf),&bcancel);

You are leaking two BSTRs here. X2BSTR macros allocate a BSTR for you, 
and leave you with the responsibility to free it. Make it

gpMyCtrl->Fire_PassThruOnBeginTransaction(
    CComBSTR(szURL), CComBSTR(pbuf), &bcancel);

-- 
With best wishes,
    Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not 
necessarily a good idea. It is hard to be sure where they are going to 
land, and it could be dangerous sitting under them as they fly 
overhead. -- RFC 1925
date: Wed, 20 Apr 2005 10:07:47 -0400   author:   Igor Tandetnik

Re: PassthroughAPP question   
Igor,

Thank you for your quick reply.

As you suggested, I used IOleControl::FreezeEvents to see if it is being
called in a way
that BeginningTransaction arrives inside the FreezeEvents bracket. I also
checked the return value of Invoke (it is being called) from within
Fire_PassThruOnBeginTransaction function. It always returns S_OK.

Here is a log of what happens after launching app and navigating to google,
/////////////////////////////////////////////
///Right after app is launched

CvbWB::FreezeEvents->FreezeEvents - TRUE
CvbWB::FreezeEvents->FreezeEvents - FALSE
CvbWB::FreezeEvents->FreezeEvents - TRUE
CvbWB::FreezeEvents->FreezeEvents - FALSE
CvbWB::FreezeEvents->FreezeEvents - TRUE
CvbWB::FreezeEvents->FreezeEvents - FALSE

//////////////////////////////////////////////
//Here is what I get after nav to goolge

WBPassthruSink::BeginningTransaction->Firing events
Invoke->OK
WBPassthruSink::BeginningTransaction->Firing events
Invoke->OK
WBPassthruSink::BeginningTransaction->Firing events
Invoke->OK
WBPassthruSink::BeginningTransaction->Firing events
Invoke->OK

/////////////////////////////////////////////
//And after terminating the app

CvbWB::FreezeEvents->FreezeEvents - TRUE
CvbWB::FreezeEvents->FreezeEvents - TRUE
CvbWB::FreezeEvents->FreezeEvents - TRUE

Any other ideas why the client app never receives the event or perhaps it
receives it but gets discarded somehow?

Best regards
MH
date: Wed, 20 Apr 2005 11:38:53 -0400   author:   MH

Re: PassthroughAPP question   
"MH"  wrote in message
news:r7GdnZMCgocO6vvfRVn-og@rogers.com
> As you suggested, I used IOleControl::FreezeEvents to see if it is
> being called in a way
> that BeginningTransaction arrives inside the FreezeEvents bracket. I
> also checked the return value of Invoke (it is being called) from
> within Fire_PassThruOnBeginTransaction function. It always returns
> S_OK.
>
> Any other ideas why the client app never receives the event or
> perhaps it receives it but gets discarded somehow?

Another thing to check - see if BeginningTransaction is called on the 
main thread, the same thread that created the control in the first place 
(you can use GetCurrentThreadId). I believe it should, but check anyway 
just in case. I'm running out of ideas here.
-- 
With best wishes,
    Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not 
necessarily a good idea. It is hard to be sure where they are going to 
land, and it could be dangerous sitting under them as they fly 
overhead. -- RFC 1925
date: Wed, 20 Apr 2005 11:45:23 -0400   author:   Igor Tandetnik

Re: PassthroughAPP question   
Igor,

The thread ids are the same as you expected. I even used a working event
just to be sure. The client never receives the event.

Thank you very much for your help.

Best Regards
MH
date: Wed, 20 Apr 2005 12:30:53 -0400   author:   MH

Re: PassthroughAPP question   
"MH"  wrote in message
news:uqKdnYhWrpZZHvvfRVn-iQ@rogers.com
> The thread ids are the same as you expected. I even used a working
> event just to be sure. The client never receives the event.

Sorry, I'm out of ideas. The problem is clearly on the client (VB) side, 
and I don't have a clue what might be wrong with VB.

I can suggest one thing to try and work around this problem. Instead of 
firing an event directly from BeginningTransaction, post yourself a 
custom message (with PostMessage, not SendMessage), and fire an event 
from that message's handler. See if the event fares better this way.
-- 
With best wishes,
    Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not 
necessarily a good idea. It is hard to be sure where they are going to 
land, and it could be dangerous sitting under them as they fly 
overhead. -- RFC 1925
date: Wed, 20 Apr 2005 12:40:48 -0400   author:   Igor Tandetnik

Re: PassthroughAPP question   
For the reader,

Please refer to KB article 280512 for fix:
SAMPLE: ATLCPImplMT encapsulates ATL event firing across COM apartments
http://support.microsoft.com/default.aspx?scid=kb;en-us;280512

And  refer to KB article 196026 for further info:
PRB: Firing Event in Second Thread Causes IPF or GPF
http://support.microsoft.com/default.aspx?scid=kb;en-us;196026
date: Fri, 5 Aug 2005 10:22:12 -0400   author:   MH

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us