Skip to content

Commit aa5d77e

Browse files
committed
Implement more basic functionality
1 parent 5166dba commit aa5d77e

8 files changed

Lines changed: 86 additions & 163 deletions

File tree

CefSharp.OutOfProcess.BrowserProcess/BrowserProcessHandler.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ protected override void OnContextInitialized()
4343
});
4444
});
4545

46+
_jsonRpc.AddLocalRpcMethod("SendDevToolsMessage", (Action<int, string>)delegate (int browserId, string message)
47+
{
48+
_ = CefThread.ExecuteOnUiThread(() =>
49+
{
50+
var browser = _browsers.FirstOrDefault(x => x.Id == browserId);
51+
52+
browser?.GetBrowserHost().SendDevToolsMessage(message);
53+
54+
return true;
55+
});
56+
});
57+
4658
_jsonRpc.AddLocalRpcMethod("CloseHost", (Action)delegate ()
4759
{
4860
_ = CefThread.ExecuteOnUiThread(() =>

CefSharp.OutOfProcess.Core/IChromiumWebBrowser.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ public interface IChromiumWebBrowser : IDisposable
102102
/// </summary>
103103
event EventHandler<LifecycleEventArgs> LifecycleEvent;
104104

105+
/// <summary>
106+
/// Fired when the <see cref="DevToolsContext"/> is available
107+
/// </summary>
108+
event EventHandler DevToolsContextAvailable;
109+
105110
/// <summary>
106111
/// Raised when a <see cref="NetworkResponse"/> is received.
107112
/// </summary>
@@ -127,6 +132,11 @@ public interface IChromiumWebBrowser : IDisposable
127132
/// </example>
128133
event EventHandler<ResponseCreatedEventArgs> NetworkResponse;
129134

135+
/// <summary>
136+
/// DevTools Context
137+
/// </summary>
138+
IDevToolsContext DevToolsContext { get; }
139+
130140
/// <summary>
131141
/// Loads the specified <paramref name="url"/> in the Main Frame.
132142
/// </summary>

CefSharp.OutOfProcess.WinForms.Example/BrowserForm.cs

Lines changed: 49 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
using System;
66
using System.ComponentModel;
7+
using System.Diagnostics;
78
using System.IO;
9+
using System.Reflection.Metadata;
810
using System.Runtime.InteropServices;
911
using System.Windows.Forms;
1012

@@ -236,23 +238,25 @@ private void DeleteMenuItemClick(object sender, EventArgs e)
236238
}
237239
}
238240

239-
private void SelectAllMenuItemClick(object sender, EventArgs e)
241+
private async void SelectAllMenuItemClick(object sender, EventArgs e)
240242
{
241243
var control = GetCurrentTabControl();
242244
if (control != null)
243245
{
244-
throw new NotImplementedException();
245-
//control.Browser.SelectAll();
246+
var devtoolsContext = control.Browser.DevToolsContext;
247+
248+
_ = await devtoolsContext.EvaluateExpressionAsync("document.execCommand('selectAll');");
246249
}
247250
}
248251

249-
private void PrintToolStripMenuItemClick(object sender, EventArgs e)
252+
private async void PrintToolStripMenuItemClick(object sender, EventArgs e)
250253
{
251254
var control = GetCurrentTabControl();
252255
if (control != null)
253256
{
254-
throw new NotImplementedException();
255-
//control.Browser.Print();
257+
var devtoolsContext = control.Browser.DevToolsContext;
258+
259+
_ = await devtoolsContext.EvaluateExpressionAsync("window.print()");
256260
}
257261
}
258262

@@ -287,71 +291,42 @@ private async void CloseDevToolsMenuItemClick(object sender, EventArgs e)
287291
}
288292
}
289293

290-
private void ZoomInToolStripMenuItemClick(object sender, EventArgs e)
294+
private async void ZoomInToolStripMenuItemClick(object sender, EventArgs e)
291295
{
292296
var control = GetCurrentTabControl();
293297
if (control != null)
294298
{
295-
throw new NotImplementedException();
299+
var devtoolsContext = control.Browser.DevToolsContext;
296300

297-
//var task = control.Browser.GetZoomLevelAsync();
301+
var currentZoomLevel = await devtoolsContext.EvaluateExpressionAsync<double>("window.devicePixelRatio");
298302

299-
//task.ContinueWith(previous =>
300-
//{
301-
// if (previous.Status == TaskStatus.RanToCompletion)
302-
// {
303-
// var currentLevel = previous.Result;
304-
// control.Browser.SetZoomLevel(currentLevel + ZoomIncrement);
305-
// }
306-
// else
307-
// {
308-
// throw new InvalidOperationException("Unexpected failure of calling CEF->GetZoomLevelAsync", previous.Exception);
309-
// }
310-
//}, TaskContinuationOptions.ExecuteSynchronously);
303+
await devtoolsContext.SetPageScaleFactorAsync(currentZoomLevel + 0.25);
311304
}
312305
}
313306

314-
private void ZoomOutToolStripMenuItemClick(object sender, EventArgs e)
307+
private async void ZoomOutToolStripMenuItemClick(object sender, EventArgs e)
315308
{
316309
var control = GetCurrentTabControl();
317310
if (control != null)
318311
{
319-
throw new NotImplementedException();
320-
//var task = control.Browser.GetZoomLevelAsync();
321-
//task.ContinueWith(previous =>
322-
//{
323-
// if (previous.Status == TaskStatus.RanToCompletion)
324-
// {
325-
// var currentLevel = previous.Result;
326-
// control.Browser.SetZoomLevel(currentLevel - ZoomIncrement);
327-
// }
328-
// else
329-
// {
330-
// throw new InvalidOperationException("Unexpected failure of calling CEF->GetZoomLevelAsync", previous.Exception);
331-
// }
332-
//}, TaskContinuationOptions.ExecuteSynchronously);
312+
var devtoolsContext = control.Browser.DevToolsContext;
313+
314+
var currentZoomLevel = await devtoolsContext.EvaluateExpressionAsync<double>("window.devicePixelRatio");
315+
316+
await devtoolsContext.SetPageScaleFactorAsync(currentZoomLevel - 0.25);
333317
}
334318
}
335319

336-
private void CurrentZoomLevelToolStripMenuItemClick(object sender, EventArgs e)
320+
private async void CurrentZoomLevelToolStripMenuItemClick(object sender, EventArgs e)
337321
{
338322
var control = GetCurrentTabControl();
339323
if (control != null)
340324
{
341-
throw new NotImplementedException();
342-
//var task = control.Browser.GetZoomLevelAsync();
343-
//task.ContinueWith(previous =>
344-
//{
345-
// if (previous.Status == TaskStatus.RanToCompletion)
346-
// {
347-
// var currentLevel = previous.Result;
348-
// MessageBox.Show("Current ZoomLevel: " + currentLevel.ToString());
349-
// }
350-
// else
351-
// {
352-
// MessageBox.Show("Unexpected failure of calling CEF->GetZoomLevelAsync: " + previous.Exception.ToString());
353-
// }
354-
//}, TaskContinuationOptions.HideScheduler);
325+
var devtoolsContext = control.Browser.DevToolsContext;
326+
327+
var currentZoomLevel = await devtoolsContext.EvaluateExpressionAsync<double>("window.devicePixelRatio");
328+
329+
MessageBox.Show("Current ZoomLevel: " + currentZoomLevel.ToString());
355330
}
356331
}
357332

@@ -368,16 +343,18 @@ private async void PrintToPdfToolStripMenuItemClick(object sender, EventArgs e)
368343

369344
if (dialog.ShowDialog() == DialogResult.OK)
370345
{
371-
throw new NotImplementedException();
346+
var devtoolsContext = control.Browser.DevToolsContext;
372347

373-
//if (success)
374-
//{
375-
// MessageBox.Show("Pdf was saved to " + dialog.FileName);
376-
//}
377-
//else
378-
//{
379-
// MessageBox.Show("Unable to save Pdf, check you have write permissions to " + dialog.FileName);
380-
//}
348+
await devtoolsContext.PdfAsync(dialog.FileName);
349+
350+
if (File.Exists(dialog.FileName))
351+
{
352+
MessageBox.Show("Pdf was saved to " + dialog.FileName);
353+
}
354+
else
355+
{
356+
MessageBox.Show("Unable to save Pdf, check you have write permissions to " + dialog.FileName);
357+
}
381358

382359
}
383360

@@ -412,30 +389,21 @@ private async void TakeScreenShotMenuItemClick(object sender, EventArgs e)
412389
return;
413390
}
414391

415-
//var chromiumWebBrowser = (ChromiumWebBrowser)control.Browser;
416-
417-
//var contentSize = await chromiumWebBrowser.GetContentSizeAsync();
392+
var devtoolsContext = control.Browser.DevToolsContext;
418393

419-
////Capture current scrollable area
420-
//var viewPort = new DevTools.Page.Viewport
421-
//{
422-
// Width = contentSize.Width,
423-
// Height = contentSize.Height,
424-
//};
394+
var screenshotPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "CefSharp screenshot" + DateTime.Now.Ticks + ".png");
425395

426-
//var data = await chromiumWebBrowser.CaptureScreenshotAsync(viewPort: viewPort, captureBeyondViewport: true);
396+
await devtoolsContext.ScreenshotAsync(screenshotPath);
427397

428-
//// Make a file to save it to (e.g. C:\Users\[user]\Desktop\CefSharp screenshot.png)
429-
//var screenshotPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "CefSharp screenshot" + DateTime.Now.Ticks + ".png");
430-
431-
//File.WriteAllBytes(screenshotPath, data);
432-
433-
//// Tell Windows to launch the saved image.
434-
//Process.Start(new ProcessStartInfo(screenshotPath)
435-
//{
436-
// // UseShellExecute is false by default on .NET Core.
437-
// UseShellExecute = true
438-
//});
398+
if (File.Exists(screenshotPath))
399+
{
400+
// Tell Windows to launch the saved image.
401+
Process.Start(new ProcessStartInfo(screenshotPath)
402+
{
403+
// UseShellExecute is false by default on .NET Core.
404+
UseShellExecute = true
405+
});
406+
}
439407
}
440408
}
441409
}

CefSharp.OutOfProcess.WinForms.Example/BrowserTabUserControl.Designer.cs

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CefSharp.OutOfProcess.WinForms.Example/BrowserTabUserControl.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public BrowserTabUserControl(OutOfProcessHost outOfProcessHost, string url)
3939
outputLabel.Text = version;
4040
}
4141

42-
private async void OnBrowserNetworkRequestFailed(object sender, Puppeteer.RequestEventArgs args)
42+
private async void OnBrowserNetworkRequestFailed(object sender, Puppeteer.RequestEventArgs args)
4343
{
4444
var request = args.Request;
4545

@@ -68,7 +68,6 @@ protected override void Dispose(bool disposing)
6868

6969
private void OnBrowserConsoleMessage(object sender, Puppeteer.ConsoleEventArgs args)
7070
{
71-
7271
DisplayOutput(string.Format("Line: {0}, Source: {1}, Message: {2}", args.Message.Location.LineNumber, args.Message.Location.URL, args.Message.Text));
7372
}
7473

CefSharp.OutOfProcess.WinForms.Example/BrowserTabUserControl.resx

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
21
<root>
3-
<!--
4-
Microsoft ResX Schema
5-
6-
Version 2.0
7-
8-
The primary goals of this format is to allow a simple XML format
9-
that is mostly human readable. The generation and parsing of the
10-
various data types are done through the TypeConverter classes
11-
associated with the data types.
12-
13-
Example:
14-
15-
... ado.net/XML headers & schema ...
16-
<resheader name="resmimetype">text/microsoft-resx</resheader>
17-
<resheader name="version">2.0</resheader>
18-
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
19-
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
20-
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
21-
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
22-
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
23-
<value>[base64 mime encoded serialized .NET Framework object]</value>
24-
</data>
25-
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
26-
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
27-
<comment>This is a comment</comment>
28-
</data>
29-
30-
There are any number of "resheader" rows that contain simple
31-
name/value pairs.
32-
33-
Each data row contains a name, and value. The row also contains a
34-
type or mimetype. Type corresponds to a .NET class that support
35-
text/value conversion through the TypeConverter architecture.
36-
Classes that don't support this are serialized and stored with the
37-
mimetype set.
38-
39-
The mimetype is used for serialized objects, and tells the
40-
ResXResourceReader how to depersist the object. This is currently not
41-
extensible. For a given mimetype the value must be set accordingly:
42-
43-
Note - application/x-microsoft.net.object.binary.base64 is the format
44-
that the ResXResourceWriter will generate, however the reader can
45-
read any of the formats listed below.
46-
47-
mimetype: application/x-microsoft.net.object.binary.base64
48-
value : The object must be serialized with
49-
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
50-
: and then encoded with base64 encoding.
51-
52-
mimetype: application/x-microsoft.net.object.soap.base64
53-
value : The object must be serialized with
54-
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
55-
: and then encoded with base64 encoding.
56-
57-
mimetype: application/x-microsoft.net.object.bytearray.base64
58-
value : The object must be serialized into a byte array
59-
: using a System.ComponentModel.TypeConverter
60-
: and then encoded with base64 encoding.
61-
-->
622
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
633
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
644
<xsd:element name="root" msdata:IsDataSet="true">

0 commit comments

Comments
 (0)