Getting More Out of Your Browser Control - Part II
by
, 13-Mar-2011 at 05:41 AM (10018 Views)
In the first blog I told you how to connect to the HTML document object inside your Microsoft Internet Explorer browser object. How you can dynamically load a string holding a HTML document structure. In this blog I will extend this a bit.
Let's go back to the Did You Know dialog in DataBase Explorer and look what extras we can learn from there.
Context Menu
If you bring up that dialog and you right click the browser control you will notice you cannot get to the source code of the HTML document (view source). There are two reasons for that. First the HTML is dynamically constructed and this means that the browser control does not have a source but more important we override the context menu with one coded in Visual DataFlex. What do you have to do for that?
First we need to tell the browser control not to show a context menu at all. You can do that by addingto the body element of the original document that we create. So the data to be loaded should be changed from:HTML Code:oncontextmenu="return false;
to:HTML Code:<html><body><p>This is a test</p></body></html>I wanted to mark the addition in red again but inside a HTML wrapper tag vBulletin apparently won't let you do that.HTML Code:<html><body oncontextmenu="return false;<p>This is a test</p></body></html>
Now we have cancelled the original floating menu we can add our own code. BTW, if you do not cancel the built in context menu operation you would get two, one from yourself and one from the browser, very confusing for the end-user I would say. To add our own context menu we grab the OnComoncontextmenu event in the cComHTMLDocument object. So change the oHTMLDocument object to:
The next step is to create a context menu object in Visual DataFlex. You can do this by simply create an object from the Visual DataFlex Studio class palette. Let us see what is behind the Copy Text menu item in the context menu of Database Explorer's Did You Know dialog. While the real floating / context menu contains more options the source code we now look at would be:Code:Object oHTMLDocument is a cComHTMLDocument Procedure OnComoncontextmenu Send Popup of oContextMenu End_Procedure End_Object
Pretty standard Visual DataFlex code, right? But if you look at the Microsoft HTML classes you won't find a CopyText function, so we need to write this ourselves. What exactly do we want to copy? All information of the information from a particular node? Let's say we want to copy the text from the paragraph element. This means we need to create an object of the cComHTMLParaElement class for this and we need to find the paragraph element in the document and then work from there. First create the cComHTMLParaElement object by coding:Code:Object oContextMenu is a cCJContextMenu Object oCopyMenuItem is a cCJMenuItem Set psCaption to "Copy" Set psImage to "ActionCopy.ico" Procedure OnExecute Variant vCommandBarControl Delegate Send CopyText End_Procedure End_Object End_Object
Make the object a sibling of the oHTMLDocument object.Code:Object oHTMLParagraphElement is a cComHTMLParaElement End_Object
The easiest way to find our element is by assigning an ID to the element before loading. So change the
into:HTML Code:<html><body><p>This is a test</p></body></html>
In our CopyText procedure we can find the element with the id "Test". We do this - like in JavaScript - with an GetElementById.HTML Code:<html><body><p id="Test">This is a test</p></body></html>
How do we copy the text to the Windows clipboard? Difficult? No, there is a CLIPBOARD: driver for the standard DataFlex I/O commands (Direct_Input / Direct_Output). So add the following code to the CopyText method.Code:Procedure CopyText Variant vDocument vElement String sText Get ComDocument to vDocument Set pvComObject of oHTMLDocument to vDocument Get ComGetElementById of oHTMLDocument "Test" to vElement If (not (IsNullComObject (vElement))) Begin Set pvComObject of oHTMLParagraphElement to vElement Get ComInnerText of oHTMLParagraphElement to sText End End_Procedure
Of course do not forget to declare the variable iChannel.Code:Move (Seq_New_Channel ()) to iChannel If (iChannel <> DF_SEQ_CHANNEL_NOT_AVAILABLE) Begin Direct_Output channel iChannel "CLIPBOARD:" Write channel iChannel sText Close_Output channel iChannel Send Seq_Release_Channel iChannel End
This finishes the second blog about Getting More Out of Your Browser Control. I have nothing ready yet but I might continue with another blog in the future about this subject. If you have wishes for extensions post a comment.