News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Webbrowser control problem

Started by minor28, May 07, 2013, 06:00:22 AM

Previous topic - Next topic

minor28


I am using the iefram.dll webbrowser control. I can navigate to different url with the IWebBrowser2.Navigate2 function. Even the "about:blank" is working. Now I want to write to the document from memory.

With the "about:blank" document I retrieve the document object with IWebBrowser2.Document function.

Now my problem starts.

MSDN say that IHTMLDocument.Write parameter should be a safe array.

pHtmlText is a BSTR


invoke SafeArrayCreateVector,VT_VARIANT,0,1
mov pSafeArray,eax
invoke SafeArrayAccessData,pSafeArray,addr pData
mov ebx,pData
mov word ptr [ebx].VARIANT.vt,VT_BSTR
mov eax,pHtmlText
mov dword ptr [ebx].VARIANT.bstrVal,eax
invoke SafeArrayUnaccessData,pSafeArray

invoke VariantInit,addr var1
mov var1.vt,VT_SAFEARRAY
mov eax,pSafeArray
mov var1.parray,eax

IHTMLDocument.Write(addr var1)


This will be a blank page totally empty not even <html></html>. Changing the parameter to pSafeArray result in "NULL" on the page. As I can see the safe array has no NULL string.

Now I use the BSTR as parameter


invoke VariantInit,addr var1
mov var1.vt,VT_BSTR
mov eax,pHtmlText
mov var1.bstrVal,eax

IHTMLDocument.Write(addr var1)


This will aleast give a result. If the html code i a short text strings it works well but if it is a longer htmlcode the text string is truncated and it is also in some extent not written as I wrote it.

Any idea how to solve this problem

Antariy

How defined pHtmlText variable?
BSTR datatype uses a DWORD with a length of the string, which lies 4 bytes above the pointer to the string.
I.e., proper pre-initialized BSTR should look like:

.data

dd sizeof pHtmlText
pHtmlText dw "<","h","t","m","l" ... and so on ... ; dw is because BSTR is usually Unicode string


minor28

pHtmlText is a pointer to a unicode string preseeded whith the length of the string, i.e. a BSTR string. I'm sure of that.

qWord

the method write() expects the type SAFEARRAY* whereas your code passes a VARIANTARG* -> you might try it with using pSafeArray instead.
MREAL macros - when you need floating point arithmetic while assembling!

minor28


invoke SafeArrayCreateVector,VT_VARIANT,0,1
mov pSafeArray,eax
mov ebx,eax
mov word ptr [ebx].SAFEARRAY.fFeatures,100h ;FADF_BSTR
invoke SafeArrayAccessData,pSafeArray,addr pData
mov ebx,pData
mov word ptr [ebx].VARIANT.vt,VT_BSTR
mov eax,pHtmlText
mov dword ptr [ebx].VARIANT.bstrVal,eax
invoke SafeArrayUnaccessData,pSafeArray

lea edi,dp ;dispparams sturcture
mov eax,pSafeArray
mov dword ptr [edi].DISPPARAMS.rgvarg,eax
mov dispidNamed,DISPID_VALUE
lea eax,dispidNamed ;default handle!
mov dword ptr [edi].DISPPARAMS.rgdispidNamedArgs,eax
mov dword ptr [edi].DISPPARAMS.cArgs,1
mov dword ptr [edi].DISPPARAMS.cNamedArgs,0

invoke VariantInit,addr RetVal

push 0
push 0
lea eax,RetValue
push eax
lea eax,dp
push eax
push DISPATCH_METHOD
push lcid
push offset NullCLSCID
push memid

mov eax,ppHtmlDocument
mov edx,dword ptr [eax]
push ppHtmlDocument
add edx,offs ;offs = IDispatch.Invoke
call dword ptr [edx]


No error in execution. Result page showing "null" with page code = "null" nothing more.

If I make a temporary file and navigate to this file correct page is visible.

minor28

My project is to calculate the sun's position at any selected time and at any selected
location on earth. I use Google maps and Google timezone api to select locations. There
are some drawings with Gdip flat apis. The ClientSite of the webbrowser control was a
tricky item to solve. I have written more clientsite methods than is used i this project.

For those who are interested the application can be downloaded and you can read the code
here  (http://minor28.divdev.se/)

How hard I tried I could not get the Write and Close methods to write to the about:blank
document. By contrast, I could create a temporary file to navigate to. The file could be
deleted after the page load was completed. A solution without creating a temporary file
was to stream text using the interface IPersistStreamInit. This became the solution.

;Implement IPersistStreamInit on the document to init stream persistance
invoke Set_Interface,ppIHTMLDocument2,WSTR("{7FD52380-4E07-101B-AE2D-08002B2EC713}"),
1,addr ppIPersistStreamInit

;Create the stream from resource html code
invoke FindResource,hInstance,RES_MAP,RT_RCDATA
.if eax
mov hResinfo,eax
invoke LoadResource,hInstance,hResinfo
.if eax
push esi ;preserve
mov esi,eax
push eax
invoke SizeofResource,hInstance,hResinfo
invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_NODISCARD,eax
.if eax
push edi ;preserve
mov hMem,eax
invoke GlobalLock,eax
mov edi,eax
push edi
xor ecx,ecx
.while byte ptr [esi]!=0
movsb
inc ecx
.endw
pop edi
invoke CreateStreamOnHGlobal,edi,TRUE,addr ppIStream
.if eax==S_OK
;Load the stream
invoke RunInterfaceMethod,ppIPersistStreamInit,IPersistStreamInit.Load,
1,ppIStream
.if eax==S_OK
;Make the browser connectable
invoke AdviseEvent,ppIWebBrowser2,offset DIID_DWebBrowserEvents2
invoke Release_Object,ppIPersistStreamInit
.endif
invoke Release_Object,ppIStream
.endif
invoke GlobalFree,hMem
pop edi ;restore
.endif
pop esi ;restore
.endif
.endif



dedndave

for older versions of internet explorer (and other browsers, i suspect), blank.html was a real physical file
newer versions, however, seem to have eliminated the file and use internal data
i am guessing it was for security reasons   :P