I made a program that opens a Google Translate window when F1 is pressed.
I want the "source" textbox to get selected (focused on)
I tried this:
formMain.Activate();
formMain.panelMain.Enabled = false;
formMain.panelMain.Focus();
formMain.panelMain.Select();
formMain.panelMain.Enabled = true;
formMain.webBrowserMain.BringToFront();
formMain.webBrowserMain.Select();
formMain.webBrowserMain.Focus();
formMain.ActiveControl = formMain.webBrowserMain;
if (formMain. WindowState != FormWindowState.Minimized)
{
Program.DoMouseClick((uint)formMain.PointToScreen(formMain. webBrowserMain.Location).X + 10, (uint)formMain.PointToScreen(formMain.webBrowserMain.Location).Y + 10);
}
HtmlElement textArea = formMain.webBrowserMain.Document.GetElementById("source");
if (textArea != null)
{
textArea.Focus();
}
But it only sometimes gets selected!
Try this code :
This includes injecting custom Js in the site and calling that function , works for me in a similar case (Always do operations on a webpage after it has completed rendered/loaded):
private void webBrowser1_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
element.text = "function trig_focus() { document.getElementById(\"theIdOfInputBox\").focus(); }";
head.AppendChild(scriptEl);
webBrowser1.Document.InvokeScript("trig_focus");
}
Related
I want to set a click event to a div in the web browser control, that div have no id, so, I searched for it by title..
and set a click like I do with button control, but it doesn't work.
this is my code :
private void button3_Click(object sender, EventArgs e)
{
var links = webBrowser1.Document.GetElementsByTagName("div");
foreach (HtmlElement link in links)
{
if (link.GetAttribute("title").Equals("div_name"))
{
link.InvokeMember("click");
return;
}
}
}
Any ideas?
And thanks in advance!
You could try this.
In this case, I've modified an existing solution. Add a script to do it:
private void button3_Click(object sender, EventArgs e)
{
var links = webBrowser1.Document.GetElementsByTagName("div");
foreach (HtmlElement link in links)
{
if (link.GetAttribute("title").Equals("div_name"))
{
HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
element.text = "function clickTitle() { document.getElementById('" + link.GetAttribute("id") + "').click(); }";
head.AppendChild(scriptEl);
webBrowser1.Document.InvokeScript("clickTitle");
}
}
}
It adds a javascript script to click on it and then clicks on it. It assumes the element has an id.
Scraping a web page. The page loads and calls a DocumentCompleted handler. Inside that handler, I invoke a java method to set a date and then invoke a click to get the new data (via POST). This all works correctly except that the DocumentCompleted handler is only called once. The POST that goes back and "gets" a new page doesn't cause the handler to fire a second time.
I tried adding multiple handlers, removing the first and adding a second handler in the first handler. Didn't work. Also ran this as Administrator, didn't change anything.
Anyone have thoughts on how to proceed? I guess I can wait 60 seconds for it to load and then grab the text but that seems clunky.
public void FirstHandler(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser wb = ((WebBrowser)sender);
string url = e.Url.ToString();
if (!(url.StartsWith("http://")) || url.StartsWith("https://"))
{
// in AJAX
}
if (e.Url.AbsolutePath != webBrowser.Url.AbsolutePath)
{
// IFRAME Painting
}
else
{
// really really complete
wb.DocumentCompleted -= FirstHandler;
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(SecondHandler);
HtmlElement webDatePicker = wb.Document.GetElementById("ctl00_WebSplitter1_tmpl1_ContentPlaceHolder1_dtePickerBegin");
string szJava = string.Empty;
szJava = "a = $find(\"ctl00_WebSplitter1_tmpl1_ContentPlaceHolder1_dtePickerBegin\"); a.set_text(\"5/20/2017\");";
object a = wb.Document.InvokeScript("eval", new object[] { szJava });
if (webDatePicker != null)
webDatePicker.InvokeMember("submit");
HtmlElement button = wb.Document.GetElementById("ctl00$WebSplitter1$tmpl1$ContentPlaceHolder1$HeaderBTN1$btnRetrieve");
if (button != null)
{
button.InvokeMember("click");
}
}
}
public void SecondHandler(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser wb = ((WebBrowser)sender);
string url = e.Url.ToString();
string d = string.Empty;
if (!(url.StartsWith("http://")) || url.StartsWith("https://"))
{
// in AJAX
}
if (e.Url.AbsolutePath != webBrowser.Url.AbsolutePath)
{
// IFRAME Painting
}
else
{
d = wb.DocumentText;
System.IO.File.WriteAllText("Finally.htm", d);
wb.DocumentCompleted -= SecondHandler;
}
_fired = true;
}
I have below code,when i search from my winform textbox and click search button but webpage text box onclick event not fired. How to do this? here is :http://www.heathrow.com/arrivals when i click search button page still same position, show in 2nd number image. internet explorer 11 i have installed
private void button2_Click(object sender, EventArgs e)
{
HtmlDocument doc = webBrowser1.Document;
HtmlElement HTMLControl2 = doc.GetElementById("searchInput");
if (HTMLControl2 != null)
{
// HTMLControl2.Style = "display: none";
HTMLControl2.InnerText = textBox1.Text;
HTMLControl2.Focus();
SendKeys.SendWait("{ENTER}");
textBox1.Focus();
}
}
Here is the code:
Form1.cs:
private void textBox1_TextChanged(object sender, EventArgs e)
{
HtmlDocument doc = webBrowser1.Document;
HtmlElement HTMLControl2 = doc.GetElementById("searchInput");
if (HTMLControl2 != null)
{
// HTMLControl2.Style = "display: none";
HTMLControl2.InnerText = textBox1.Text;
HTMLControl2.Focus();
SendKeys.SendWait("{ENTER}");
textBox1.Focus();
}
}
Anything else is default.
HtmlDocument doc = webBrowser1.Document;
HtmlElement HTMLControl2 = doc.GetElementById("searchInput");
if (HTMLControl2 != null)
{
// HTMLControl2.Style = "display: none";
HTMLControl2.InnerText = textBox1.Text;
SendKeys.Send("{ENTER}");
textBox1.Focus();
HTMLControl2.Focus();
HTMLControl2.InnerText = textBox1.Text;
SendKeys.Send("{ENTER}");
textBox1.Focus();
HTMLControl2.Focus();
}
I'm creating a Word add-in which allows the user to select various text in a Word document and click a button on the ribbon which will wrap that text with a Content Control (rich text). Eventually these content controls will then be mapped to XML.
The code so far is like this:
public partial class Ribbon1
{
private RichTextContentControl titleRichTextControl;
private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
{
}
private void addTitle_Click(object sender, RibbonControlEventArgs e)
{
AddRichTextControlAtSelection();
}
private void AddRichTextControlAtSelection()
{
word.Document currentDocument = Globals.ThisAddIn.Application.ActiveDocument;
currentDocument.ActiveWindow.Selection.Range.Select();
Document extendedDocument = Globals.Factory.GetVstoObject(currentDocument);
titleRichTextControl = extendedDocument.Controls.AddRichTextContentControl("titleRichTextControl");
titleRichTextControl.PlaceholderText = "Enter the title";
titleRichTextControl.Title = "Title";
titleRichTextControl.Tag = "title";
}
}
All this is fine and it works for the first time the button is clicked. However, if there is more than one 'title' (in this case) that needs adding, and the user presses the button a second time, it throws the error:
The control cannot be added because a control with the name titleRichTextControl already exists in the Controls collection.
It's clear why it complains, but i can't think of the correct way to go to allow multiple clicks of the button to generate multiple content controls of the same type (rich text content control) and the same name ("title" for example).
Can anybody point me in the right direction please.
OK this was how i did it in the end:
private void addTitle_Click(object sender, RibbonControlEventArgs e)
{
AddRichTextControlAtSelection();
}
int count = 0;
private void AddRichTextControlAtSelection()
{
word.Document currentDocument = Globals.ThisAddIn.Application.ActiveDocument;
Document extendedDocument = Globals.Factory.GetVstoObject(currentDocument);
if (currentDocument.ContentControls.Count > 0)
{
currentDocument.ActiveWindow.Selection.Range.HighlightColorIndex = word.WdColorIndex.wdYellow;
currentDocument.ActiveWindow.Selection.Range.Select();
richTextControls = new List<RichTextContentControl>();
foreach (word.ContentControl nativeControl in currentDocument.ContentControls)
{
if (nativeControl.Type == Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlRichText)
{
count++;
RichTextContentControl tempControl = extendedDocument.Controls.AddRichTextContentControl("VSTORichTextControl" + count.ToString());
richTextControls.Add(tempControl);
tempControl.Title = "Title";
tempControl.Tag = "title";
break;
}
}
}
else
{
RichTextContentControl VSTORichTextControl;
VSTORichTextControl = extendedDocument.Controls.AddRichTextContentControl("VSTORichTextControl");
VSTORichTextControl.PlaceholderText = "Enter the DM title";
VSTORichTextControl.Title = "Title";
VSTORichTextControl.Tag = "title";
}
}
This is the scenario
1-Navigate to admin page.
2-Enter username and password
3-Navigate to new page
4-Fill some text in textareas etc and post .
5-Repeat Step 3 and 4 until loop ends
The Code Below successfully does step 1 and 2. But it reaches step 3 before new page is loaded and generates the error "Object reference not set to an instance of an object" on this line doc.GetElementById("title").SetAttribute("value", "check1");
I am trying to achieve this from last 3 days but can't reached step 3 until now. Any help will be appreciated
bool AdminPagework =false;
bool postnavigationdone =false;
public Form1()
{
InitializeComponent();
webBrowser1.DocumentCompleted +=
new WebBrowserDocumentCompletedEventHandler(AdminPageCredentials);
webBrowser1.Navigate("www.website.com/admin");
}
private void AdminPageCredentials(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (AdminPagework == false && (webBrowser1.ReadyState == WebBrowserReadyState.Complete))
{
HtmlDocument doc = webBrowser1.Document;
doc.GetElementById("login").SetAttribute("value", "ADMIN");
doc.GetElementById("pass").SetAttribute("value", "123");
doc.GetElementById("submit").InvokeMember("click");
AdminPagework = true;
webBrowser1.DocumentCompleted +=
new WebBrowserDocumentCompletedEventHandler(RedirectToPostPage);
webBrowser1.Navigate("http://www.website.com/admin/post.php");
}
}
public void RedirectToPostPage(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if ((postnavigationdone == false) && (webBrowser1.ReadyState == WebBrowserReadyState.Complete))
{
HtmlDocument doc = webBrowser1.Document;
doc.GetElementById("title").SetAttribute("value", "check1");
doc.GetElementById("content").SetAttribute("value", textBox2.Text);
doc.GetElementById("post-format-video").InvokeMember("click");
doc.GetElementById("in-category-64").InvokeMember("click");
webBrowser1.Document.GetElementById("mm").SetAttribute("value", "01");
webBrowser1.Document.GetElementById("jj").SetAttribute("value", "01");
webBrowser1.Document.GetElementById("aa").SetAttribute("value", "2013");
webBrowser1.Document.GetElementById("hh").SetAttribute("value", "01");
webBrowser1.Document.GetElementById("mm").SetAttribute("value", "01");
doc.GetElementById("publish").InvokeMember("click");
postnavigationdone = true;
}
}
var titleElement = doc.GetElementById("title");
titleElement.SetAttribute("value","check1");
Try that and see if the title element is found after all, since the most likely reason it fails is: There is no element with the name "title".
I like using ScrapySharp framework (you'll find it on NuGet) for web automation.
var titleNodes = doc.DocumentNode.CssSelect("div#title").ToList();
foreach(var titleNode in titleNodes)
{
titleNode.SetAttribute("value","check1");
}
btw. why would you do that anyway, changing this attribute? Just curious...