Access the HTML source code in the webbrowser control directly
Huazhong Normal University
Lu Xiahai
---- In order to display HTML documents in its own procedure, we generally use an ActiveX control TWEBBRowser that comes with IE (Internet Explorer IE). This control uses the same kernel as IE, powerful, starting from Delphi5, formally getting support from Inprise, replacing the original THTML control, becoming the preferred control of the HTML document in Delphi.
---- But in the actual programming process, I found that this control provides a lot of restrictions, such as browsing of the HTML document, can only be implemented by specifying the URL or file name, can not read and write directly like the THTML control in the past HTML source. So if the program dynamically generates a HTML text, you must write the text content first to a temporary file, then pass the file name of this file to the WebBrowser control, implement display. Walking this detachment makes the program response speed, and it is easy to leave some "garbage" (temporary document).
---- After investigating some programs that use the WebBBrowser control, I found most programs, such as the famous domestic software Foxmail, is the way to deliver HTML documents through temporary files; but some foreign software, such as MS own Outlook Express does not exist, because it does not need to generate temporary files, the display speed of the HTML document is significantly more than Foxmail.
---- To this end, I check out some relevant information, and finally find the way to directly access the HTML source code directly in the WebBrowser control with the help of netizens. Always thank the netizen Anglefalls on BBS (BBS.WHNET.EDU.CN) to provide clues.
---- In fact, the Document object in the webbrowser control provides an IPERSISTREAMINIT interface. Through this interface, we can easily implement read and write to the HTML source code.
---- The following is the definition and description of the IPersistStreaminit interface:
{IPERSISTREAM Interface}
{$ Externalsym ipersistStream}
IPERSISTREAM = Interface (IPERSIST)
['{00000109-0000-0000-c000-000000000046}']
Function isdirty: hResult; stdcall;
/ / Whether the last storage is modified
Function Load (const stm: istream): hResult; stdcall;
// Load from the stream
Function Save (Const Stm: istream;
FCLEARDIRTY: BOOL): HRESULT; stdcall;
/ / Save the flow
Function GetSizeMax (Out Cbsize: LargeInt):
HRESULT; stdcall; // get the size of the required saving
END;
{IpersistStreaminit Interface}
{$ Externalsym ipersiststreaminit}
IPERSISTREAMINIT = Interface (IPERSISTREAM)
[{7FD52380-4e07-101b-ae2d-08002b2ec713} ']
Function initnew: hResult; stdcall; // initialization
END;
First implement it, because this is the most urgent requirement:
Procedure Sethtml (Const WebBrowser: TWEBBROWSER; Const HTML: String);
VAR
Stream: istream;
HHTMLTEXT: HGLOBAL;
PSI: IPERSISTREAMINIT;
Begin
IF NOT ASSIGNED (WebBrowser.document).
HHTMLTEXT: = Globalalloc (GPTR, Length (HTML) 1);
IF 0 = HHTMLText The RaiselastWin32error;
CopyMemory (Pointer (HHTMLText),
PCHAR (HTML), Length (HTML);
Olecheck (CreateStreamonhglobal
(HHTMLTEXT, TRUE, STREAM);
Try
Olecheck (WebBrowser.Document.
QueryInterface (IPERSISTREAMINIT, PSI);
Try
Olecheck (psi.initnew);
Olecheck (psi.load (stream));
Finally
PSI: = NIL;
END;
Finally
Stream: = nil;
END;
END;
- One memory will copy the HTML source code that needs to be displayed. This is because the next step is required to create a stream that the WebBrowser control can read. The parameter gptr of the GlobalLoc function indicates that a fixed memory area that needs to be assigned. If the assignment fails, it returns 0, then triggers an exception via the RaiseLastWin32ELOR function, prompting the user; then use the CreateStreamOnhglobal function to establish a stream based on the global heap memory block The second parameter is automatically released when it is released when TRUE is released. If the establishment of success, this flow and the in-memory block just built are shared with the same memory area. Then, use the WebBrowser.Document.QueryInterface function to create an IPersistStreaminit interface. Then you can use this interface directly, psi.initnew initialize the status; psi.load (stream) is loaded from the stream into the HTML source code.
--- Here, the HTML source code specified by the HTML parameter is displayed in the control specified by the webbrowser parameter.
---- It is worth noting that each function called for the COM interface, that is, those who return type HRESULT must be packaged in Olecheck, because a COM interface operation that does not check the return state is too dangerous; The release of the interface, although Delphi can be complete in the background, but as a good programming habit, it should also be explicitly manually released, and the release simply sets the interface to NIL.
---- Next to read the HTML source code:
Function gethtml (Const WebBrowser:
TWEBBROWSER: STRING;
Const
Bufsize = $ 10000;
VAR
SIZE: INT64;
Stream: istream;
HHTMLTEXT: HGLOBAL;
PSI: IPERSISTREAMINIT;
Begin
IF NOT ASSIGNED (WebBrowser.document).
OLECHECK (WebBrowser.Document.Queryinterface (IPersistStreaminit, PSI);
Try
//Olecheck(psi.getsizemax(size);
HHTMLTEXT: = GlobalAlloc (GPTR, BUFSIZE);
IF 0 = HHTMLText The RaiselastWin32error;
Olecheck (CreateStreamonhglobal (HHTMLText,
True, stream);
Try
Olecheck (psi.save (stream, false);
Size: = Strlen (Pchar (HHTMLText));
SetLENGTH (RESULT, SIZE);
CopyMemory (Pchar (Result), Pointer (HHTMLText),
Size);
Finally
Stream: = nil;
END;
Finally
PSI: = NIL;
END;
END;
---- This function has a parameter webbrowser specifies that the HTML source code is read from that control, returns a string for the HTML source code in this control. First, you should first check if the webbrowser.document object is valid, then quit; then get the IPersistStreaminit interface; then get the size of the HTML source: I should use the getSizemax function of the IPersistStreaminit interface, but in my machine, this function range value 0, invalid. Therefore, you can only define a sufficiently large buffer, such as buffsize = $ 1000 bytes (note that this buffer should be large enough); then allocate the global heap memory block, build stream, and then write HTML text. Because this HTML text is the string ending in # 0 in the stream, you can use Size: = Strlen (Pchar (HHTMLText)) to get the actual length with setLength (Result, size); set the return string length of HTML source Length, final replication string to return in string.
--- Here, the two functions required to directly access the HTML source code in the WebBrowser control are completely parsed.
---- But when you need to pay attention, before using these two functions, it is best to initialize the webbrowser.document object. A function is provided below, and the webbrowser.document object initialization is initialized by displaying a blank page.
Procedure Showblankpage (WebBrowser:
TWEBBROWSER);
VAR
URL: Olevariant;
Begin
URL: = 'About: blank';
WebBrowser.naviGate2 (URL);
END;
---- It is recommended to call this function in the FormCreate event you have a webbrowser control, initialize the webbrowser.document object.
---- This article is debugged in the Win NT Delphi 5 environment
---- Reference: MSDN
---- Special Thank: Baiyun Huanghe BBS (bbs.Whnet.edu.cn) Netizen Anglefalls