Managed BHOs not instantiated using Protected Mode - c#

I am writing a BHO for IE using C#. The code I'm concerned with is this:
public class BHO : IObjectWithSite, IOleCommandTarget
{
...
public BHO()
{
MessageBox.Show("Constructor called");
}
public int SetSite(object site)
{
MessageBox.Show("SetSite called!");
if( site != null )
{
_webBrowser = (WebBrowser) site;
_webBrowser.NavigateComplete2 += OnNavigateComplete2;
}
else
{
_webBrowser.NavigateComplete2 -= OnNavigateComplete2;
_webBrowser = null;
}
return 0;
}
private void OnNavigateComplete2(object pDisp, ref object URL)
{
MessageBox.Show("OnNavigateComplete2 called");
}
When IE is run with Protected Mode off, everything works fine. However, if Protected Mode is turned on, NavigateCompleted2() is called, but SetSite() and the constructor are never called (!?!). However, if I create a menu item which calls a method in the BHO class, or open a new tab, everything is correctly called.
Does anyone know why it doesn't work when I open a new IE window?
The full source listing can be found here.

Someone on MSDN answered my question: the constructor and method were still being called, but for some reason the MessageBoxes don't show when I open a new window in Protected Mode until the page is loaded. Variables weren't being set due to a different problem - the constructor was instantiating an object which was silently failing.
I now need help with a different (very much related) problem.

Related

Disabling back button C# Android Xamarin Code Not Responding

So im trying to disable the back button in my app and it seems like the code im using doesnt want to respond, its hard to explain in words so I made a gif so you can see it more clearly and understand because im not sure I will be able to explain in words.
I want to disable the back button in "Activity2" but the codes I've been trying doesnt want to respond to the back button
Ive tried these codes, dont know any more solutions since im new to android development.
First attempt
public override void OnBackPressed ()
{
base.OnBackPressed ();
}
Second attempt (Both did the same thing)
public override void OnBackPressed ()
{
// base.OnBackPressed (); /* Comment this base call to avoid calling Finish() */
// Do nothing
}
What could the possible issue be here?
Try this
protected override bool OnBackButtonPressed()
{
return true;
}
Returning true means that nothing will happen.. if you return false it should still do the default operation (going back)
This is the way to do it on a contentpage atleast... Unsure about activity.
Maybe try this:
OnBackPressed in Xamarin Android
protected override void OnBackPressed()
and
[Activity ( NoHistory = true )]
did you check that pressing the back button actually enters your function?
Set a breakpoint like this :
http://imgur.com/maQCdBg
And start the application in debug mode (F5)
This code will get it to work, make sure you build the program and restart your emulator before you run it (I think thats what made it work for me)
public override void OnBackPressed()
{
// base.OnBackPressed (); /* Comment this base call to avoid calling Finish() */
// Do nothing
}
I did this and it worked perfectly
public override void OnBackPressed()
{
// This prevents a user from being able to hit the back button and leave the login page.
return;
//base.OnBackPressed();
}
Do Just Like This
public override void OnBackPressed()
{
return;
}
You can Try like this
Step 1 Add [Activity(NoHistory =true)
Step 2 Add protected override bool OnBackButtonPressed()
{
return true;
}
to your content page that you want to disable Back Button Pressed.

Why do all pages open in the default browser instead of inside the form?

What I Expect to Happen
The webpage opens inside the form.
What Really Happens
The webpage opens in the default browser (in this case Chrome).
The Code
The Navigate(string) snippet is copied directly from MSDN.
using System;
using System.Windows.Forms;
namespace BrowserFrame
{
public partial class BrowserForm: Form
{
public BrowserForm()
{
InitializeComponent();
Navigate("http://www.stackoverflow.com");
}
private void Navigate(String address)
{
if (String.IsNullOrEmpty(address)) return;
if (address.Equals("about:blank")) return;
if (!address.StartsWith("http://") &&
!address.StartsWith("https://"))
{
address = "http://" + address;
}
try
{
webBrowser1.Navigate(new Uri(address));
}
catch (System.UriFormatException)
{
return;
}
}
}
}
What I Did So Far
Changing the default browser (e.g. IE, Firefox) opens the page in the default browser.
Using webBrowser1.Navigate(new Uri("http://www.stackoverflow.com")); directly does the same thing.
Tried calling Navigate from other events (e.g. OnLoad, MouseClick); same result.
Update
Turns out this happens to all web-based UI controls. (Posted a question on superuser.)
I don't understand why it would open in an external browser, as it doesn't happen to me, but you can try this and see if it makes any difference.
Have you tried:
webBrowser1.Navigate(address); without using an Uri?
It works fine for me, and it doesn't need http:// or https://.
I guess they automated that in the class constructor for strings.
Or perhaps you could try changing to this simple version:
public BrowserForm()
{
InitializeComponent();
webBrowser1.Navigate("http://www.stackoverflow.com");
}
Just to see if it helps.

Implement browser in windows form using awesomium

I"m using Awesomium to try and implement webpages inside my windows form application.
I've used the the awesomium .NET samples but I just don't get the my tab with my homeurl.
When I run my project the status bar is floating inside my form and nothing else happens.
Anyone know where I can get a tut on how to do this or know what could be the problem?
public Laboratory() {
WebCoreConfig webConfig = new WebCoreConfig() {
SaveCacheAndCookies = true,
HomeURL = "http://www.google.com",
LogLevel = LogLevel.Verbose
};
// Using our executable as a child rendering process, is not
// available when debugging in VS.
if (!Process.GetCurrentProcess().ProcessName.EndsWith("vshost")) {
// We demonstrate using our own executable as child rendering process.
// Also see the entry point (Main function) in Program.cs.
webConfig.ChildProcessPath = WebCoreConfig.CHILD_PROCESS_SELF;
}
WebCore.Initialize(webConfig);
InitializeComponent();
}
#region methodes
#region OpenTab
internal WebDocument OpenTab(string url = null, string title = null) {
WebDocument doc = String.IsNullOrEmpty(url) ? new WebDocument() :
String.IsNullOrEmpty(title) ? new WebDocument(url) : new WebDocument(url, title);
doc.Show(dockPanel);
return doc;
}
#endregion
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
this.OpenTab();
}
I've redone the left panel completely and used the other example that was with the download, that works like a charm. It's very basic but that'll do for now.
I too had the same problem but i devised a work around for the problem . I implemented the main browser engine that needs to be rendered on every tab (WebDocument Page as per the example) as a user control . Then i used a DockPannel in the mainForm .
So i create an instance of the user control and then add this to an instance of the DockPannel and thus it creates a tab with the required structure .
In case you have still not found a solution or have problems , please leave down a comment and i'll put in some code to help you .

Refactoring big ball of mud; not sure static is being used properly here. Advice?

I'll admit sometimes the deeper nuances of the keyword static escape me.
Here's what I'm seeing:
public partial class Default : CSSDEIStatusBase
{
private static Default _csWitWeb;
protected void Page_Load(object sender, EventArgs e)
{
//DoStuff
_csWitWeb = this;
//OtherStuff
}
public static void ForceLoadSyncOperation(int? index)
{
Default._csWitWeb.LoadSelectedSyncOperation(index);
}
}
The only references to ForceLoadSyncOperation are:
Default.ForceLoadSyncOperation(index);
or
Default.ForceLoadSyncOperation(null);
Both of these calls originate from:
public partial class DataOriginUserControl : System.Web.UI.UserControl
and are not located inside of static methods.
E.G:
protected void btnCancelSyncOperation_Click(object sender, EventArgs e)
{
this.lblErrorMessage.Text = string.Empty;
this.lblErrorMessage.Visible = false;
int index = _syncOperation.Sequence - 1;
Default.ForceLoadSyncOperation(index);
}
This all seems really quirky to me. Does this smell to anyone else? Not really sure how to untangle it, though, as I can't exactly create an instance of the Default page inside of a user control.
Thoughts? Thanks for reading.
protected void LoadSelectedSyncOperation(int? index)
{
SyncOperationConfiguration[] syncOperations = CSServiceClient.GetInterfaceConfiguration().SyncOperationConfigurations.ToArray();
PopulateSyncOperationsListView(syncOperations);
SyncOperationConfiguration syncOperation = null;
try
{
syncOperation = syncOperations[index.HasValue ? index.Value : 0];
}
catch
{
syncOperation = syncOperations[0];
}
ucDataOrigin.LoadSyncOperationData(syncOperation);
Session["ConfigMenuActiveIndex"] = 1;
menuConfiguration.Items[(int)Session["ConfigMenuActiveIndex"]].Selected = true;
mvwConfiguration.ActiveViewIndex = (int)Session["ConfigMenuActiveIndex"];
}
Presumably, the user control is contained within the Default page and the static member is being used as a shortcut to get the current instance of Default. I would've done it this way:
Default defaultPage = this.Page as Default;
if (defaultPage != null)
{
defaultPage.LoadSelectedSyncOperation(index);
}
Using a static member in this way is not safe. It opens up the door for race conditions. There is the potential risk that the user control is loaded in another page and calls LoadSelectedSyncOperation() on a separate request's instance of Default, thus wreaking all kinds of potential havoc.
I don't know what LoadSelectedSyncOperation does but this code looks weird. Whenever you click btnCancelSyncOperation you end up calling this method on some page, but you never know on which of them. It doesn't make much sense to me.
I would definitely say your concerns are valid. I can't think of any reason that this design would make sense, ever. This would throw a flag for me, too.
Based on your reply to my comment, if the Default.LoadSelectedSyncOperation is not dependent upon the Default page somehow, then I suggest it be refactored into a separate class (not an ASP.NET Page).
Whether it makes sense for the method or new class to be static or not is a separate concern and would be based on the logic contained within the method.

How to use Internet Explorer OnQuit Event in a BHO using C#?

I'm trying to use the OnQuit Event of IE, but it's just not firing when I close Internet Explorer. Is there any other way to detect closing of tabs, or the browser in IE?
I'm using it in a BHO written in C#.
Using IE9 and native c++ BHO (ATL), I've no problems getting the onQuit event
My BHO derives from IDispEventImpl, and in the SINK_MAP I specify the DISPID_ONQUIT event:
class ATL_NO_VTABLE CMyBho
:public CComObjectRootEx<CComSingleThreadModel>
...
,IObjectWithSiteImpl<CMyBho>
,IDispEventImpl<1, CMyBho, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>
{
...
BEGIN_SINK_MAP(CMyBho)
SINK_ENTRY_EX( 1, DIID_DWebBrowserEvents2, DISPID_ONQUIT, onQuit )
END_SINK_MAP()
...
STDMETHODCALLTYPE onQuit( );
...
STDMETHOD(SetSite)(IUnknown* unkSite) {
CComQIPtr<IServiceProvider> ifServiceProvider(unkSite);
CComPtr<IWebBrowser2> ifBrz2;
ifServiceProvider->QueryService( SID_SWebBrowserAPP, IID_IWebBrowser2,
(void**)&ifBrz2 );
this->DispEventAdvise( ifBrz2 );
}
}
Saying all that, I know this is native code (vs. C#) and this is IE9 - but maybe it will give you a hint what needs to be done on your C# implementation. Sent me a note or comment if you want the full source code or need more help.
If you are using WebBrowser Object then as per this OnQuit() MSDN:
The WebBrowser object ignores this event.. One solution is to use native code as mentioned in Uri's answer.
OnQuit works pretty well for me with IE11.
Handler:
public void OnQuit()
{
logger.Debug("Entered OnQuit");
}
Wiring:
int IObjectWithSite.SetSite(object site)
{
if (site != null)
{
mainWindowBrowser = (WebBrowser)site;
mainWindowBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
mainWindowBrowser.OnQuit += new DWebBrowserEvents2_OnQuitEventHandler(this.OnQuit);
}
else
{
mainWindowBrowser.DocumentComplete -= new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
mainWindowBrowser.OnQuit -= new DWebBrowserEvents2_OnQuitEventHandler(this.OnQuit);
mainWindowBrowser = null;
}
return 0;
}

Categories