Hello All,

At one time ernie and I were working on getting a Web Browser
control to inplace activate on a window. I did complete the code
but didn't transfer it to anyone. My harddrive crashed some time
ago and unfortunately, I'm now stuck on some of the original
problems I solved eariler:

1) Is OLEIVERB_INPLACEACTIVATE = -5L the same as
OLEIVERB_INPLACEACTIVATE equ 0FFFFFFFBh ?

2) Ensuring that my client site is well defined.

3) The return value from the LocalAlloc function in the
"CreateObject" function is the C++ "This" pointer.
RiGhT?????

4) Getting people to not loose respect for me
because of my QueryInterface code. It will be fixed...


See the source code attachment. Be sure to change the
paths in Browser.inc.



:alright: Xtreme
Posted on 2001-08-20 09:04:16 by Xtreme
According to calc.exe -5 = 0xFFFFxFFFB . What does your code do?
Posted on 2001-08-20 23:16:15 by eet_1024
1) My calc.exe agrees with eets. Basically, if you set HEX mode to DWORD, then set back to decimal mode, type in a negative number, then switch again to HEX, you get the HEX representation of the negative decimal number (IE, -5 becomes FFFFFFFB)

2) Huh? (guess I best read your source later)

3) exactly correct.

4) No comment, as long as you don't comment on my registrar script parser. QueryInterface will always look ugly until you do something like make it scan a table (at which point it becomes inintelegable and thus looks 'realy leet.')
Posted on 2001-08-21 06:39:07 by Ernie
eet_1024,

This code should display the MS Web Browser control on a
window and allow one to display (D)HTML.


Note: You have to click the client area of the window to make it
create the control. Or you could move "invoke CreateWB" to
WM_CREATE.


Unfortunately the DoVerb function of IOleObject fails and I don't
understand why...

Xtreme
Posted on 2001-08-21 07:51:14 by Xtreme
Just for completeness:

-5 =

0xB for 4-bit
0xFB for 8-bit
0xFFFB for 16-bit
0xFFFFFFFB for 32-bit
0xFFFFFFFFFFFFFFFB for 64 bit
...you get the idea...
negitive numbers are a relitive concept, and the bit count includes one bit for sign.

I'll have to checkout that code when I have more time.
Posted on 2001-08-21 08:27:30 by bitRAKE
bitRAKE,

Thanks for the breakdown. The primary thing that confused me
was the 'L' in -5L. There are other number "extensions" in the
C++ header files that I don't get as well: U and t (note the case).
I suppose these mean Long, UINT, and t...(something).

At any rate the contant was defined correctly so there must be
a goof in my class definition (client site).
Posted on 2001-08-21 08:44:31 by Xtreme
I have the original C++ source (NO mfc) if anyone needs it.
I may just post it here anyway...
Posted on 2001-08-21 15:56:55 by Xtreme
X,

Do you realize that when you're done you should be able to host most any activeX control on your window?

To host any control, you need to build a client site. Client sites are kinda generic.
Posted on 2001-08-22 07:03:09 by Ernie
Ernie,

The Object struct instance is the client site.
Any idea why DoVerb is failing?

Its probably something in "CreateObject"...

Thanks!

PS: When I'm finished I'll send you a formal version to put in the
COM section of the MASM32 package, along with a tut...
Posted on 2001-08-22 07:43:47 by Xtreme
Sorry, I never got that far into insertable objects to know the fine points of do verbs.

The general purpose stuff sounds great. You don't have to wait for me, you can publish on your own too. Want a link on my page?
Posted on 2001-08-22 20:16:55 by Ernie
Xtreme,

code in CreateObject should look like:




mov ebx, eax
mov eax,pobj
mov [eax], ebx

mov (Object ptr [ebx]).nRefCount,0


that is because parameter is a pointer to an object, not the object itself.

After this change your program still crashes
:grin:

Reason is: your parameter to SetClientSite is wrong. Be sure that your parameter is a pointer to an IClientSite interface.
May be you should change code to:


; Set the Web Browser Control's site
; coinvoke _pIOleObject, IOleObject, SetClientSite, [pif]
mov eax,pif
lea eax,[eax].Object.iOleClientSite.lpVtbl
coinvoke _pIOleObject, IOleObject, SetClientSite, eax



with this changes done, the OleClientSite procs are called, but after some time the program crashes.


regards,

japheth
Posted on 2001-08-23 07:27:17 by japheth
Heres the original C++ source code. Its actually useful in itself
because it doesn't use MFC.

The package includes an EXE that shows the WB Control in action.

Note: Right-click somewhere on the window background to see the IE context menu.
Posted on 2001-08-23 09:16:58 by Xtreme
Xtreme

I had a second look at your code.

you should think once again about your macro GETOBJECTPOINTER.

In my opinion it does not work correctly. Consider QueryInterface: this function can be called from any interface. To subtract a value depending just on the queriing interface will not work.

Have a look at Ernie's examples. For every supported Interface there exists an entry:



ObjectEntry STRUCT DWORD
m_pVtbl DWORD 0 ; interface object
m_pBase DWORD 0 ; pointer to base
ObjectEntry ENDS


and the object (ASMCTRL i.e.) ist defined like:



AsmCtrlObject STRUCT
ObjectData0 ObjectData { } ; base values
AsmCtrlData0 AsmCtrlData { } ; custom object data
ObjectEntry0 ObjectEntry { } ; delegated Unknown
ObjectEntry1 ObjectEntry { } ; IAsmCtrl
ObjectEntry2 ObjectEntry { } ; IOleObject


this is more complicated I admit but it cannot be avoided.

japheth
Posted on 2001-08-23 10:32:22 by japheth
Japheth,

Bill T's original macro code to suit my needs. This
is a down side to having code "definitions" and source in different
files. The "Object.Interface" that Bill calls on does not exist in my
app...

THANK YOU!



OOPs... I spoke too soon.

I didn't relize that Interface is a parameter passed to the macro.
How can this then be incorrect? Besides how can the
IOleClientSite procs get called if this is wrong?
Posted on 2001-08-23 11:20:09 by Xtreme
Xtreme,

to get your code to work I have changed macro GETOBJECTPOINTER to:



GETOBJECTPOINTER MACRO Object, Interface, pif
mov eax, pif
sub eax,
ENDM



the definition of Object to:

[code]
; declare the site structure

Object struct
iUnknown IIUnknown <?>
iBase0 dd ?
iOleWindow IIOleWindow <?>
iBase1 dd ?
iOleClientSite IIOleClientSite <?>
iBase2 dd ?
iOleInPlaceSite IIOleInPlaceSite <?>
iBase3 dd ?
iDispatch IIDispatch <?>
iBase4 dd ?
iDocHostUIHandler IIDocHostUIHandler <?>
iBase5 dd ?
iDocHostShowUI IIDocHostShowUI <?>
iBase6 dd ?
nRefCount dd ?
Object ends
[/code]

and CreateObject to:

[code]
mov (Object ptr ).iOleInPlaceSite.lpVtbl, offset vtblIOleInPlaceSite ; save the offset(pointer) to the interface VTABLE in lpVtbl
mov (Object ptr ).iDispatch.lpVtbl, offset vtblIDispatch ; save the offset(pointer) to the interface VTABLE in lpVtbl
mov (Object ptr ).iDocHostUIHandler.lpVtbl, offset vtblIDocHostUIHandler ; save the offset(pointer) to the interface VTABLE in lpVtbl
mov (Object ptr ).iDocHostShowUI.lpVtbl, offset vtblIDocHostShowUI ; save the offset(pointer) to the interface VTABLE in lpVtbl
mov .Object.iBase0,0
mov .Object.iBase1,8
mov .Object.iBase2,16
mov .Object.iBase3,24
mov .Object.iBase4,32
mov .Object.iBase5,40
mov .Object.iBase6,48
[/code]

with this changes QueryInterface always returns the correct interface. Without this changes the webbrowser control queries for IDispatch and gets IOleInPlaceSite (or was it IOleClientSite? I forgot). And the interface pointer to IOleClientSite is received by the object thru the call IOleObject:SetClientSite, not by QueryInterface.

when executing this code I get so far that IDispatch:Invoke is called from the webbrowser control twice. But then it crashes again. I had no time yet to check this.

japheth
Posted on 2001-08-24 03:13:55 by japheth
japeth,

Last night I examined the macro more closely. I agree that is
is just too simple to work here. I also placed messageboxes
in the queryinterface function of both the C++ and ASM versions.
The C++ version doesn't call IOleClientSite at all (at least on start
up) but the ASM version does (its the second and fourth interface
call). This undoubtably means theres a problem with the ASM
QueryInterface function (As my second look at your post shows
you found!).

Also note that I found some errors in:


    [*]Declarations of IDispatch, IOleWindow, IOleClientSite,
    and IOleInPlaceSite. See Ernie's \masm32\COM\include\
    component.inc for proper declares. Or does it really matter
    that I declare a BOOL as BYTE and SIZE as SIZEL?

    [*]AddRef and Release. I uncommented them and used nRefCount
    as a "normal" (global) variable as in the C++ version.

    [*]Possibly the CoCreateInstance call: Why are the first, forth,
    and fifth parameters, pointers and in the C++ version only the
    fifth one is? If you remove the addrs assembly error occurs...


    ---------------------------------------------------------------------------------

    The changes above wouldn't break the code to set the client
    site would it? It looks to me that there are now two ways to
    write that same code...
Posted on 2001-08-24 08:53:02 by Xtreme
Xtreme,

to answer your questions:

1. No. Important is the number of parameters.
2. For the first step we can live without them
3. CoCreateInstance works definitely, this is no problem

Currently your modified program does not crash any more, it shows a "blank" page. QueryInterface works. 2 additional errors I have found so far are:

a. IOleInPlaceSite inherits from IOleWindow, not IUnknown. That is you must include GetWindow and ContextSensitiveHelp in the vtable.

b. IsEqualGUID is a function from OLE32.LIB. Better use this function than implement your own version. For your own version does not save esi and edi registers.

japheth
Posted on 2001-08-24 14:02:09 by japheth
Japeth,

I'm looking into your last post over the weekend...

Thank You!
Posted on 2001-08-24 14:17:47 by Xtreme
Xtreme,

I have got it to work now.

Note:

- I have put your files together into one file (since without that VC could not display source code)

- I had no definition for IWebBrowser2 available, so I just included the minimum of IWebBrowser interface

- the path to frames.htm is hard coded in browser.asm

- changing of client area isnt implemented yet


It is a very interesting project. Next step is to implement event sinks (support IConnectionPointContainer).

japheth
Posted on 2001-08-24 15:47:38 by japheth
Japheth,

Only one problem Assembler can't find IWebBrowser_Navigate
at line 547....

I look at it at home as well as connectionpoint....

THANKS!
Posted on 2001-08-24 16:12:24 by Xtreme