winform中ShowInTaskbar设为false时,注册的热键失效的问题解决

      最近一个项目需要实现通过热键控制界面的显示和隐藏的效果。抛开热键的问题,先来看界面的显示和隐藏,.net中通过以下两个方法实现:

ContractedBlock.gif ExpandedBlockStart.gif Code
  //隐藏窗体,并不在任务栏显示
  private void HideCurrentForm()
ExpandedBlockStart.gifContractedBlock.gif  
{
   WindowState 
= FormWindowState.Minimized;
   ShowInTaskbar 
= false
  }

  
//显示窗体,并显示在任务栏上
  private void ShowCurrentForm()
ExpandedBlockStart.gifContractedBlock.gif  
{
   WindowState 
= FormWindowState.Normal;
   ShowInTaskbar 
= true;
  }

      

      OK,经测试没有问题。下面来考虑热键的问题。查了一下MSDN,没有在.NET类库中找到注册和销毁热键的方法,于是决定调用WIN32 API来实现。搜索后得到以下代码:

ContractedBlock.gif ExpandedBlockStart.gif Code
[System.Runtime.InteropServices.DllImport("user32.dll")] //申明API函数 
public static extern bool RegisterHotKey(
IntPtr hWnd, 
// handle to window 
int id, // hot key identifier 
uint fsModifiers, // key-modifier options 
Keys vk // virtual-key code 
);

[System.Runtime.InteropServices.DllImport(
"user32.dll")] //申明API函数 
public static extern bool UnregisterHotKey(
IntPtr hWnd, 
// handle to window 
int id // hot key identifier 
); 

        

       于是在主界面的构造函数中增加注册热键的代码
 

 

RegisterHotKey(Handle,  800 2 , Keys.D0);

 

       同时,覆载Form类的WndProc方法(此部分代码仍来自网上)

ContractedBlock.gif ExpandedBlockStart.gif Code
ExpandedBlockStart.gifContractedBlock.gif        /**//// <summary>
        
/// 监视热键
         
/// </summary>
        
/// <param name="m"></param>

        protected override void WndProc(ref Message m)//监视Windows消息 
ExpandedBlockStart.gifContractedBlock.gif
         {
            
const int WM_HOTKEY = 0x0312//如果m.Msg的值为0x0312那么表示用户按下了热键 
              switch (m.Msg)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
case WM_HOTKEY:
                    ProcessHotkey(m); 
//按下热键时调用ProcessHotkey()函数
                    break;
            }

            
base.WndProc(ref m); //将系统消息传递自父类的WndProc 
        }


        
//按下设定的键时调用该函数 
        private void ProcessHotkey(Message m)
ExpandedBlockStart.gifContractedBlock.gif       
{
            IntPtr id 
= m.WParam; //IntPtr用于表示指针或句柄的平台特定类型 
              string sid = id.ToString();
            
switch (sid)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
case "800":// 按下Control + 0 切换窗体状态
                    CutOverForm();//切换界面的显示和隐藏状态
                    break;
            }

       }


      其中CutOverForm()方法负责切换界面的显示。
      但是,一测试,不好,当我通过热键将窗口隐藏后,无论如何也无法将其再次显示出来了。设断电,调试,发现第一次热键有效,第二次就无法触发热键了。反复测试发现当我把HideCurrentForm()中的ShowInTaskbar设为true时,则可以连续触发热键,但显然无法满足项目的需求。于是,继续搜索,发现也有人http://blog.csdn.net/Yasker/archive/2006/02/22/606294.aspx遇到了同样的问题,只要在代码中将ShowInTaskbar设为false,则热键立即失效,但找了很久也没有找到解决方案,于是,准备转向WIN32 API。在网上搜索到参考代码
 http://read.pudn.com/downloads63/sourcecode/windows/csharp/222835/%CF%D4%CA%BE%D2%FE%B2%D8%B3%CC%D0%F2/WindowsApplication1/Form1.cs__.htm

 

ContractedBlock.gif ExpandedBlockStart.gif Code
    [DllImport("user32")]
    
private static extern int SetWindowPos(IntPtr hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);

     
//隐藏窗体
     SetWindowPos(hwnd, HWND_BOTTOM, 000,0, SWP_HIDEWINDOW);
     
//显示窗体
     SetWindowPos(hwnd, HWND_TOP, tempRect.X, tempRect.Y, tempRect.Width - tempRect.X, tempRect.Height - tempRect.Y, SWP_SHOWWINDOW);

  

      测试,测试,大喜:)
      正在我准备收工的时候,无意间看到参考代码中的一个方法中有对ShowInTaskbar的操作,而在前面的代码中其执行的是销毁热键的操作,之后接着重新注册热键。这个,难道?马上测试

ContractedBlock.gif ExpandedBlockStart.gif Code
    private void HideCurrentForm()
ExpandedBlockStart.gifContractedBlock.gif    
{
         UnregisterHotKey(Handle, 
800);
         WindowState 
= FormWindowState.Minimized;
         ShowInTaskbar 
= false
         RegisterHotKey(Handle, 
8002, Keys.D0);
    }

    
//显示窗体,并显示在任务栏上
     private void ShowCurrentForm()
ExpandedBlockStart.gifContractedBlock.gif    
{
         UnregisterHotKey(Handle, 
800);
         WindowState 
= FormWindowState.Normal;
         ShowInTaskbar 
= true;
         RegisterHotKey(Handle, 
8002, Keys.D0);
    }

 

       运行,Ctrl + 0,来回切换,成功!困扰了自己好几天问题原来在这!!只是当改变ShowInTaskbar的属性为false,为何热键会失效呢?不知哪位可以帮忙解释一下?本人Form下的开发刚刚入门,实在是无从查起:(

 

转载于:https://www.cnblogs.com/zhangyz215/archive/2009/04/17/1438141.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值