Setting custom cursor via css in winforms WebBrowser control - c#

I'm using the old WebBrowser control in a winforms app (C#) to display some static html document. So far, I managed to display what I want, react in a custom way to link clicks, show custom rich tooltips etc.
I'm struggling to set custom mouse cursors, though. The Control itself does not support the ctrl.Cursor property, and setting cursors via CSS in the HTML does only work for standard cursors, NOT for custom cursors.
I'm aware of the neccessity to set the engine to latest (see meta tag in head). The question is, how can I point to a .cur / .png file; I tried with relative paths, absolute paths (just for tests), or doesn't the WebBrowser control maybe allow custom cursors at all?
Here's my snippet:
this.webBrowser1.DocumentText = #"<!DOCTYPE html>
<html>
<head>
<meta http-equiv=""X-UA-Compatible"" content=""IE=edge"" />
<title>Foo</title>
<style>
.customcursor {cursor:url('C:\path\to\stuff.cur'), auto !important;}
</style>
</head>
<body>
<a href='...' class='customcursor'>Foo</a>
</body>
</html>";

Related

How do I render special characters in HTML the same in WPF as in Winforms?

I'm working on an email notification project, where in a preexisting Winforms screen the client can edit an email template - adding html, text, etc. A very simplified example input:
<!DOCTYPE html>
<html>
<head>
<title>The Title</title>
</head>
<body bgcolor="#f2f2f2" style="margin: 0; padding: 0;">
<br />
<b>Please do not respond to this e-mail, as it is not monitored.</b>
<br/>
<br/>
“Foo bar baz.
<br/>
<br/>
Baz bar foo.”
<br/>
</body>
</html>
This is saved as a string. On the same screen, the user may then click a button which will raise a ShowDialog call on another Form. This form previews the user's html in a WebBrowser control:
this.webBrowser.DocumentText = theHtmlString;
And the results:
Problem:
I am creating a WPF screen related to the Winforms screens mentioned. It too needs the ability to preview the user's html. To do so I've used an attached behavior modified from this version. Essentially, this dialog also previews the user's html in a WebBrowser control:
webBrowser.NavigateToString(theHtmlString);
However, the results aren't correct, as highlighted below:
If this were my own html input, I'd simply remove the offending characters and replace them with standard quotations. But since this input is from the client, how do I get WPF to render the same as Winforms?
The reason this poses an issue:
In the old Winforms screen, the user creates/edits-existing email templates, previews them, is satisfied with the rendered example, saves changes.
In the new WPF screen, the user exports/imports existing email templates, previews them, is dissatisfied with the rendered example and strange characters, becomes confused when the other screen still renders correctly - calls to report a "bug" in the new screen.
Simple Reproduction Example: - Credit to Eser
var encoded = WebUtility.HtmlEncode(" “ Test ” "); //" “ Test ” "
var buf = Encoding.UTF8.GetBytes(" “ Test ” ");
var str = Encoding.GetEncoding("Windows-1252").GetString(buf); //" “ Test †"
Just add this meta tag to the <head> of your HTML:
<meta charset='utf-8'>
This will display the special characters correctly. I just tested your exact code with this and it works.

Navigating trough objects of a web page, using an embedded web browser

I have a Windows Forms application that uses a WebBrowser control to display an embedded web page. The file is (successfully) loaded using:
webHelp.DocumentStream=
Assembly.GetExecutingAssembly()
.GetManifestResourceStream("MyAssembly.help.html");
In order for this to work (i.e. the file to be loaded/displayed) I set the webHelp.AllowNavigation = false;. I don't fully understand why, but if it's set to true, the page is not displayed.
In my HTML document (see bellow) I want to be able to navigate trough different sections. But when I click on a link, the browser control does not go to the targeted element. The web page works fine in the stand-alone Internet Explorer 10, so it must have something to do with the control, more specifically the AllowNavigation property. MSDN didn't help much.
How can I achieve this navigation behavior? Is there another way of loading the HTML file without setting the AllowNavigation property to false?
This is my simple HTML file:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Using this tool</title>
</head>
<body>
<h3>Description</h3>
<div><p id="contents">Contents</p></div>
<div>
<p id="general">Using the file converter</p>
<p>*converter description*</p>
Go To Top!
</div>
<div class="divBlock" >
<p id="selectOption">Selecting a conversion action</p>
<p>*action selection*</p>
Go To Top!
</div>
</body>
</html>
EDIT: After additional tests I found the root of the problem. The problem appeared after setting a value for the URL property, running the application and afterwards clearing this value. The embedded page is not loaded any more, unless the AllowNavigation property is set to false. There are two solutions, described in my answer bellow.
I also have my own WebBrowser. I've tested it and it loads your HTML file perfectly.
I simply used:
webBrowser1.Navigate("C:\\myPath\\SofNavigate.html");
When I click on links it goes to "#contents" without problems.
I am not sure why you need to use webHelp.Docstream instead of simple Navigate.
By the way, when I turn off navivation, then I am not able to go anywhere from the page that I started on. So Navigation must be on in order to go anywhere from the "home page".
Try to debug that part, as it appears to be the bigger problem that you have.
Here is a good example on how to set up simple webBrowser. Try to use it as a base and see what you do differently that messes up your navigation.
[EDITED] Win8/IE10, your code works for me unmodified inside Form.Load event on a simple form which has just a single WebBrowser control with all default settings (and WebBrowser.AllowNavigation is true by default). Check the properties of your WebBrowser control in the Designer, you may have something wrong in there.
[/EDITED]
You're using HTML5, which handles anchor links via id attribute (i.e. <p id="contents"> ... <a href="#contents">. By default, WebBrowser control works in legacy IE7 mode with HTML5 disabled. You need to turn it on with FEATURE_BROWSER_EMULATION feature control, before WebBrowser object gets created. The best place to do this is a static constructor of your form:
static MainForm()
{
SetBrowserFeatureControl();
}
private static void SetBrowserFeatureControl()
{
// http://msdn.microsoft.com/en-us/library/ee330730(v=vs.85).aspx#browser_emulation
// FeatureControl settings are per-process
var fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
// make sure the control is not running inside Visual Studio Designer
if (String.Compare(fileName, "devenv.exe", true) == 0 || String.Compare(fileName, "XDesProc.exe", true) == 0)
return;
// web pages containing standards-based !DOCTYPE directives are displayed in Standards mode
using (var key = Registry.CurrentUser.CreateSubKey(
#"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",
RegistryKeyPermissionCheck.ReadWriteSubTree))
{
key.SetValue(fileName, (UInt32)9000, RegistryValueKind.DWord);
}
}
Try it and your links should work as expected. This solution does NOT require admin rights, the affected key is under HKEY_CURRENT_USER.
[UPDATE] There may be a better solution, it works at least for IE10 here on my side. Add <meta http-equiv="X-UA-Compatible" content="IE=edge" /> as below and leave the registry intact. If you see document.compatMode: CSS1Compat, document.documentMode: 10, you should be good to go, but test with older IE versions too.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title></title>
<script type="text/javascript">
window.onload = function () {
info.firstChild.data =
"document.compatMode: " + document.compatMode +
", document.documentMode: " + document.documentMode;
}
</script>
</head>
<body>
<pre id="info"> </pre>
</body>
</html>
EDIT: After finding the cause of the problem (see the edit to the question) I can now propose three solutions:
1. WebBrowser control replacement:
Simply delete the existing WebBrowser control and add a new one. This solution does not require any modification of the AllowNavigation property. DO NOT modify the URL property.
2. When deleting and adding a new WebBrowser control is not an option:
Since the AllowNavigation property was influencing the loading and displaying of the web page, there was no reason for it to be left to false afterwards. Setting back the property in the Shown event solved the navigation problem, without requiring other alterations (e.g. in the HTML file or the Registry):
private void helpForm_Shown(object sender, EventArgs e)
{
webHelp.AllowNavigation = true;
}
3. Reseting the Document
It seams that the Document property gets (automatically) initialized if URL property is at one time set and reset. Adding webHelp.Document.OpenNew(true); before loading the resource stream solves the problem without the need for re-adding the WebBrowser and without modifying the AllowNavigation property.

Webbrowser word wrap

I am writing small webbrowser in C# and I would like it to wrap works and images, instead of using horizontal scroll bar.
I need something similar to Word Wrap, as in Notepad.
Here is an example:
Chrome:
My browser:
I've looked at other topics but many suggest solutions in CSS and dealing with html.
I was wondering if there is a way to disable that in WebBrowser itself or by using some other method.
To clarify, Scroll Bar is not a problem, I know that it can easily be disabled by:
webBrowser1.ScrollBarsEnabled = false;
In standard HTML mode, images wrap automatically. E.g.:
<!DOCTYPE html>
<head>
<title></title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<script>
window.onload = function() {
for (var i = 0; i < 50; i++) {
var img = document.createElement("img");
img.src = "http://png-4.findicons.com/files/icons/1943/yazoo_smilies/128/big_smile.png";
container.appendChild(img);
}
}
</script>
</head>
<body>
<div id="container"></div>
</body>
Fiddle: http://jsfiddle.net/Noseratio/VzdDW/
You did not post your HTML, so it's hard to guess, but try enabling the standard mode, both for your web page and for WebBrowser control (by implementing browser feature control).

WebBrowser 'steals' shortcut keys

PROBLEM:
I have a WebBrowser and have exposed its ActiveX methods. In my Form in which the WebBrowser is positioned I have a MainMenuStrip with shortcuts. Only when I am typing in a textbox on my Form do the shortcuts properly work. For example, when I press CTRL + N, a shortcut of my Form - instead of a new Form opening, the page the WebBrowser is currently on opens in IE.
WHAT I'VE TRIED:
I have tried focusing the form every 100ms using a timer which didn't work (this would not be a viable option anyway as it is not very subtle and the program has to carefully navigate the WebBrowser using SendKeys etc).
Code for WebBrowser:
this.webBrowser1.WebBrowserShortcutsEnabled = false;
this.webBrowser1.AllowWebBrowserDrop = false;
this.webBrowser1.IsWebBrowserContextMenuEnabled = false;
Inheriting from WebBrowser and overriding ProcessCmdKey:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.N))
{
newToolStripMenuItem.PerformClick();
return true; // or false
}
}
WHAT I'M TRYING TO ACHIEVE:
That the WebBrowser's shortcuts are disabled (I read somewhere that the ActiveX prevents this...why?).
What I would like is that unless one is currently typing/navigating in the WebBrowser the Form's shortcuts work. Focus should be taken from the WebBrowser WHEREEVER there's a click outside the control, not just when other textboxes are in focus (e.g. when there's a click in the blank of the form.
Try inheriting from WebBrowser control and override Control.IsInputKey. See if Ctrl+N arrives in there.
After investigating a lot, we came to know it is browser compatibility issue.
We have added meta tag into the HTML page,then shortcuts are working fine. Below is the sample code.
<html>
<body>
<Head>
<meta http-equiv="X-UA-Compatible" content="IE=IE8" />
</head>
<form>
First name:<br>
<input type="text" name="firstname">
<br>
Last name:<br>
<input type="text" name="lastname">
</form></body>
</html>
There are three different solutions for this problem.
Adding meta tag to make the Web site browser compatible.
Override "PreocessCmdKey" method and handle the shortcuts.
Emulate browser by adding the key under FEATURE_BROWSER_EMULATION.
If you don't want to set the meta tag in html code, you can assign meta tag to the Document text property of webbrowser control before navigating the URL. Below is the sample.
//Setting compatible mode of IE.
this.m_oWebBrowser.DocumentText = #"<html>
<head><meta http-equiv=""X-UA-Compatible"" content=""IE=IE8"" /> </head>
<body></body>
</html>";
this.m_oWebBrowser.Navigate("www.google.com");

Best control for rendering HTML

I have the need to render some html text (not an html page with <html> and <body> tags and everything, just some <i>'s and <hr />s and stuff) in a C# .NET 4.0 Winforms application. Preferably it would be a Panel-like control that you could just p.HTML = "somehtml" on and it would display HTML. Has anyone had any experience with .NET HTML rendering controls that they could recommend? I found this on codeproject but I'm a little wary of stuff on there.
Why not use the build in WebBrowser control. You can always enclose your html snippet in standard <html/> markup.
string html = "<i> some text </i>";
webbrowser1.DocumentText = string.Format("<html>{0}</html>", html);
You can try this one link
You can use the WebBrowser control in
design mode with a second WebBrowser
control set in view mode.
In order to put the WebBrowser control
in design mode, you can use the
following code.
This code is a super stripped down
version of a WYSIWYG editor for one of
our software products.
Simply create a new form, drop a
WebBrowser control on it, and put this
in the form_load
Me.WebBrowser1.Navigate("about:blank")
Application.DoEvents()
Me.WebBrowser1.Document.OpenNew(False).Write("<html><body><div id=""editable"">Edit this text</div></body></html>")
'turns off document body editing
For Each el As HtmlElement In Me.WebBrowser1.Document.All
el.SetAttribute("unselectable", "on")
el.SetAttribute("contenteditable", "false")
Next
'turns on editable div editing
With Me.WebBrowser1.Document.Body.All("editable")
.SetAttribute("width", Me.Width & "px")
.SetAttribute("height", "100%")
.SetAttribute("contenteditable", "true")
End With
'turns on edit mode
Me.WebBrowser1.ActiveXInstance.Document.DesignMode = "On"
'stops right click->Browse View
Me.WebBrowser1.IsWebBrowserContextMenuEnabled = False

Categories

Resources