Forcing a process to the be topmost process

I am running a keyboard hook that, when required, launches a process.  That process is a simple C# Windows form with a form on which there is a listview . . . nothing fancy.

It is desired that this form immediately have the focus so the user can begin using the keyboard UP/DOWN arrow keys without having to first "activate" the form.  I want to remove the requirement that the user first have to left click on the form to give it the focus before they can begin using the UP/DOWN keys.

It seems that no matter what I try, the form is never the topmost window. The user is always forced to have to left click on this window first.

I've tried the following:

Setting the "Topmost" property of the form to "true" in the form's Design mode.
Calling the following in the form's Load() event:
      SetFocus(this.Handle)
      SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
      
      AllowSetForegroundWindow(System.Diagnostics.Process.GetCurrentProcess().Id);//cb#27
      SetForegroundWindow((int)this.Handle);

I've even tried elevating the Priority to "RealTime" when it's launched.

I launch the process using the following:



            ProcessStartInfo Prog2 = new ProcessStartInfo();
            Prog2.UseShellExecute = false;
            Prog2.FileName = "c:\someapp.exe";
            Prog2.Arguments = "1";

            Process p2 = Process.Start(Prog2);
            p2.PriorityBoostEnabled = true;
            p2.PriorityClass = ProcessPriorityClass.RealTime;
            p2.WaitForExit();



QUESTION:

The TaskManager has a "SwitchTo" button which always works on any process running.  Is there any way to programatically simulate the "Switch To" functionality within the calling program?

Thanks in advance,

richelieu7778Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

lazyberezovskyCommented:
Just set focus to desired control on Shown event of Form:
private void Form_Shown(object sender, EventArgs e)
{
    textBox1.Focus();
}

Open in new window

0
richelieu7778Author Commented:
That didn't help. I had already set the focus to item #1 in the listview control.  Setting the focus to the listview itself, as you suggested, didn't help.

Pressing the "Switch To" button on the Task Manager *always* works.

There's go to be some property / method in the Process class where you can force that process to be the topmost process . . . . i.e. exactly what the "Switch To" command does in the Task Manager. . . . . there's got to be one . . . . I just can't find it. . . .something like:

        Process p2 = Process.Start(Prog2);
        p2.Topmost = true;

I can't find it . . .
0
lazyberezovskyCommented:
I tried Shown event with ListView.
It works: listView1.Focus();
Mind that item just not displayed as selected (I'll think about this). If you press arrow key - you'll move to next item.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

richelieu7778Author Commented:
It works, but not under unique circumstances, i.e. when the process is launched from another process . . .

All I need is the code which programatically executes whatever Task Manager executes when its "Switch To" button is pressed.  That's all I need.  That works *every* time under *all* circumstances, unique or not.

I hope somebody knows what that is. . . .it can't be that complicated . . . but who knows. . . . it might be a secret held by Microsoft.
0
Daniel Van Der WerkenIndependent ConsultantCommented:
You're gonna have to bit the bullet and use PInvoke:

http://weimenglee.blogspot.com/2007/01/programmatically-switch-to-another.html

0
richelieu7778Author Commented:
Whoooo Hoooo!!!  It *looks* like Dan7el might have it.  I was not aware of the "ShowWindowAsync" method.

I can't try it right now. . . . but I'll try it later today and report back . . .

0
lazyberezovskyCommented:
Man, I tried launching app from other process. All works just fine:
Process.Start(appPath);

As mentioned above:
1) I subscribed to Shown event of form and set focus to ListView there
2) form itself TopMost = true (you can set this from designer)

           
0
richelieu7778Author Commented:
Well. . . . I can't get either method to work.  "ShowWindowAsync()" works just fine when and only when VS.NET 2008 is running from the debugger but not in an EXE. I'm wondering if it's process priority thing . . . .  It seems that not matter what I do, tompost is ignored.
0
lazyberezovskyCommented:
Thad definitely works:
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

// Use like this:
string appName = "WindowsApplication1";
Process[] processes = Process.GetProcessesByName(appName);

if (processes.Length > 0)
{
   Process app = processes[0];
   SetForegroundWindow(app.MainWindowHandle);
}

Open in new window

0
richelieu7778Author Commented:
Already tried that-- . . . . it didn't work . . it’s not that easy in my case.

I've discovered that a complication arises when the calling process (my keyboard hook, in my case)  either:

     1) has no Windows Form,

     2) has a windows form but it's Visible propery is set to False, or

     3) even it it has a Windows form, and it's Visible property is set to true but the Windows form doesn't have the current focus at the instant the new process (which does has a Form) is launched.

In other words, a Form of a spawned process is not allowed to have the current focus if the Form from which the process is spawned does *not* have current focus.  I think I read somewhere that it is a “feature”, or limitation, depending on how you look at it, of the SetForegroundWindow().  That’s why the AllowSetForegroundWindow() exists; to allow, under *limited* circumstances, a process which would not normally be allowed to call SetForegroundWindow(), to be allowed to call it

But, in my case, AllowSetForegroundWindow() *STILL* didn’t work.

The *only* thing I found, that consistently works, so far in my investigation, is to call the following in the spawned process (the code in between the “extra stuff required” comment is the new stuff:

        [STAThread]
        static void Main()
        {
   
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);


      //start of extra stuff required
                frmSomeForm frm = new frmSomeForm();
                frm.Show();
                frm.WindowState = FormWindowState.Minimized;
                frm.WindowState = FormWindowState.Normal;
                frm.TopLevel = true;
                frm.TopMost = true;
       //end of extra stuff requried

                Application.Run(new frmSomeForm ());

        }

It flickers a little when first launched, but I can live with that, for now.  As I learn more I can pare down the unnecessary stuff.
0
richelieu7778Author Commented:
To clarify:  the keyboard hook *never* has focus since it is just that--a background process which handles keyboard combinations.  Since it didn't have focus, the form of the process it launched couldn't have focus (at least without the workaround I stated above).
0
richelieu7778Author Commented:
Although my situation was so unique, and nobody provided a solution which worked consistently, for *my situation* both of you tried to help.

I'll split the points.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.