C#强制形式焦点 [英] C# Force Form Focus

查看:241
本文介绍了C#强制形式焦点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我没有搜索谷歌和SO前提出这个问题。基本上,我有一个具有编译成它形式的DLL。的形式将被用于显示信息,以在屏幕上。最终,这将是异步的,在DLL中暴露出了很多的定制。现在我只是希望它正确显示。那我遇到的问题是,我通过在PowerShell会话中加载它使用的DLL。所以,当我尝试显示形式,并得到它来顶部,具有焦点,它有显示在所有其他应用程序没有问题,但我不能为我的生命得到它显示在PowerShell窗口。下面是我目前使用的尝试并获得它显示code。我相信,大多数也不会被要求一旦我弄清楚,这才重新presents所有我通过谷歌找到的东西。

So, I did search google and SO prior to asking this question. Basically I have a DLL that has a form compiled into it. The form will be used to display information to the screen. Eventually it will be asynchronous and expose a lot of customization in the dll. For now I just want it to display properly. The problem that I am having is that I use the dll by loading it in a Powershell session. So when I try to display the form and get it to come to the top and have focus, It has no problem with displaying over all the other apps, but I can't for the life of me get it to display over the Powershell window. Here is the code that I am currently using to try and get it to display. I am sure that the majority of it won't be required once I figure it out, this just represents all the things that I found via google.

CLass Blah
{
        [DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
        public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, uint pvParam, uint fWinIni);

        [DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("User32.dll", EntryPoint = "ShowWindowAsync")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
        private const int WS_SHOWNORMAL = 1;

    public void ShowMessage(string msg)
    {
            MessageForm msgFrm = new MessageForm();
            msgFrm.lblMessage.Text = "FOO";
            msgFrm.ShowDialog();
            msgFrm.BringToFront();
            msgFrm.TopMost = true;
            msgFrm.Activate();

            SystemParametersInfo((uint)0x2001, 0, 0, 0x0002 | 0x0001);
            ShowWindowAsync(msgFrm.Handle, WS_SHOWNORMAL);
            SetForegroundWindow(msgFrm.Handle);
            SystemParametersInfo((uint)0x2001, 200000, 200000, 0x0002 | 0x0001);
    }
}

正如我说,我敢肯定,大多数要么是不需要的,甚至平掉错了,我只是想证明我曾经尝试过的事情。此外,正如我所说的,我打算这已经在某些时候,我怀疑会倒闭,需要一个单独的线程异步地显示。会分裂出形式到它自己的线程使其更容易导致其在PowerShell会话中得到重点是什么?

As I say I'm sure that most of that is either not needed or even flat out wrong, I just wanted to show the things that I had tried. Also, as I mentioned, I plan to have this be asynchronously displayed at some point which I suspect will wind up requiring a separate thread. Would splitting the form out into it's own thread make it easier to cause it to get focus over the Powershell session?

@Joel,感谢信息。这是根据你的建议,我的尝试:

@Joel, thanks for the info. Here is what I tried based on your suggestion:

msgFrm.ShowDialog();
msgFrm.BringToFront();
msgFrm.Focus();
Application.DoEvents();

的形式仍然出现的的的PowerShell会话。我会制定出线程进行。我以前产生的线程,但从来没有在那里交谈的子线程需要的父线程,所以我们会看到它如何去。

The form still comes up under the Powershell session. I'll proceed with working out the threading. I've spawned threads before but never where the parent thread needed to talk to the child thread, so we'll see how it goes.

Thnks所有的想法而已乡亲。

Thnks for all the ideas so far folks.

好吧,穿线花了照顾的问题。 @Quarrelsome,我也尝试两个。无论是(也不两者一起)工作。我很好奇,什么是邪恶关于使用线程?我没有使用Application.Run,​​我还没有到有问题。我使用的是中介类,这两个父线程和子线程访问。在该对象我使用的是ReaderWriterLock锁定一个属性重新presents,我想显示的窗体上的子线程创建的消息。父锁物业然后写的东西应该显示。子线程锁定的财产,并读取它应该改变形式上的标签。这孩子有这样做的一个轮询间隔(我把它默认为500毫秒),这我并不真正感到高兴,但我无法找到一个事件驱动的方式让孩子线程知道proerty发生了变化,所以我中号套牢投票。

Ok, threading it took care of the problem. @Quarrelsome, I did try both of those. Neither (nor both together) worked. I am curious as to what is evil about using threading? I am not using Application.Run and I have yet to have a problem. I am using a mediator class that both the parent thread and the child thread have access to. In that object I am using a ReaderWriterLock to lock one property that represents the message that I want displayed on the form that the child thread creates. The parent locks the property then writes what should be displayed. The child thread locks the property and reads what it should change the label on the form to. The child has to do this on a polling interval (I default it to 500ms) which I'm not real happy about, but I could not find an event driven way to let the child thread know that the proerty had changed, so I'm stuck with polling.

推荐答案

我也遇到了麻烦激活,并带来一个窗口到前台。这里是code,最终为我工作。我不知道这是否会解决您的问题。

I also had trouble activating and bringing a window to the foreground. Here is the code that eventually worked for me. I'm not sure if it will solve your problem.

基本上,调用的ShowWindow(),那么SetForegroundWindow()。

Basically, call ShowWindow() then SetForegroundWindow().

using System.Diagnostics;
using System.Runtime.InteropServices;

// Sets the window to be foreground
[DllImport("User32")]
private static extern int SetForegroundWindow(IntPtr hwnd);

// Activate or minimize a window
[DllImportAttribute("User32.DLL")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SW_SHOW = 5;
private const int SW_MINIMIZE = 6;
private const int SW_RESTORE = 9;

private void ActivateApplication(string briefAppName)
{
    Process[] procList = Process.GetProcessesByName(briefAppName);

    if (procList.Length > 0)
    {
        ShowWindow(procList[0].MainWindowHandle, SW_RESTORE);
        SetForegroundWindow(procList[0].MainWindowHandle);
    }
}

这篇关于C#强制形式焦点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆