[英]How to prevent my C# winforms application from stealing focus when I set the visible properly to true?
我有一個在后台運行的C#winforms應用程序,正在監聽要按下的熱鍵。 當按下熱鍵時,我的表格會短暫出現。 表單始終在運行,但設置為隱藏,直到我收到熱鍵事件,此時我將visible屬性設置為true。 代碼如下所示:
void hook_volumeDown(object sender, KeyPressedEventArgs e)
{
this.Visible = true;
}
應該注意,此表單的最頂層屬性設置為true。
真正奇怪的是,在我的C#應用程序從另一個應用程序中竊取焦點后,它將再也不會這樣做了。 例如:我啟動我的應用程序,然后啟動一些像Team Fortress 2這樣的fullscreep應用程序。然后我按下我的熱鍵。 Team Fortress 2最小化,我看到了我的形式。 然而,然后,我可以恢復TF2,並再次按我的熱鍵我想要的(具有所需的效果),TF2將保持聚焦。
無論如何,我正在尋找解決這個問題的方法。 我在這里發現了很多關於類似問題的問題,但是所有問題都與創建/啟動新表單有關,而不是使現有表單可見(除非我遺漏了一些東西)。 我可以重新編寫應用程序,以便在每次需要時創建一個新表單,但這需要創建另一個表單,以便一直看不見只是為了等待熱鍵事件,所以我寧願保持原樣。
有任何想法嗎?
我認為你的問題與Visible = true在第一次和后續調用之間表現不同的事實有關。 第一次調用visible並且尚未創建窗口句柄時,通過調用CreateWindowEx創建Window,它具有一些控制窗口行為方式的樣式參數。 我認為您需要確保使用樣式WS_EX_NOACTIVATE創建窗口,您可以通過覆蓋CreateParams來完成。
其他要試試的東西:
1)ShowWindow函數(由Visible = true使用)在第一次調用時忽略焦點參數( http://msdn.microsoft.com/en-us/library/ms633548%28VS.85%29.aspx )該程序提供了STARTUPINFO結構。 深入研究反射器並找出Form類是否提供STARTUPINFO結構,如果是,則如何操作它。
2)Form有一個ShowWithoutActivation屬性,可以覆蓋並設置為true,你有沒有覆蓋它?
對不起“沒有確切的答案”,但我希望這至少可以為您提供一些進一步調查的起點。 祝好運。
看到你的函數中使用的KeyPressedEventArgs看起來很奇怪。 熱鍵可以通過P / Invoking RegisterHotKey()API函數實現。 當按下熱鍵時,它會向您的窗口發送一條消息。 這是一個在啟動時不可見的表單示例,當您按下熱鍵時彈出。 在這種情況下,按Ctrl + Alt + U:
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
private const int MYKEYID = 0; // In case you want to register more than one...
public Form1() {
InitializeComponent();
this.FormClosing += (s, args) => UnregisterHotKey(this.Handle, MYKEYID);
}
protected override void SetVisibleCore(bool value) {
if (value && !this.IsHandleCreated) {
this.CreateHandle();
RegisterHotKey(this.Handle, MYKEYID, MOD_CONTROL + MOD_SHIFT, Keys.U);
value = false;
}
base.SetVisibleCore(value);
}
protected override void WndProc(ref Message m) {
if (m.Msg == WM_HOTKEY && m.WParam.ToInt32() == MYKEYID) {
this.Visible = true;
if (this.WindowState == FormWindowState.Minimized)
this.WindowState = FormWindowState.Normal;
SetForegroundWindow(this.Handle);
}
base.WndProc(ref m);
}
// P/Invoke declarations
private const int WM_HOTKEY = 0x312;
private const int MOD_ALT = 1;
private const int MOD_CONTROL = 2;
private const int MOD_SHIFT = 4;
[DllImport("user32.dll")]
private static extern int RegisterHotKey(IntPtr hWnd, int id, int modifier, Keys vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
}
}
請注意,SetForegroundWindow()函數可能是您在問題中描述的問題的根源。 當用戶正在使用其他窗口時,Windows不允許應用程序在用戶的臉上推動窗口。 至少幾秒鍾的不活動必須在允許窗口竊取焦點之前到期。 使用給定的代碼,很容易看到,表單的任務欄按鈕將閃爍。 避免將ShowInTaskbar屬性設置為false。 沒有必要使用此代碼,任務欄按鈕將不會顯示,直到按下熱鍵。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.