Avatar of dbtoth
dbtoth asked on

IE Browser in Second Thread Grabs Keyboard Focus

After resolving an issue getting a form with an IEBrowser control to successfully run on a second thread I am fighting a problem with updates to that window grabbing active window, mouse and keyboard focus.

Basically, the intent was to load a Powerpoint PPS file on a second display window and whenever the window isn't needed for displaying valuable information to let the PPS file spew advertising in the clients direction.

The problem I've got is that the form running in that second thread grabs active window, keyboard and mouse focus everytime a slide transitions. The problem is system wide, it doesn't matter what other application you are running, the IEBrowser control update always grabs focus.

I have a suspicion this is related to my original problem. When the window on the new thread was invoked with MySecondScreen.Show() the window immediately opened, then closed, then the thread terminated. I resolved that by calling .ShowDialog() instead. This made the window on that thread system modal and I suspect this is the reason for my issue...

So the solution as I see it is to either (a) figure out how to keep the window open on the new thread without making the window modal, or (b) prevent that window from pulling focus from everything else on update.

Anyone got any ideas?
.NET ProgrammingC#

Avatar of undefined
Last Comment
dbtoth

8/22/2022 - Mon
dbrckovi

Hi!

Try creating a do-while loop which will keep your thread running as long as the browser window is open.

        private void ShowBrowser()
        { //function which you call with ThreadStart object
            Form2 frm = new Form2();
            frm.Show();
 
            do
            {
                Application.DoEvents();
            } while (frm != null && frm.Visible);
        
        }

Open in new window

ASKER
dbtoth

This keeps the window from closing, but the IEBrowser control still grabs active window, keyboard and mouse focus every time a slide transitions in the PPS file.
dbrckovi

I've been testing it by setting up a timer on web browser which reloads google or youtube every 10 seconds, and it didn't remove focus from main form.
Can you post a code sample of how you loaded pps file in IEBrowser control, so I can try the same?
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
dbrckovi

In the meantime try setting your main form's TopMost property to true.
ASKER
dbtoth

It's called from the mainform, Form1

outScreen = f.MySecondScreen;
outScreen.ActivateContent(outFile);

Here's the code from SecondScreen()

        delegate void ActivateContentDelegate(string contentFile);
        public void ActivateContent(string contentFile)
        {
            if (this.InvokeRequired)
            {
                ActivateContentDelegate d = new ActivateContentDelegate(ActivateContent);
                this.Invoke(d, new object[] { contentFile });
            }
            else
            {
                axWeb1.Navigate(contentFile, ref refMissing, ref refMissing, ref refMissing, ref refMissing);
            }
        }

I notice that it doesn't happen on my Form1, where the second thread was created, but it does happen to any Modal dialog launched from Form1. As an example, I have a simple little Login form that prompts for username and password. It's launched on a button click from Form1

LoginForm lf = new LoginForm();
lf.ShowDialog()

If I leave the application sitting on the main Form1, then focus is NOT lost when the PPS transitions

If I click the button to launch the LoginForm, the login form appears (with activewindow, keyboard and mouse focus) until the PPS transitions a slide... then the login form goes inactive until the mouse is clicked back inside the login form, which activates it until the next PPS transition.

Using TopMost on the login form didn't help.
dbrckovi

Hi!

I can't recreate your exact situation because I can't find axSHDocVw.dll on my computer. Web browser control I use won't open pps files inside its client area. Instead it starts Power Point.
But I've created a timer on second form which activates it every few seconds. It seems to produce the same result as you described.

If your second form is not ment for user interaction, but only to display PPS, then you might reactivate topmost form every time second form is activated, so it will lose focus as soon as it gets it.

Something like this:

I know this isn't the most elegant sollution, but I'll try to play with it some more and see if I can come up with something better.
// create:    
public static Form TopMostForm = null;
 
// then in Form1_Load:     
 Form1.TopMostForm = this;
 
// when calling login form:  
LoginDialog d = new LoginDialog();
TopMostForm = d;
d.ShowDialog();
TopMostForm = this;
 
//finally in Second form's Activate event
if (Form1.TopMostForm != null && Form1.TopMostForm.WindowState != FormWindowState.Minimized && Form1.TopMostForm.Visible == true)
{
    Form1.TopMostForm.Activate();
}

Open in new window

Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
dbtoth

I think the instructions I found on MSDN called for axSHDocVw to be added. I don't remember specifically why but there were two controls that MS wanted added for the IEBrowser control support.

The issue with Office documents not loading inside the browser was causes by one of the service packs, it's also documented on MSDN with some .REG files that modify the behaviour of each office file type separately for those that are to launch inside the web browser.

Either way you seem to have found the same problem I'm having.

I had considered the TopMost method you suggest, the problem is that I'd have to edit every single modal form in my solution, and then the setting would get lost if a form calls another form... it's not really a workable fix unfortunately.

I wonder if there's some way to hack the message loop itself to prevent the activate message from ever being dispatched to the second window... I know it's messy trying to find old style window HWND handles for managed code forms but that seems it might be the way to deal with this... head off the activate that being tripped by the slide changes and maybe the other windows won't deactivate.
dbrckovi

I found interesting forum thread here: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=402741&SiteID=1

Summary:
When second form recieves WM_ACTIVATE message, code tries to return focus to the form which had it previously.
If this form was not found, it simply deactivates second form, and windows switches the focus back automaticaly.

I've modified the code so it prevents WM_ACTIVATE to be passed to base.WndProc() function.

Try pasting this in the form where PPS is shown:
using System.Runtime.InteropServices;
.
.
.
        [DllImport("user32.dll")]
        private extern static IntPtr SetActiveWindow(IntPtr handle);
        private const int WM_ACTIVATE = 6;
        private const int WA_INACTIVE = 0;
 
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_ACTIVATE)
            {
                if (((int)m.WParam & 0xFFFF) != WA_INACTIVE)
                {
                    if (m.LParam != IntPtr.Zero)
                    {
                        SetActiveWindow(m.LParam);
                    }
                    else
                    {
                        // Could not find sender, just in-activate it.
                        SetActiveWindow(IntPtr.Zero);
                    }
                }
            }
            else
            {
                base.WndProc(ref m);
            }
        } 

Open in new window

ASKER
dbtoth

I tried adding the above code to the SecondScreen.cs. It made absolutely no difference, focus is still lost from any modal dialog launched from the original form.

As an interesting note, I've tried this on three different computers. One has office 2003 the other two are office 2007. The presentation being viewed is an Office 2003 PowerPoint slideshow.

On the PC with Office 2003 I cannot stop focus from being lost no matter what I try but on both PC's running Office 2007, the keyboard focus is NOT lost on the main form when the slide transitions.

Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
dbrckovi

Maybe Power Point ActiveX doesn't use WM_ACTIVATE message, but something else.
Since I can't recreate your exact situation I'm running out of ideas.

Maybe you might consider using some online presentation viewers like www.zoho.com.
It's a complete web based office application in which you can import MS PPS files and publish them.
You can then paste HTML code into your local html file and load it in WebBrowser control.

This is the example of my PPS html file if you'd like to check it out.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Untitled Page</title>
</head>
<body>
<iframe src="http://show.zoho.com/embed?USER=dbrckovi&DOC=BLA-pps1&IFRAME=yes" height="335" width="450" name="BLA-pps" scrolling=no frameBorder="0" style="border:1px solid #AABBCC"></iframe>
</body>
</html>

Open in new window

ASKER CERTIFIED SOLUTION
dbtoth

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
See how we're fighting big data
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question