【发布时间】:2008-09-05 15:25:11
【问题描述】:
所以,在问这个问题之前,我确实搜索了谷歌和 SO。基本上我有一个 DLL,其中编译了一个表单。该表单将用于在屏幕上显示信息。最终它将是异步的,并在 dll 中公开大量自定义。现在我只想让它正确显示。我遇到的问题是我通过在 Powershell 会话中加载它来使用 dll。因此,当我尝试显示表单并将其置于顶部并获得焦点时,它在显示所有其他应用程序时没有问题,但我终生无法将其显示在 Powershell 窗口上.这是我目前用来尝试显示的代码。我敢肯定,一旦我弄清楚了大部分内容就不需要了,这只是代表我通过谷歌找到的所有东西。
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 会话吗?
@Joel,感谢您提供的信息。这是我根据您的建议尝试的:
msgFrm.ShowDialog();
msgFrm.BringToFront();
msgFrm.Focus();
Application.DoEvents();
表单仍然出现在 Powershell 会话下。我将继续解决线程问题。我之前已经产生了线程,但从未在父线程需要与子线程对话的地方产生线程,所以我们将看看它是如何进行的。
感谢大家迄今为止提出的所有想法。
好的,线程解决了这个问题。 @Quarrelsome,我确实尝试了这两种方法。两者都没有(也没有一起)。我很好奇使用线程有什么坏处?我没有使用 Application.Run 并且我还没有遇到问题。我正在使用父线程和子线程都可以访问的中介类。在该对象中,我使用 ReaderWriterLock 来锁定一个属性,该属性表示我希望在子线程创建的表单上显示的消息。父级锁定属性,然后写入应该显示的内容。子线程锁定属性并读取它应该将表单上的标签更改为什么。孩子必须在轮询间隔(我默认为 500 毫秒)上执行此操作,我对此并不满意,但我找不到事件驱动的方式让子线程知道属性已更改,所以我我坚持轮询。
【问题讨论】:
-
你能在表单中的一个控件上调用 Focus() 吗?
-
感谢您的回复。 @Chad,只是尝试 Focus() 表单上的控件,结果与我已经得到的结果相同。 @Dean,我认为要使用您的方法,我需要将表单拆分为自己的线程。我计划在某个时候这样做,所以我想我现在就开始吧。