Original: "Four" chrome core browser based on. NET development
One:
Last week went to Beijing on business, to the National Grid projects to do the architectural plan, every day very late to sleep, customers over the Vice-President also so desperately work.
Tired of not, directly resulting in the fourth article did not send out on time.
Hope to learn an open mind 1, small knight and so attention to my friends forgive me.
Two:
In this article, we mainly implement the following three features:
Browser Address bar , browser window size change , browser download file
To achieve these three functions, we have created a new project,
There is no change in the contents of the Program.cs file;
There is no change in the contents of the DLL folder;
The reference to the resource, the configuration of the Assembly, did not make any changes;
Three:
We create a BS folder in the solution that puts the browser-related classes in this folder.
First, create a class called Bsdownloadhandler in this folder.
As the name implies, this class is created for downloading files.
If you want to implement the download file, first let this class inherit Cefdownloadhandler
Then rewrite the parent class's Onbeforedownload and ondownloadupdated two methods
The rewritten code is as follows:
protected Override voidOnbeforedownload (Cefbrowser Browser, Cefdownloaditem Downloaditem,stringSuggestedname, Cefbeforedownloadcallback callback) {callback. Continue (string. Empty,true); } protected Override voidondownloadupdated (Cefbrowser browser, Cefdownloaditem Downloaditem, Cefdownloaditemcallback callback) { if(downloaditem.iscomplete) {MessageBox.Show ("Download Successful"); if(Browser. Ispopup &&!Browser. hasdocument) {browser. GetHost (). Parentwindowwillclose (); Browser. GetHost (). CloseBrowser (); } } }
The Onbeforedownload method is called before the browser starts to download the file, and CEF masks all file download events by default
If you want CEF to handle download events, call the continue event of the callback parameter.
The Suggested_name parameter is the recommended name for the downloaded file, which is the contents of the File Name text box after the file dialog box is saved.
--------------------------
Ondownloadupdated method, CEF calls this method several times during the download of the file, not only after the download is complete.
If you want to terminate the download, you can also call the Cancel method of the callback parameter
--------------------------
Downloaditem is an instance of the type that describes the download file.
He has a series of attributes,
Includes: whether completed, canceled, current speed, percent completed, number of bits completed, number of bits in total, start time, end time, etc.
Do not attempt to refer to this instance in addition to the above two methods.
----------------------------
Because there are many ways to download files in the browser, it is possible to open a path by window.open (JS) to download the file
At this point, we have to close the open window, (CEF will not automatically help us to turn off such a window), so after the completion of the download, the following two lines of code are executed:
if (Browser. Ispopup &&! Browser. Hasdocument) { browser. GetHost (). Parentwindowwillclose (); Browser. GetHost (). CloseBrowser (); }
Four:
In order to make the browser's window size change as the container's window size changes.
We have to know when the browser's window handle was created successfully and when it was added to the parent window.
In the previous article, we mentioned that the Cefbrowserhost.createbrowser method is asynchronous.
Let's think of some way to get the handle to the browser window that was created after the method was executed successfully.
First, we'll create a class named Bslifespanhandler within the BS folder.
This class inherits from Ceflifespanhandler, and we override the Onaftercreated method in this class
The code for the entire class is as follows:
Public class Bslifespanhandler:ceflifespanhandler { private bsclient bclient; Public Bslifespanhandler (bsclient BC) { = BC; } protected Override void onaftercreated (Xilium.CefGlue.CefBrowser browser) { base. onaftercreated (browser); bclient.created (browser); } }
To create an instance of this class, you must pass in an instance of Bsclient, about the contents of bsclient, we'll talk about it later.
There are many ways to overload the base class Ceflifespanhandler.
Includes: Event before popup window , event after successful creation of browser window, event to execute modal window, event before closing window
(although this is called an event, it is actually a method, except that CEF automatically calls these methods)
We have rewritten the Onaftercreated method in this class (the event that the browser window was created successfully),
In this method, we call the created method of the Bsclient instance,
and pass the browser instance as a parameter to this method
The browser here is actually the browser core that we created, which allows you to get the browser's window handle.
Five:
In our previous article, we created a browserclient class that inherits from Cefclient.
But we did not give any implementations of this class, but when we called the Cefbrowserhost.createbrowser method, we passed an instance of the class.
Now, let's put this class in the BS folder and rename it to Bsclient, adding the following implementation code for this class:
Public classbsclient:cefclient { Public EventEventHandler oncreated; Private ReadOnlyCeflifespanhandler Lifespanhandler; Private ReadOnlyCefdownloadhandler Downloadhandler; Publicbsclient () {Lifespanhandler=NewBslifespanhandler ( This); Downloadhandler=NewBsdownloadhandler (); } protected OverrideCeflifespanhandler Getlifespanhandler () {returnLifespanhandler; } protected OverrideCefdownloadhandler Getdownloadhandler () {returnDownloadhandler; } Public voidCreated (Cefbrowser bs) {if(oncreated! =NULL) {oncreated (BS, Eventargs.empty); } } }
In this class, we rewrite the Getlifespanhandler and Getdownloadhandler methods,
In this way, the Bslifespanhandler and Bsdownloadhandler we created earlier will make the most of it.
You can also rewrite a lot of methods here,
For example:Getcontextmenuhandler (right-click menu handle), Getdialoghandler (dialog handle) Getkeyboardhandler (keyboard handle), etc.
In this class we also expose a oncreated event, and the created method invokes the event.
This method is called in the Bslifespanhandler class.
This means that when the browser is created, the Oncreated event is triggered.
Six:
We create a class under the BS folder Bsctl
This class is our browser control,
Let's take a look at this class's only constructor:
Publicbsctl (Control ctl) {parent=ctl; varCWI =cefwindowinfo.create (); Cwi. Setaschild (parent. Handle,NewCefrectangle (0,0, parent. Width, parent. Height)); varBC =Newbsclient (); Bc. Oncreated+=bc_oncreated; varBS =Newcefbrowsersettings () {}; Cefbrowserhost.createbrowser (CWI, BC, BS,"Http://www.cnblogs.com/liulun"); Parent. SizeChanged+=parent_sizechanged; }
You will find that several lines of core code in the previous article have moved here.
The parameter CTL for the constructor, which is a Windows control, typically a container control such as a panel,
The browser window we created will be rendered within this container control
At the same time, we register the SizeChanged event for this container control
The Oncreated event was also registered for Bsclient.
When we created the default browser, we specified its default home page (that's my blog)
If you don't want to do this, you can specify it as: About:blank
----------------------------
Let's take a look at the implementation code for these two events
voidBc_oncreated (Objectsender, EventArgs e) {BS=(cefbrowser) sender; varHandle =BS. GetHost (). Getwindowhandle (); Resizewindow (handle,parent. Width,parent. Height); } voidParent_sizechanged (Objectsender, EventArgs e) { if(bs! =NULL) { varHandle =BS. GetHost (). Getwindowhandle (); Resizewindow (handle, parent. Width, parent. Height); } }
In the event of a successful browser creation, we save the instance of the browser as a private property
He is a core object and will be used in many places later.
We pass BS. GetHost (). Getwindowhandle () to obtain a handle to the browser window.
With this handle, we can reset the size of the browser window so that he changes with the size of the main form.
--------------------------------
Here's a look at the code for the Resizewindow method:
[DllImport ("user32.dll")] [return: MarshalAs (unmanagedtype.bool)] Public Static extern BOOLSetWindowPos (IntPtr hWnd, IntPtr Hwndinsertafter,intXintYintCxintCyUINTuflags); Private voidResizewindow (INTPTR handle,intWidthintheight) { if(Handle! =IntPtr.Zero) {nativemethod.setwindowpos (handle, IntPtr.Zero,0,0, width, height,0x0002|0x0004 ); } }
In the Resizewindow method, you set the location and size of the browser window by invoking the method of the Windows API in PInvoke mode
where 0x0002 equivalent to swp_nomove;0x0004 equivalent to Swp_nozorder
---------------------------
In this class, there is also a method, the code is as follows:
Public void Loadurl (string url) { bs. Getmainframe (). Loadurl (URL); }
This method is responsible for switching the address of the browser
Seven:
Now let's design the main window.
Some of the necessary layout codes are as follows, not much to explain:
This. Addresscontainer.anchor = ((System.Windows.Forms.AnchorStyles) (((System.Windows.Forms.AnchorStyles.Top |System.Windows.Forms.AnchorStyles.Left) This. Gobtn.anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top |( System.Windows.Forms.AnchorStyles.Right))); This. Addresstb.anchor = ((System.Windows.Forms.AnchorStyles) (((System.Windows.Forms.AnchorStyles.Top |System.Windows.Forms.AnchorStyles.Left) This. Browsercontainer.anchor = ((System.Windows.Forms.AnchorStyles) (((System.Windows.Forms.AnchorStyles.Top |System.Windows.Forms.AnchorStyles.Bottom) This. Statuscontainer.anchor = ((System.Windows.Forms.AnchorStyles) (((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
------------------------------------------
After a series of previous work, the Code of our main window has been streamlined a lot
Public Partial classDemo:form {BSCTL bs; PublicDemo () {InitializeComponent (); This. Name ="Cefbrowser"; This. Text ="The simplest implementation"; } Private voidCefbrowser_load (Objectsender, EventArgs e) {BS=NewBsctl (Browsercontainer); } Private voidGobtn_click (Objectsender, EventArgs e) { if(!string. Isnullorwhitespace (Addresstb.text)) {BS. Loadurl (Addresstb.text); } } }
After the window was loaded successfully, we created an instance of the browser (the browser container was passed to the constructor when it was created).
When you click the Go button, you switch the address of the browser.
-------------------------------------------------
The final effect is as follows (the size of the browser window will vary depending on the size of the main window)
SOURCE Download:
Http://files.cnblogs.com/liulun/CefDemo2.zip
Developing Chrome Core Browser "four" based on. Net