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

Code
  //隐藏窗体,并不在任务栏显示
  private void HideCurrentForm()
  {
   WindowState = FormWindowState.Minimized;
   ShowInTaskbar = false; 
  }
  //显示窗体,并显示在任务栏上
  private void ShowCurrentForm()
  {
   WindowState = FormWindowState.Normal;
   ShowInTaskbar = true;
  }

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

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方法(此部分代码仍来自网上)

Code
        /**//// <summary>
        /// 监视热键
         /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref Message m)//监视Windows消息 
         {
            const int WM_HOTKEY = 0x0312; //如果m.Msg的值为0x0312那么表示用户按下了热键 
              switch (m.Msg)
            {
                case WM_HOTKEY:
                    ProcessHotkey(m); //按下热键时调用ProcessHotkey()函数
                    break;
            }
            base.WndProc(ref m); //将系统消息传递自父类的WndProc 
        }

        //按下设定的键时调用该函数 
        private void ProcessHotkey(Message m)
       {
            IntPtr id = m.WParam; //IntPtr用于表示指针或句柄的平台特定类型 
              string sid = id.ToString();
            switch (sid)
            {
                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

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, 0, 0, 0,0, SWP_HIDEWINDOW);
     //显示窗体
     SetWindowPos(hwnd, HWND_TOP, tempRect.X, tempRect.Y, tempRect.Width - tempRect.X, tempRect.Height - tempRect.Y, SWP_SHOWWINDOW);

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

Code
    private void HideCurrentForm()
    {
         UnregisterHotKey(Handle, 800);
         WindowState = FormWindowState.Minimized;
         ShowInTaskbar = false; 
         RegisterHotKey(Handle, 800, 2, Keys.D0);
    }
    //显示窗体,并显示在任务栏上
     private void ShowCurrentForm()
    {
         UnregisterHotKey(Handle, 800);
         WindowState = FormWindowState.Normal;
         ShowInTaskbar = true;
         RegisterHotKey(Handle, 800, 2, Keys.D0);
    }

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

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

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

  1. Winform中设置BackgroundWorker在取消时关闭后台进程不生效-没有跳出循环

    场景 Winform中设置BackgroundWorker在取消时关闭后台进程: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1 ...

  2. Winform中使用FastReport的PictureObject时通过代码设置图片源并使Image图片旋转90度

    场景 FastReport安装包下载.安装.去除使用限制以及工具箱中添加控件: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  3. Winform中使用FastReport的DesignReport时怎样给通过代码Table添加数据

    场景 FastReport安装包下载.安装.去除使用限制以及工具箱中添加控件: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  4. Winform中使用FastReport的DesignReport时怎样设置Table的size自动调整

    场景 FastReport安装包下载.安装.去除使用限制以及工具箱中添加控件: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  5. Winform中通过NPOI导出Excel时通过ICellStyle和IDataFormat格式化日期显示格式

    场景 Winform中通过NPOI导出Excel的三种方式(HSSFWorkbook,XSSFWorkbook,SXSSFWorkbook)附代码下载: https://blog.csdn.net/B ...

  6. Ubuntu中配置Java环境变量时,出现command not found问题解决记录

    百度出Ubuntu中配置Java环境变量时,在利用sudo gedit /etc/profile 对profile编辑后, 在terminal中输入 sudo source /etc/profile, ...

  7. Winform中设置BackgroundWorker在取消时关闭后台进程

    场景 在Winform中拖拽 一个BackgroundWorker控件,配合进度条控件能开启一个后台线程并报告进度条进度. 但是在执行后台线程的任务时,如果想要取消,怎样让其停止执行. 注: 博客主页 ...

  8. Winform中使用NPOI导出Excel时XSSFWorkbook wb = new XSSFWorkbook()报错

    场景 在使用NPOI导出xlsx格式的Excel时提示: NPOI.POIXMLException类型的未经处理的异常在NPOI.OOXML.dll中发生. 注: 博客主页: https://blog ...

  9. winform中textbox属性Multiline=true时全选

    1.文本框右键属性 => 添加KeyDown事件. 2.添加如下代码: private void txt_result_KeyDown(object sender, KeyEventArgs e ...

最新文章

  1. C# vs. C++/C : 从技术管理角度的分析(附: .Net 在桌面领域的潜敌分析)
  2. .NET 6 使用 string.Create 提升字符串创建和拼接性能
  3. 软件测试技术lab1 2017.3.13
  4. 怎样取消连续包月自动续费_苹果手机连续包月会员怎么取消 设置iPhone解除应用自动续费...
  5. canvas笔记-绘制运动小球(落地弹起,遇边回弹)
  6. read 和write
  7. Android 功耗(22)---MTK 功耗问题分析
  8. 工作中常用到的 Spring 依赖管理技术盘点
  9. SpringCloud学习笔记002---Spring Cloud实战微服务准备
  10. 新基建东风下,开发者这样抓住工业互联网风口!
  11. flutter offset_用Flutter实现58App的首页
  12. Windows服务器系统的端口要求
  13. Oracle安装基本步骤
  14. 游戏框架(Unity3D游戏客户端基础框架)
  15. 小程序中使用全局样式
  16. html消除表格线,html5 消除表格线
  17. 讯时后台编辑器在IE8下无法打开窗口的解决办法
  18. 【天光学术】经济哲学论文:经济哲学视域下的生态危机根源与解决途径
  19. c语言change函数用法,通过值和引用函数
  20. 流量充值解决方案(附代码)

热门文章

  1. bzoj 4653: [Noi2016]区间(尺取+线段树)
  2. bzoj 1066: [SCOI2007]蜥蜴(最大流)
  3. opencv cv.findContours 函数详解
  4. zynq文档学习之向GPIO引脚写数据
  5. 8086的总线操作顺序
  6. 使用与不使用@RequestBody注解的区别
  7. 使用ef查询有缓存的问题
  8. 结对编程-黄金点游戏之旅[二]
  9. iOS安全系列之一:HTTPS
  10. spark视频-spark机器学习