How can I get text under mouse pointer WebBrowser control? - c#

I'm currently working on WYSIWYG editor using .net WebBrowser control and I need to implement spell checking.
My question is how can I get text under mouse pointer when I right click on the misspelled word to show all spell suggestions?
Tried to wrap every misspelled word in html label with javascript event, but there seems to be the problem in invoking C# code from javascript.

Ok - here are my 2 cents.
Firstly I imagine you have an editable element more than likely a div and you're using this as your WYSIWYG editor. I also guess you have an Ajax function somewhere that you've setup on a certain keystroke to check the spelling of the entire (maybe even some) of the contents of the DIV, and it can send you back a list of the misspelled words.
My idea is - 1. Create a range on the contents of your editable div, then do a search for the word using the TextRange object - here : http://msdn.microsoft.com/en-us/library/ms535872%28VS.85%29.aspx. Use the findText method which Searches for text in the document (range) and positions the start and end points of the range to encompass the search string.
Once you have this you should copy the text value into a variable, then construct a < Span> possibly even set the bottom-border style of the span to have a red underline, or even use an image so that it looks like that regular misspelled squiggly wave. Set the inner contents of this Span to the value of the original misspelled word. Also don't forget to assign an onclick (or right click) to this SPAN, so you can do another lookup on spelling suggestions later. Great, now you have an offline SPAN but its not yet inserted into the document.
Next step: Use the TextRange pasteHTML method to paste the new SPAN into the document, remember the range should already be defined from the find operation, so you shouldn't have to mess around looking for the text again (or selecting it).
Once the span is in the document using pasteHTML, it should be straight forward, just create another div, absolutely position it just under the SPAN so when the user right clicks it - the "context menu comes up" - populated by Ajax.
After that it should be a very easy case of creating another range, and replacing this time the SPAN with just straightforward text.
ALL of this is theory, but hope it helps!
Also you might want to check out - http://www.aspfree.com/c/a/Code-Examples/Searching-Body-Text-with-textRange-Enter-the-Gecko/ - which will help you make the whole solution work in FireFox (not only IE)

I'll add some more two cents in as I'm currently working on something similar.
Okay, so I'm assuming you are a WebBrowser object? If so, my suggestion would be to use a contextual menu strip every time you every time you right click. From there you can fire the context menu Opening event that will grab that specific HTML element for you.
In short you could use a similar code snippet
Point mouseLocation;
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
HtmlElement elem = webBrowser.Document.GetElementFromPoint(mouseLocation);
//From here you would do what ever it is you need for your element in the browser
}
private void webContextMenuStrip_Opening(object sender, CancelEventArgs e)
{
//This just gets you the specific mouse position for the given element
mouseLocation = webBrowser.PointToClient(MousePosition);
}
Hope this atleast gets you started and best of luck!

Related

.NET WPF WebBrowser Control: Insert HTML at ControlRange selection

I have a WebBrowser control that I am using to create an HTML editor, and I need to be able to insert a string of HTML at the current selection in the document.
Generally, I can do something like this to paste HTML at the current selection, if the selection is a text selection:
IHTMLSelectionObject selection = webBrowser.Document.DomDocument.selection;
// Assume that selection.type == "Text"
IHTMLTxtRange textRange = selection.createRange() as IHTMLTxtRange;
textRange.pasteHTML(myHtmlString);
However, if the current selection is a ControlRange selection, there doesn't seem to be any direct way to insert/paste HTML at that position.
For example:
// Assume that selection.type == "Control"
IHTMLControlRange ctrlRange = selection.createRange() as IHTMLControlRange;
// This throws an error, as IHTMLControlRange has no pasteHTML method
ctrlRange.pasteHTML(myHtmlString);
I know that I can use the HtmlElement.InsertAdjacentElement method to insert an element before or after another element, but that is very limiting, as sometimes I need to be able to insert raw HTML, rather than needing to create an HtmlElement object for it first.
Is there any way to be able to paste/insert an HTML string at the caret position, or over a ControlRange selection?
I have found a workaround for this problem, at least for my specific use case.
The IHTMLSelectionObject.createRange() method returns dynamic, but it will resolve to either an IHTMLTxtRange or an IHTMLControlRange, depending on what the selection type is.
If selection.type == "Text" or selection.type == "None", it returns an IHTMLTxtRange, and if selection.type == "Control", it returns an IHTMLControlRange.
The following statement works for empty selections and text selections:
DomDocument.selection.createRange().pasteHTML(myHtml);
However, in the case of pasting over a control selection, the above statement won't work by default because the createRange() method will return an IHTMLControlRange, which, as mentioned above, has no createRange() method. However, we would be wanting to overwrite the current selection with the new HTML anyway, so one could assume that it is safe to just clear the selection (delete it) and then paste the HTML at the newly empty selection.
Solution
Something like this should work for all types of selections:
// If we have a control selection, clear the selection
if (DomDocument.selection.type == "Control")
DomDocument.selection.clear();
// Now it is no longer a control selection, but an empty text selection
DomDocument.selection.createRange().pasteHTML(myHtml);
This does feel a bit hacky, but it solves the problem for me.

GeckoFX - How to Highlight a specific HTMLelement?

I load HTML document in GeckoFX control. Hovering an HTML element (input, select & link) will highlight it with red color, moving mouse out will restore it's visual state.
One idea is to use OnPaint event and draw rectangle at mouse coordinate.
But I do not know how to use this in C# with GeckoFX control.
Any ideas on how to achieve this or to highlight HTML element are welcome.
Thank you.
Not sure what kind of highlight you have in mind, but in any case you should be able to use Style for it.
For example, you can use DomMouseOver event of GeckoWebBrowser and in the event handler check if the element that the mouse is over is the element you want to highlight (by id, by tag name, by class name). If so, then maybe something like
theElement.SetAttribute("style", "background: #" + color);
would be sufficient?
Also another way to do it would be to inject html / javascript or css to the page you are browsing and handling it from that side.
I do both of these things, though I prefer the first one because it's easier to manage from c# code...

Ranorex test automation issue: Unable to reliably click a button on silverlight web app

We have automated a few test cases using the Ranorex automation framework for a Silverlight web application. These test cases involve clicking buttons in order to invoke certain messages on the screen. In order to grab the button on the screen, we first create an Ranorex button object and then point it to the appropriate element using Ranorexpath. Then, we use the RanorexButton.Click() event to click the button. However, this event is unreliable. It works sometimes and at other times the button is not clicked. When the button is not clicked, we have to run the test case again from the start. What are we doing wrong? If this is a known problem of ranorex, please suggest workarounds.
I was facing the same problem but I am able to resolve the problem by introducing a Validate.Exists(infoObject) just before the click. Please make sure that you pass infoObject of your button or any element in Validate.Exists API.
Example:
Validate.Exists(repo.MyApp.LoginBtnInfo);
var button = repo.MyApp.LoginBtn;
button.Click();
With regards,
Avinash Nigam
I haven't heard about such a problem with Ranorex yet, maybe this is just a timing issue.
You could add a Validate.Exists(yourButton) right before the click, this ensures that the click is performed after the button was successfully loaded.
If it is a WebElement you could also use the PerformClick() method instead of the normal Click() method.
There are also different methods which will ensure that the button is in the visible area and has focus, like the EnsureVisible() or the Focus() method.
You will find the available methods of the used adapter in the online API of Ranorex.
If the Button is not within the area you can see without scrolling, you can use a
var button = repo.Buttons.button1;
button.EnsureVisible();
button.Click();
In this way the button is forced to be watched.
It might as well be an issue with the xpath and element Id-s.
If you have changing element Id-s even when the page is navigated away from and moved back (for example we have this issue with SAP related components) you might need to make a more robust xPath path variable using regular expressions.
Try to find object and parts of the path that do not change (eg. "iFrame id="MainContent"" or "btn id="ID_XXXX_Search_Button"") - ofcourse this will only help if the issue is within this.
Ranorex Regular Expression info can be found here: http://www.ranorex.com/support/user-guide-20/ranorexpath.html#c3294
A quick example of what I'm talking about:
Let's say we have an input field that has a changing ID in it's name:
US_EL.ID_F2B49DB60EE1B68131BD662A21B3432B:V_MAIN._046A-r
And I know that the part in the Id that doesn't change is:
:V_MAIN._046A-r
I can create a path for this searching the element by the ending of the elements' id that doesn't change using regular expression:
/dom[#domain='test.example.com']//iframe[#'identifier']//iframe[#'identifier2']//input[#id**~'^**:V_MAIN._046A-r']
The bold part will specify to search for an input element with an Id that ends with ":V_MAIN._046A-r".
An issue that might arrise from this is if you have elements using partially the same names you might get multiple elements returned for the same path. So it's wise to add a few more certain points to the path (eg. "iframe[#'identifier2']") when this issue arrises.

Popup on mouse hover the word

I am doing a website using asp.net C# and I would like to popup a small window with information as soon as mouse hover a particular word. I know that I have to use jquery but I don't know exactly how to do it.
Any suggestions please?
There are many plugins out there that will help you achieve what you are looking for. However it is also very possible to implement this functionality yourself. I wouldn't be surprised either if some of the plugins you come across also use similar code.
The following is my attempt to demystify tooltip/popup plugin behaviour.
You could wrap the desired word in a <span> element and give it a .hover class.
<div>
This is some text with a <span class="hover">special</span>
word that has hovercraft capabilities.
</div>
Your jQuery (ver 1.7+) would look something like this :
$(".hover").on('mouseenter',function(){
// The popup must be shown here (mouse is over element).
}).on('mouseleave',function(){
// The popup must be hidden here (mouse has left element).
});
I should add here that I am using a great and yet sometimes forgotten capability of jQuery called "chaining". The on() function actually returns the object that it was attached to. In this case $(".hover") - so if I want to call another function on that object I can just add it as another function at the end. Another example of this would be :
$("#myElement").text("An error has occured!").css("color","#FF0000");
That line of code would also at the text to #myElement and also turn the colour red.
With regard to your actual popup - I would suggest two things :
Have an element at the bottom of your markup (written last so highest index - or manually set the highest z-index)
You could also have the popup in a hidden element right next to the element that is supposed to trigger the popup.
What you're after sounds like a 'tool tip'.
The solutions using jQuery are somewhat involved - so I'll just direct you to external resources.
Possible solutions:
ToolTip Plugin for jQuery
Build a Better Tooltip with jQuery Awesomeness

Get the links id for the current cursor position in the webrowser control

We are using the WebBrowser control in c# winforms and need to be able to get information about the Url the cursor is positioned on.
So we have a web page in design mode, which has multiple urls, when the cursor is over one I would like to call a method which would return the id of the link.
Thanks
You can use the IHTMLCaret to get the cursor position from there using IMarkupPointer you can get the element in the current scope.
The webBrowser control has a Document property which has a Links collection. Each Link is an HTMLElement which has events you can tap into. Again, I'm not sure what you mean "cursor" because in the web world, unless if you're in a textbox, there really isn't a "cursor" (which is what I meant to ask in my comment) but you can tap into the MouseOver event and other stuff like that.
Example:
foreach (HtmlElement element in this.webBrowser1.Document.Links)
{
element.MouseOver += (o, ex) =>
{
Console.WriteLine(ex.ToElement.GetAttribute("HREF"));
};
}
This will print out the actual URL that the mouse is over.
You can have a look at this article - Hosting a web browser component in a C# winform - which explains several ways to perform that. or go directly to this one - Hosting a webpage inside a Windows Form - Basically what you need to do is handle the Click of the DOM object inside the COM WebBrowser of IE. You achieve this by handling the Js events inside your C# code.
I remember this kind of customization must be done using the AxSHDocVw.AxWebBrowser COM object instead of the System.Windows.Forms.WebBrowser Class from the newer versions of the .Net Framework.
I could send you more data about this, I did it some project, just give me time to find it ;). In the mean time try with those links.
By!

Categories

Resources