How to control application from WebBrowser Control? - browser

I've googled it, but came out empty. And the worst thing is that I know it is possible.
Anyway, I'm developing an application that uses the WebBrowser control to display information regarding an object (like Outlook does with the Rules and Alerts dialog box).
My question is how do I do for the click on a, say, hyperlink in the WebBrowser execute some function within the Windows Form?
For instance, say I have a link like this and when I click it I want the application to display an specific form, like the Outlook does when you click on hyperlinks like People and Distribution List

This looks useful: How to: Implement Two-Way Communication Between DHTML Code and Client Application Code

ChrisW's answer will work, but there's another way if you're just relying on hyperlinks.
In Comicster, I have links in my WebBrowser control like this:
New Collection
And then in the WebBrowser's Navigating event, I have some code to check if the user has tried to navigate to an "action:" link, and intercept it:
private void webBrowser1_Navigating(object sender,
WebBrowserNavigatingEventArgs e)
{
if (e.Url.Scheme == "action")
{
e.Cancel = true;
string actionName = e.Url.LocalPath;
// do stuff when actionName == "FileNew" etc
}
}
With a little bit of code you can even parse the URL parameters and "pass them through" to your host application's action, so I can do things like:
Edit this issue
... which will open a properties dialog for the issue with ID 1.

Related

Create a generic popup panel

I have added a Global Button with the following code.
public override void Initialize()
{
if (!String.IsNullOrEmpty(Base.PrimaryView))
{
Type primaryViewItemType = Base.Views[Base.PrimaryView].Cache.GetItemType();
PXAction action = PXNamedAction.AddAction(Base, primaryViewItemType, "SubmitTicket", "Submit Ticket", TestClick);
}
}
public IEnumerable TestClick(PXAdapter adapter)
{
throw new PXException("Button clicked from graph" + Base.GetType().Name);
}
And it renders the button like this in each of the pages.
Now, I would like to display a popup panel, on button's click. I know I can create a popup panel on screen section. But, is there some way that I can have a general popup panel created in one place and can be displayed on each of the pages on the button's click?
Thank you.
As #HB_ACUMATICA mentioned there is no good easy way.
Providing another alternative to his post, you can create a graph and use it as a reusable popup by calling:
throw new PXPopupRedirectException(graph, string.Empty, true)
One thing I ran into was a sizing issue on the popup...
Changing the height/width when calling another graph as an in-page popup using PXPopupRedirectException
If you do copy and paste the PXSmartPanel you can create re-usable business logic by implementing the reusable business logic pattern found in this help as a starting point:
Reusing Business Logic
If I understand correctly you want to share the same PXSmartPanel control in different pages without having to copy/paste it in every screen.
In Acumatica Framework this is achieve by custom container controls like 'PXUploadDialog' which derives functionality from other controls like 'PXSmartPanel'. This is the control that is used when you attach files in all screen.
Unfortunately there seems to be no documentation on how to achieve this.
The closest I found is this SO question which is essentially unanswered:
Create custom User Control for Acumatica
Considering this, you may want to copy/paste the same smart panel in all screen.
To ease copying you can use the 'Edit ASPX' feature, make sure you backup the project before.
Edit ASPX to get to the code:
Copy paste your smart panel in the page and click 'GENERATE CUSTOMIZATION SCRIPT' to package the changes in the project:

How to open a hyperlink in separate browser tab in Coded UI

I have three different Hyperlinks on a web page
Planning.
Solutions.
Contact Us.
I want to open them in separate browser tab one by one using codedUI.
i have written the above code to obtain the list of Hyperlink
HtmlControl Hyperlink = new HtmlControl(browser);
Hyperlink.SearchProperties.Add(HtmlControl.PropertyNames.ControlType,"Hyperlink");
UITestControlCollection controls = Hyperlink.FindMatchingControls();
foreach(UITestControl control in controls)
{
if (control is HtmlHyperlink)
{
HtmlHyperlink link = (HtmlHyperlink)control;
if(link.InnerText=="Planning"|| link.InnerText== "Solutions")
{
//separate Tab logic goes here
}
}
}
I need the help related to opening a hyperlink in new browser tab. Is it possible in CodedUI ?
By default if you click the mouse middle button (or click the scroll wheel), it opens a link in new tab. I would modify your code as below in this case,
if(link.InnerText=="Planning"|| link.InnerText== "Solutions")
{
//Open Link in New tab, by clicking middle button
Mouse.Click(link, MouseButtons.Middle);
}
You can do this a couple different ways. I would use #Prageeth-Saravan 's approach first to see if it works because it's easier and actually tests your UI. You could also:
Get the URL from the found link control
Send the "New tab" keyboard shortcut
Reinstantiate your browser window object to be sure it's pointing to the new tab
Navigate to that URL
The reason why I bolded step 3 is regardless of approach, if you intend to assert or interact with anything in a new tab you're going to have to remember that the CodedUI software will still be "Looking" at the old tab until you reinitialize it.

Save button is disabled on edit form, cannot click it via UIAutomation

This issue is in the same application as my last question.
I'm experiencing some "odd" behavior, and I don't know if it's functioning as designed or if there's something wrong. In the 3rd party application that I'm "injecting" data into I experience different behavior when I manually edit a record vs. when my automated application edits a record.
If I run the 3rd party application and manually edit a record, the 'Save' and 'Undo' buttons in the toolbar become enabled once I begin typing in a field.
If I run the 3rd party application, then run my automated application to edit a record, my application sets focus to the first field on the form, then "injects" the data into the fields (it actually looks like someone is typing it in very fast) but the 'Save' and 'Undo' buttons stay disabled the whole time. I try to invoke the 'Save' button when I reach the bottom of the form, but I receive an error:
"An unhandled exception of type 'System.Windows.Automation.ElementNotEnabledException' occurred in UIAutomationClient.dll
Additional information: The operation is not allowed on a nonenabled element."
I used this code example on MSDN to insert text in the textboxes of the 3rd party application.
if (!element.TryGetCurrentPattern(
ValuePattern.Pattern, out valuePattern))
{
// Set focus for input functionality and begin.
element.SetFocus();
// Pause before sending keyboard input.
Thread.Sleep(100);
// Delete existing content in the control and insert new content.
SendKeys.SendWait("^{HOME}"); // Move to start of control
SendKeys.SendWait("^+{END}"); // Select everything
SendKeys.SendWait("{DEL}"); // Delete selection
SendKeys.SendWait(value);
}
// Control supports the ValuePattern pattern so we can
// use the SetValue method to insert content.
else
{
// Set focus for input functionality and begin.
element.SetFocus();
((ValuePattern)valuePattern).SetValue(value);
}
Perhaps I'm not searching the correct keywords, but Google has not been much help to me, and I only found one SO post that seemed related. If anyone can shed some light on this I'd really appreciate it.
TIA
UPDATES:
Re: why don't I check if button is enabled...
I don't know how to accomplish that, I was trying to do that earlier today. I have an AutomationElement that references the 'Save' button, but the AutomationElement doesn't have an Enabled property.
AutomationElement toolbar = _mainWindow.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "59392"));
AutomationElement saveButton = toolbar.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Commit Changes (CTRL S)"));
I tried to cast the AutomationElement as Button to check the Enabled property but I receive a build error "Cannot convert type 'System.Windows.Automation.AutomationElement' to 'System.Windows.Forms.Button'"
if (!((Button)saveButton).Enabled)
((Button)saveButton).Enabled = true;
...ok, more searching lead to this: UIAutomation Button Style Enabled
so now I can check if it is enabled, but I haven't figured out how to enable it yet.
2014.10.02 - I think it's not possible to enable a disabled button via UIAutomation. So I will modify my question a bit. If I manually click on an input field and begin typing the 'Save' button becomes enabled. If I use UIAutomation to modify the record the 'Save' button does not become enabled. So, how can I use UIAutomation to get the window into the same state that it's in when I manually edit the record?
You could try using the win32 api to send messages to the button directly. You can get all the handles you need from uiautomation just use the post message function like this.
public TestSetup AutomationLibrary;
[DllImport("User32.dll")] //http://msdn.microsoft.com/en-us/library/windows/desktop/ms644944(v=vs.85).aspx
public static extern int PostMessage(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam);
public int WM_ENABLE = 0x0A;
public int WM_COMMAND = 0x111;
public MainWindow()
{
InitializeComponent();
AutomationLibrary = new TestSetup();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
AutomationElement aeDesktop = AutomationLibrary.GetDesktop();
AutomationElement aeForm1 = AutomationLibrary.GetAutomationElement("Form1", aeDesktop);
AutomationElement aeDisabledButton = AutomationLibrary.GetAutomationElement("DISABLED", aeForm1);
IntPtr windowIntPtr = new IntPtr(aeForm1.Current.NativeWindowHandle);
IntPtr controlIntPtr = new IntPtr(aeDisabledButton.Current.NativeWindowHandle);
PostMessage(windowIntPtr, WM_COMMAND, (IntPtr)WM_ENABLE, controlIntPtr);
}
The TestSetup is my own home brewed automationlibrary but basically I am just getting automation elements then using the PostMessage function from User32.dll to enable the button. although it doesnt seem to actually enable the button, it does have the unintend consequence of clicking the button.
I used this article as reference for the postmessage function http://www.codeproject.com/Articles/487938/Re-Active-Disabled-Controls
Hope this helps

xpages: compute Confirm Action confirmation text does not work in XPiNC

I'm using Notes/Domino 8.5.3. I've added a button control to an xpage. The button uses a Confirm Action to display a client-side prompt to the user before continuing with the next action defined for the button. When I use static text for the Confirmation Text for the Confirm Action, the confirmation prompt is displayed. However, when I change the Confirmation Text to be computed, and retrieve the text from a profile document, the confirmation prompt it not displayed at all in XPiNC. The confirmation prompt with the computed confirmation text is displayed just fine in a browser. Is there a work-around for this issue with XPiNC?
Following is the code I'm using in the Confirm Action to get the text for the prompt:
var server = database.getServer();
var dbProfile:NotesDocument = database.getProfileDocument("DBProfile", "");
var msg = dbProfile.getItemValueString("ContactsInitUpdatePrompt");
return msg;
To further my comments, this is a work around I use the below code for an app that uses the bootstrap extension library on the web but uses basic functionality with xpinc.
If the values for xPinc are different you could make the confirm action different in the browser and in the client.
if (#ClientType()== "Notes")
{
<action>;
}
else{
<action>;
}
I think that profile documents are a bad idea in xPages though. Having to restart HTTP to get a new value ruins the point I think. Almost better to hard code values at that point. I think you can set application scope to handle the work of profile documents. But then application scope in xpinc is just on the current machine as the server is the client.

SharePoint itemDeleting evert is not working

I have a site in SharePoint and I want to custom delete from a list. So, I'm creating the
public class ListItemEventReceiver : SPItemEventReceiver
{
public override void ItemDeleting(SPItemEventProperties properties)
{
if (properties.ListTitle.Equals("Projects List"))
{
Projects pr = new Projects();
string projectName = properties.ListItem["Project Name"].ToString();
pr.DeleteProject(projectName);
}
}
}
Where 'Projects' class has 'DeleteProject' method who deletes the item.
But it's doing nothing :(
I mention that everything it's ok in Feature.xml
Where am I wrong?
Edit (from 'answer'):
Yes, I've tried this:
properties.ErrorMessage = "projectName :" + projectName;
properties.Cancel = true;
in if clause and the event it's firing and displays the project name corectly.
I'm the farm administrator, and site administrator with full control over this site.
DeleteProject method it's right, because I've tried it in some other application (c#) and it's works fine.
A couple of things to check:
Is your list item reciever connected to the list, so that it fires?
Does the user that causes the trigger to fire have the the right to delete items?
Is there any programming error in DeleteProject?
Try putting in some logging to see how far it is running.
Edit
Could the problem be here:
string projectName = properties.ListItem["Project Name"].ToString();
Is the list item called "Project Name" with a space in the name?
Edit 2
From your comments, the combination of authentication and connection string means that it is the security context of the logged on user that is being used against the database. Check the rights of your user.
If event is firing and the only method pr.DeleteProject(projectName); is not working properly then it is difficult to guess what is wrong. If it is not confidential, please post your code and then I shall be in better position to identify what is wrong.
By the way, are you calling .Update() Method on list?
Please check out this link http://msdn.microsoft.com/en-us/library/ms431920.aspx
One more thing to care about is Itemed and Iteming events. It is better to use Before or After properties as appropriate in case of Item*ing events.
Regards,
Azher Iqbal

Resources