PlanetSquires Forums

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 2 [3]

Author Topic: CWindow RC 17  (Read 13771 times)

José Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3228
Re: CWindow RC 17
« Reply #30 on: August 24, 2016, 09:23:26 PM »

Another problem with the WebBrowser conttrol is that Microsoft, in its infinite wisdom, makes IE 7 the default-rendering mode for all applications that use the WB control. And to change this behavior, you have to add the application name to the registry key HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION.

José Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3228
Re: CWindow RC 17
« Reply #31 on: August 24, 2016, 09:34:44 PM »

The OLE Container works with the 64-bit compiler. What I'm having problems are with the events.

José Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3228
Re: CWindow RC 17
« Reply #32 on: August 24, 2016, 11:21:29 PM »

Got it! I just needed to change EXTENDS Afx_IDocHostUIHandler2 to EXTENDS Afx_IUnknown.

Because it worked with 32 bit, it made me thing, wrongly, that the problem was elsewhere, and I only have tried this after discarding anything else. Such is life!

Regarding the problem of compatibility, for the examples that I will do, using my own html code, I will use a meta tag:

<meta http-equiv=”X-UA-Compatible” content=”IE=edge”>.

If somebody wants to do a browser, be aware of the compatibility problem and don't blame me if some web pages aren't rendered correctly.

The following article discusses the question:

Controlling WebBrowser Control Compatibility
https://blogs.msdn.microsoft.com/patricka/2015/01/12/controlling-webbrowser-control-compatibility/

Marc Pons

  • Junior Member
  • **
  • Posts: 141
  • FF3 User
Re: CWindow RC 17
« Reply #33 on: August 25, 2016, 06:41:57 AM »

Jose

here my evolution of your olecon.inc

I wanted to be able to know wich cId is making the event ( interresting when using more than 1 component ...)

so i put a dummy class type to be generic to be able to transmit the value of the cID when advise is done
Code: [Select]
'dummy event type to mimic the event Afx_IDispatch to put the cID in event class
TYPE Dummy_Events
dummy as integer
        m_cID as integer = -1
END TYPE

I've checked the m_cID is 4 bytes (in 32bits) after the adress of the class ( if i put it like that)
that's why dummy as integer exists in dummy_events (hope it also works in 64bits)
Code: [Select]
TYPE CWebBrowserEventsImpl EXTENDS Afx_IDispatch
   DECLARE VIRTUAL FUNCTION QueryInterface (BYVAL riid AS REFIID, BYVAL ppvObject AS LPVOID PTR) AS HRESULT
   DECLARE VIRTUAL FUNCTION AddRef () AS ULONG
   DECLARE VIRTUAL FUNCTION Release () AS ULONG
   DECLARE VIRTUAL FUNCTION GetTypeInfoCount (BYVAL pctinfo AS UINT PTR) AS HRESULT
   DECLARE VIRTUAL FUNCTION GetTypeInfo (BYVAL iTInfo AS UINT, BYVAL lcid AS LCID, BYVAL ppTInfo AS ITypeInfo PTR PTR) AS HRESULT
   DECLARE VIRTUAL FUNCTION GetIDsOfNames (BYVAL riid AS CONST IID CONST PTR, BYVAL rgszNames AS LPOLESTR PTR, BYVAL cNames AS UINT, BYVAL lcid AS LCID, BYVAL rgDispId AS DISPID PTR) AS HRESULT
   DECLARE VIRTUAL FUNCTION Invoke (BYVAL dispIdMember AS DISPID, BYVAL riid AS CONST IID CONST PTR, BYVAL lcid AS LCID, BYVAL wFlags AS WORD, BYVAL pDispParams AS DISPPARAMS PTR, BYVAL pVarResult AS VARIANT PTR, BYVAL pExcepInfo AS EXCEPINFO PTR, BYVAL puArgErr AS UINT PTR) AS HRESULT
   DECLARE CONSTRUCTOR
   DECLARE DESTRUCTOR
m_cID as integer = -1  '// cID of the component     first position of vars
   m_pIDocHostUIHandler AS ANY PTR
END TYPE

the new class
Code: [Select]
TYPE COleCon

Public:
   m_pData AS Afx_OleConDispatch PTR
   m_bUninitOLE AS BOOLEAN
   m_dwCookie AS DWORD          ' // Cookie for Unadvise
   m_riidEvt AS IID PTR         ' // IID of the events interface
m_pEvt as Dummy_Events PTR '// dummy event to mimic the event Afx_IDispatch to put the cID in event class
cID as INTEGER = -1 '// the control ID
Ev_cID as INTEGER = -1 '// the control ID fired event ( changed by advise/unadvise)

Private:
   DECLARE SUB CreateContainer (BYVAL pWindow AS CWindow PTR, BYVAL cID AS INTEGER, BYREF wszProgID AS WSTRING, _
      BYREF wszLibName AS WSTRING, BYREF rclsid AS const CLSID, BYREF riid AS const IID, BYREF wszLicKey AS WSTRING, _
      BYVAL x AS LONG = 0, BYVAL y AS LONG = 0, BYVAL nWidth AS LONG = 0, BYVAL nHeight AS LONG = 0, _
      BYVAL dwStyle AS DWORD = 0, BYVAL dwExStyle AS DWORD = 0, BYVAL ambientFlags AS DWORD = 0)
...

the new advise function
Code: [Select]
PRIVATE FUNCTION COleCon.Advise (BYVAL pEvtObj AS IDispatch PTR, BYVAL riid AS IID PTR) AS HRESULT
   OC_DP("BEGIN COlecon.Advise")
   IF pEvtObj = NULL THEN RETURN E_POINTER
m_pEvt = cast(any ptr ,pEvtObj)
   m_riidEvt = riid
   ' // Query for the IConnectionPointContainer interface
   DIM pCPC AS IConnectionPointContainer PTR
   DIM hr AS HRESULT = IUnknown_QueryInterface(m_pData->m_pOcx, @IID_IConnectionPointContainer, @pCPC)
   IF hr <> S_OK OR pCPC = NULL THEN RETURN hr
   ' // Query for the IConnectionPoint interface
   DIM pCP AS IConnectionPoint PTR
   hr = pCPC->lpvtbl->FindConnectionPoint(pCPC, riid, @pCP)
   IF hr <> S_OK OR pCP = NULL THEN
      IUnknown_Release(pCPC)
      RETURN hr
   END IF
   ' // Terminates the advisory connection previously established between a connection point object and a client's sink.
   IF m_dwCookie THEN hr = pCP->lpvtbl->Unadvise(pCP, m_dwCookie)
   m_dwCookie = 0
   ' // Establishes a connection between a connection point object and the client's sink.
   hr = pCP->lpvtbl->Advise(pCP, cast(IUnknown PTR, pEvtObj), @m_dwCookie)
   IF pCPC THEN IUnknown_Release(pCPC)
   IF pCP THEN
this.Ev_cID = this.cID
m_pEvt->m_cID = this.cID
print "Advise event : " & m_pEvt-> m_cID
IUnknown_Release(pCP)
END IF
   OC_DP("END COlecon.Advise")
   RETURN hr
END FUNCTION

the evolution of unadvise function
Code: [Select]
IF pCP THEN
     IUnknown_Release(pCP)
     this.Ev_cID = -1
END IF

a simple test is also included, must be compiled with -s console parameter ( because sleep)
« Last Edit: August 25, 2016, 07:51:58 AM by Marc Pons »
Logged

José Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3228
Re: CWindow RC 17
« Reply #34 on: August 25, 2016, 02:32:42 PM »

I already had changed the example before going to sleep. Will add more changes if needed.

There is no need to change the Advise/Unadvise functions. Just add a new constructor to the events class:

Code: [Select]
' ########################################################################################
' CWebBrowserEventsImpl class
' Implementation of the WebBrowser events sink class
' ########################################################################################
TYPE CWebBrowserEventsImpl EXTENDS Afx_IDispatch
   DECLARE VIRTUAL FUNCTION QueryInterface (BYVAL riid AS REFIID, BYVAL ppvObject AS LPVOID PTR) AS HRESULT
   DECLARE VIRTUAL FUNCTION AddRef () AS ULONG
   DECLARE VIRTUAL FUNCTION Release () AS ULONG
   DECLARE VIRTUAL FUNCTION GetTypeInfoCount (BYVAL pctinfo AS UINT PTR) AS HRESULT
   DECLARE VIRTUAL FUNCTION GetTypeInfo (BYVAL iTInfo AS UINT, BYVAL lcid AS LCID, BYVAL ppTInfo AS ITypeInfo PTR PTR) AS HRESULT
   DECLARE VIRTUAL FUNCTION GetIDsOfNames (BYVAL riid AS CONST IID CONST PTR, BYVAL rgszNames AS LPOLESTR PTR, BYVAL cNames AS UINT, BYVAL lcid AS LCID, BYVAL rgDispId AS DISPID PTR) AS HRESULT
   DECLARE VIRTUAL FUNCTION Invoke (BYVAL dispIdMember AS DISPID, BYVAL riid AS CONST IID CONST PTR, BYVAL lcid AS LCID, BYVAL wFlags AS WORD, BYVAL pDispParams AS DISPPARAMS PTR, BYVAL pVarResult AS VARIANT PTR, BYVAL pExcepInfo AS EXCEPINFO PTR, BYVAL puArgErr AS UINT PTR) AS HRESULT
   DECLARE CONSTRUCTOR
   DECLARE CONSTRUCTOR (BYVAL hwnd AS HWND)
   DECLARE DESTRUCTOR
   m_hwnd AS HWND   ' // Handle of the container's window
   m_pIDocHostUIHandler AS CDocHostUIHandler2Impl PTR
END TYPE
' ########################################################################################

Code: [Select]
' ========================================================================================
' Constructors
' ========================================================================================
CONSTRUCTOR CWebBrowserEventsImpl
   ' // Create an instance of the IDocHostUIHandler class
   m_pIDocHostUIHandler = NEW CDocHostUIHandler2Impl
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
CONSTRUCTOR CWebBrowserEventsImpl (BYVAL hwnd AS HWND)
   m_hwnd = hwnd
   ' // Create an instance of the IDocHostUIHandler class
   m_pIDocHostUIHandler = NEW CDocHostUIHandler2Impl
END CONSTRUCTOR
' ========================================================================================

' ========================================================================================
' Destructor
' ========================================================================================
DESTRUCTOR CWebBrowserEventsImpl
   ' // Delete the IDocHostUIHandler class
   IF m_pIDocHostUIHandler THEN Delete m_pIDocHostUIHandler
END DESTRUCTOR
' ========================================================================================

Code: [Select]
   ' // Create an instance of our CWebBrowserEventsImpl class and connect the WebBrowser events
   DIM pEvtObj AS CWebBrowserEventsImpl PTR = NEW CWebBrowserEventsImpl(pOlecon->hWindow)
   dim hr as hresult = pOleCon->Advise(pEvtObj, DIID_DWebBrowserEvents2)

Doing it in the events class, that you have to implement anyway, you can add as much info as you want/need and not being limited to what Advise supports.

I also have modified the ForwardMessage function:

Code: [Select]
' ========================================================================================
' Forwards the message to the control. Active in-place objects must always be given the
' first chance at translating accelerator keystrokes. You can provide this opportunity by
' calling IOleInPlaceActiveObject.TranslateAccelerator from your container's message loop
' before doing any other translation. You should apply your own translation only when this
' method returns FALSE.
' Remarks: If the control is the WebBrowser control, TranslateAccelerator calls the namesake
' method of the IDocHostUIHandler interface.
' ========================================================================================
PRIVATE FUNCTION COleCon.ForwardMessage (BYVAL pMsg AS tagMsg PTR) AS BOOLEAN
   IF m_pData->m_pOcx = NULL THEN RETURN FALSE
   ' // See if the window with focus is the WebBrowser control
   IF m_pData->m_wszProgID = "Shell.Explorer" OR m_pData->GuidText(@m_pData->m_rclsid) = "8856F961-340A-11D0-A96B-00C04FD705A2"  THEN
      DIM hwndFocus AS HWND = GetFocus
      DIM hWin AS HWND = FindWindowEx(m_pData->m_hwnd, NULL, "Shell Embedding", "")
      IF hWin THEN hWin = FindWindowEx(hWin, NULL, "Shell DocObject View", "")
      IF hWin THEN hWin = FindWindowEx(hWin, NULL, "Internet Explorer_Server", "")
      IF hWin <> hwndFocus THEN RETURN FALSE
   ELSE
      ' // See if the window that has the focus is a child of our container window
      DIM hWndParent AS HWND, hWndTmp AS HWND
      hWndParent = GetFocus()
      DO
         hWndTmp = GetParent(hWndParent)
         IF hWndTmp = NULL THEN EXIT DO
         hWndParent = hWndTmp
         IF hWndParent = m_pData->m_hwnd THEN EXIT DO
      LOOP
      IF hWndParent <> m_pData->m_hwnd THEN RETURN FALSE
   END IF
   ' // Translate the message
   DIM hr AS HRESULT, pActiveObject AS IOleInPlaceActiveObject PTR
   hr = IUnknown_QueryInterface(m_pData->m_pOcx, @IID_IOleInPlaceActiveObject, @pActiveObject)
   IF pActiveObject = NULL THEN RETURN FALSE
   hr = pActiveObject->lpvtbl->TranslateAccelerator(pActiveObject, pMsg)
   IUnknown_Release(pActiveObject)
   IF hr = S_OK THEN RETURN TRUE
END FUNCTION
' ========================================================================================

« Last Edit: August 25, 2016, 02:36:56 PM by Jose Roca »
Logged

Marc Pons

  • Junior Member
  • **
  • Posts: 141
  • FF3 User
Re: CWindow RC 17
« Reply #35 on: August 26, 2016, 06:47:03 AM »

Jose,

I've also tried with constructor (var something),it was my first idea,
but i wanted to be more automatic and why impose to define something when it can be automatized ?
My dummy type proposition can do that easily ( or other solution to write to mem var)

And as the event class is only connected after advise is done we don't care before.
in my opinion using advise/unadvise  to enable/disable events is a good solution,
testing the cid var of that event class (or whatever var : hwnd  if prefered) could be interresting.
advise to set the var value , unadvise to reset the var value.

a detail point in your proposal
Code: [Select]
DIM pEvtObj AS CWebBrowserEventsImpl PTR = NEW CWebBrowserEventsImpl(pOlecon->hWindow)you probably want to do : pOlecon->m_pData->m_hwnd

and using your word " Doing it in the events class, that you have to implement anyway, you can add as much info as you want/need "

transfering m_pData is even better, to not be limited

what do you think?
Logged

Marc Pons

  • Junior Member
  • **
  • Posts: 141
  • FF3 User
Re: CWindow RC 17
« Reply #36 on: August 26, 2016, 07:00:00 AM »

Jose

My target idea is to have a generic tool as your TypeLib Browser adapted to freebasic using your Cwindow framework
to ease the job of non-expert COM as I am when needing to use activeX/OCX component.

am i dreaming ?

Today, i use the AxSuite3, my adaptation of the AxSuite2 done by Loe ( using lot of your original code ),
not perfect but quite usable.
Logged

José Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3228
Re: CWindow RC 17
« Reply #37 on: August 26, 2016, 12:01:45 PM »

Quote
you probably want to do : pOlecon->m_pData->m_hwnd

and using your word " Doing it in the events class, that you have to implement anyway, you can add as much info as you want/need "

transfering m_pData is even better, to not be limited

what do you think?

It was only an example. You can store whatever you wish / need.

José Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3228
Re: CWindow RC 17
« Reply #38 on: August 26, 2016, 12:13:51 PM »

Besides, you don't even need to add new constructors. You can access the data directly, e.g.

Instead of

Code: [Select]
DIM pEvtObj AS CWebBrowserEventsImpl PTR = NEW CWebBrowserEventsImpl(pOlecon->hWindow)

you can do

Code: [Select]
DIM pEvtObj AS CWebBrowserEventsImpl PTR = NEW CWebBrowserEventsImpl
pEvtObj->m_hwnd = pOlecon->hWindow

I also want to make the Advise and Unadvise methods standalone functions, for use with non visual OCXs.

José Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3228
Re: CWindow RC 17
« Reply #39 on: August 26, 2016, 12:15:56 PM »

Jose

My target idea is to have a generic tool as your TypeLib Browser adapted to freebasic using your Cwindow framework
to ease the job of non-expert COM as I am when needing to use activeX/OCX component.

am i dreaming ?

Today, i use the AxSuite3, my adaptation of the AxSuite2 done by Loe ( using lot of your original code ),
not perfect but quite usable.


It is a lot of work and has low priority to me, since I don't use OCXs. First I have to do other things.
Pages: 1 2 [3]