我有一个在后台运行的应用程序,就像我可以将我的应用程序保存在系统托盘中。如果它仍然在系统托盘上,我的应用程序将完成它的工作。每当用户按F10或F9时,将完成一些工作。我试过这个:
public partial class Form1 : Form
{
public int a = 1;
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
[DllImport("User32.dll")]
private static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey);
[DllImport("User32.dll")]
private static extern short GetAsyncKeyState(System.Int32 vKey);
const int MYACTION_HOTKEY_ID = 1;
public Form1()
{
InitializeComponent();
RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F9);
RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int)Keys.F10);
this.ShowInTaskbar = false;
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID && (GetAsyncKeyState(Keys.F9) == -32767))
{
if ((a % 2) != 0)
{
a++;
MessageBox.Show(a.ToString()+"not equal F9");
label1.Text = "not equal F9";
}
if ((a % 2) == 0)
{
a++;
MessageBox.Show(a.ToString()+"equal F9");
label1.Text = " equal F9";
}
}
else if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID && (GetAsyncKeyState(Keys.F10) == -32767))
{
if ((a % 2) != 0)
{
a++;
MessageBox.Show(a.ToString() + "not equal F10");
label1.Text = "not equal F10";
}
if ((a % 2) == 0)
{
a++;
MessageBox.Show(a.ToString() + "equal F10");
label1.Text = " equal F10";
}
}
base.WndProc(ref m);
}
}
因为我使用设置“this.ShowInTaskbar = false”这一行它不起作用。但如果我没有设置它它工作正常。对于我的应用程序我必须使用这一行。我怎么能解决这个问题? ???
答案 0 :(得分:7)
您需要通过本机函数调用(例如RegisterHotKey()
)订阅操作系统发送的某些消息。调用此函数时通过指定窗口的Handle
告诉操作系统将消息发送到哪个窗口,这可以被视为一个地址。当您设置ShowInTaskbar = false
时,句柄会发生变化,操作系统将无法知道您的联系方式。
见第一个案子:
RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F9);
要解决您的问题,您可以创建一个派生自NativeWindow
的类,其中“提供窗口句柄的低级封装和窗口过程。”并从该类中派生(或至少使用该类的句柄取决于您的实现),使用永远不会改变的句柄注册热键。
public sealed class HotkeyManager : NativeWindow, IDisposable
{
public HotkeyManager()
{
CreateHandle(new CreateParams());
}
protected override void WndProc(ref Message m)
{
if (m.Msg == Constants.WM_HOTKEY)
{
//handle hotkey message
}
base.WndProc(ref m);
}
public void Dispose()
{
DestroyHandle();
}
}
答案 1 :(得分:1)
据我所知,每当您更改“ShowInTaskbar”状态时,都需要重新注册热键。
其他人有类似的问题;见this thread。