You can use WebBrowser to download, but do not know how to save to file. The real source code access WebBrowser, returns the original format code, the. uses ActiveX; function WB_SaveHTMLCode(WebBrowser: TWebBrowser; const FileName: TFileName): Boolean; var ps: IPersistStreamInit; fs: TFileStream;. uses UrlMon; function DownloadFile(SourceFile, DestFile: string): Boolean; begin try. Result:= UrlDownloadToFile(nil, PChar(SourceFile), PChar(DestFile), 0.
|Published (Last):||25 December 2016|
|PDF File Size:||3.69 Mb|
|ePub File Size:||14.22 Mb|
|Price:||Free* [*Free Regsitration Required]|
I use the TWebBrowser control quite a lot. Navigate you probably know what I mean. You wouldn’t have to do such a thing with a native Delphi control such as a TMemo — you would simply access a relevant property like TMemo. Lines or use a method like TMemo. You can also do this with TWebBrowserbut its not straightforward — not very “Delphi” — you have to query and manipulate interfaces and all sorts of stuff.
It’s all so very COM! So, I decided to create a wrapper class for TWebBrowser that makes navigating, loading and saving a whole lot easier and more intuitive. This article walks through the development of that class and examines some of the key techniques for working with TWebBrowser along the way.
A word of caution before we get started. The code I’ll present here is for illustration purposes only. Don’t expect it to be perfect for production code, although you should be able to use it as a basis.
How to save the page displayed in a TWebBrowser to a single page .mht web archive file
Please feel free to take the core unit from the demo and modify, specialise or generalise it for your own purposes. The approach we will take is to develop a wrapper class for TWebBrowser rather than derive a new class from it.
Let’s first decide of the main functions of the web browser we want to be able to access easily — these will be our requirements for the wrapper class. Here’s the list I drew up:. This first stage won’t worry about Unicode support other than that needed to make the code compile and work with Delphi and later. The first savee to notice is the WebBrowser property that enables access to the wrapped control. The public methods fall naturally into several groups and, rather than explaining the purpose twdbbrowser each method now, we will look at them in groups.
The protected “helper” methods will be discussed along with the public methods they service. The constructor is very simple — it just stores a reference to the TWebBrowser control that the object is wrapping. This control reference is passed as a parameter to the constructor:. This method essentially falls into two parts. Firstly we decide whether to use the twfbbrowser cache to access the document. The decision is based on whether the document is stored locally or is on the internet.
We simply check the start of the URL string for some known local protocols etc. It would be a simple matter to adapt the method by adding a default parameter to let the user of the code specify what if any caching should take place this is left as an exercise.
The final part of the routine simply uses the browser object’s Navigate method to load the resource into the document. We then go into a loop and wait for the document to load completely. The local Pause procedure does a busy wait, polling the message queue for about 5ms at a time. Now let us review the specialised navigation methods. The simplest of these is the NagivateToLocalFile method. This method simply checks if the file exists and, if so, prefixes the given file name with the file: If the file doesn’t exist no action is taken.
A boolean value indicating whether the file exists is returned.
How to load and save documents in TWebBrowser in a Delphi-like way
You may prefer to modify the method to raise an exception when the file does not exist. We discussed this protocol in article 10 where we also developed some functions to return res: We will re-use these functions later.
Two overloaded methods are provided. Both methods create the required URL for a given module, twrbbrowser name and an optional resource type. The overloaded methods vary in the way the module is described. The first method accepts twebbrwser handle of a loaded module pass HInstance to access the current program.
The second method is simply passed a module name as a string. If the resource type parameter is omitted then it is left out of the URL — the res: Here are the methods:. The implementation of these functions is described in article In both cases we could improve the methods by checking that the required resources exist and raising an exception or returning false if not.
This swve left as an exercise hint: Let’s first look at the stream and string methods, which are very similar:. As can be seen this is all quite straightforward if you’re used to using TStream s.
The main thing to note here is that we must ensure there is a document present in TWebBrowser since, as we will see in a moment, we need it in order to load the delphl from the stream. We do this by navigating to the special about: Once we have our blank document we load the stream into it using InternalLoadDocumentFromStreamwhich is defined below:.
And this is where it gets more complicated — for twebbriwser first time we have to mess around with the COM stuff. We check that the web browser control’s document object is available and bail out if not.
We then check tebbrowser see if the document supports the IPersistStreamInit interface, getting a reference to the supporting object. IPersistStreamInit is used to effectively “clear” the document object using the interface’s InitNew method. If this succeeds we finally load the relphi content into the document depphi calling the IPersistStreamInit. Load accepts a stream object, but the stream it expects is a COM one that must support the IStream interface.
Since TStream does not natively support this interface, we have to find some way to provide it. TStreamAdapter from Delphi’s Classes unit comes to the rescue here — this object implements IStream and translates IStream ‘s method calls into equivalent calls onto the TStream object that it wraps.
We create the needed TStreamAdapter object by passing a reference to our stream in its constructor. Finally, we pass the adpated stream to IPersistStreamInit.
Load, and we’re done.
If you’re wandering why we don’t free StreamAdapter and PersistStreamInit it’s because they are both interfaced objects and will be automatically destroyed at the end of the method by Delphi’s built in interface reference counting. Note that even though the stream adapter class is freed, the underlying TStream object continues to exist, which is what we want. Note that the browser control interprets the encoding of the stream sets the document’s character set accordingly.
However, the character set can also be specified in HTML code. There are three methods that are used to save savw document’s code. They complement the three LoadXXX methods as follows:. Their operation is quite simple and needs little explanation:. The only thing of note in the above methods is the use of TStringStream ‘s DataString property to read out the completed string after writing to the stream. The SaveToStream method follows.
It interacts with the browser control twebbrwser save the whole document to a stream. Note twebbrowsfr, like in InternalLoadDocumentFromStreamwe again try to get the web browser document’s IPersistStreamInit interface and then use its Save method to write the document to the stream.
Note that the browser control writes the stream in the correct character set for the document. Since the browser control supports different character encodings we need to add support for this to our code. For much of this we’re going to rely on the encoding support built into Delphi and later, so get ready for some conditionally defined code.
When we discussed requirements we decided we needed to be able to specify an encoding when writing to files and streams and when reading from a string. The second requirement was to provide access to the encoding used for the browser control’s current document. Taking these into account the definition of our TWebBrowserWrapper class becomes:. We provide access to the browser’s current document encoding via the read only Encoding property which has a read accessor method named GetDocumentEncodingdefined in the following listing.
To get the document encoding we need to examine the structure of the stream that is generated when then the document is saved. We first record the default encoding to return if we can’t examine the document for any reason.
Once we have a reference to the current document in Doc we create a memory stream object and save the browser content into it by calling InternalSaveDocumentToStream.
The resulting stream is then examined by Mauricio Julio’s GetStreamEncoding function to get the encoding.
Listing 14 shows the implementation GetStreamEncoding. This routine simply copies the provided stream into a TBytes array then uses the GetBufferEncoding class method of TEncoding to determine the encoding. As noted already we will provide a new overloaded version of LoadFromString that takes a TEncoding parameter that determines the encoding that will be used to load the string containing the HTML.
We will also need to re-implement the original LoadFromString method. Twehbrowser the new code:. The first thing twebbrowsee note is that, on non-Unicode compilers, the original version of LoadFromString is unchanged. However the Unicode version now calls the new overloaded version of the method, passing the default encoding in the Encoding parameter.
The new, Gwebbrowser only, overloaded method first writes the the string to a temporary memory stream, encoded according to the Encoding parameter.
: save all TWebbrowser Frame Sources?
The stream is prefixed by any byte order mark required by the encoding. Once we have the stream we simply call the existing LoadFromStream method to load the stream into the document. StringToStreamBOMdescribed above, first converts the string into a byte array according the required encoding.
It then writes any required byte order mark to the stream stored in the Preamble variable followed by the byte array. In addition to providing new overloaded versions of SaveToStream and SaveToFile we must re-implement SaveToString when compiling with Unicode compilers to take account of the browser document’s encoding.
We will first tewbbrowser at the revised SaveToString method before discussing the new overloaded methods.