调用win32 API,实现全局系统热键小结

这是在做客服呼叫中心的项目时用到的,是C/S的windows系统,其中有个模块要实现象QQ那样的热键呼出,所以总结了一下这方面的代码。
//API辅助操作类
using System;
using System.Windows.Forms; // for Key namespace
using System.Runtime.InteropServices;
namespace hotkeytest
{
/// <summary>
/// WIN32 Windows API辅助操作类.
/// </summary>
public class NativeWIN32
{
   public NativeWIN32()
   {}
   /* ------- using WIN32 Windows API in a C# application ------- */
   [DllImport("user32.dll", CharSet=CharSet.Auto)]
   static public extern IntPtr GetForegroundWindow(); //
   [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
    public struct STRINGBUFFER
   {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
    public string szText;
   }
   [DllImport("user32.dll", CharSet=CharSet.Auto)]
   public static extern int GetWindowText(IntPtr hWnd,   out STRINGBUFFER ClassName, int nMaxCount);
   [DllImport("user32.dll", CharSet=CharSet.Auto)]
   public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
   [DllImport("user32.dll", CharSet=CharSet.Auto)]
   public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
   public const int WM_SYSCOMMAND = 0x0112;
   public const int SC_CLOSE = 0xF060;
   public delegate bool EnumThreadProc(IntPtr hwnd, IntPtr lParam);
   [DllImport("user32.dll", CharSet=CharSet.Auto)]
   public static extern bool EnumThreadWindows(int threadId, EnumThreadProc pfnEnum, IntPtr lParam);
   [DllImport("user32.dll", CharSet=CharSet.Auto)]
   public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr next, string sClassName, IntPtr sWindowTitle);

   /* ------- using HOTKEYs in a C# application -------
   in form load :
    bool success = RegisterHotKey(Handle, 100,      KeyModifiers.Control | KeyModifiers.Shift, Keys.J);
   in form closing :
    UnregisterHotKey(Handle, 100);
   
   protected override void WndProc( ref Message m )
   {
    const int WM_HOTKEY = 0x0312;  
   
    switch(m.Msg)
    {
     case WM_HOTKEY:  
      MessageBox.Show("Hotkey pressed");  
      break;
    }  
    base.WndProc(ref m );
   }
   ------- using HOTKEYs in a C# application ------- */
   [DllImport("user32.dll", SetLastError=true)]
   public static extern bool RegisterHotKey( IntPtr hWnd, // handle to window    
    int id,             // hot key identifier    
    KeyModifiers fsModifiers,   // key-modifier options    
    Keys vk             // virtual-key code    
    );
  
   [DllImport("user32.dll", SetLastError=true)]
   public static extern bool UnregisterHotKey( IntPtr hWnd,   // handle to window    
    int id       // hot key identifier    
    );
   [Flags()]
    public enum KeyModifiers
   {  
    None = 0,
    Alt = 1,    
    Control = 2,    
    Shift = 4,    
    Windows = 8
   }

}
}
________________________________________
窗体代码:
   protected const String m_sFilename = "config.xml";
   protected Keys m_hotkey;
   protected bool m_ctrlhotkey, m_shifthotkey, m_althotkey, m_winhotkey;
   //监视热键
   protected override void WndProc( ref Message m )
   {
    const int WM_HOTKEY = 0x0312;  
            
    switch(m.Msg)
    {
     case WM_HOTKEY:  
      MessageBox.Show("您点了热键!");
      break;
    }  
    base.WndProc(ref m );
   }
   //注册热键
   public void SetHotKey(Keys c, bool bCtrl, bool bShift, bool bAlt, bool bWindows)
   {
    //先赋到变量
    m_hotkey = c;
    m_ctrlhotkey = bCtrl;
    m_shifthotkey = bShift;
    m_althotkey = bAlt;
    m_winhotkey = bWindows;
    //注册系统热键
    NativeWIN32.KeyModifiers modifiers = NativeWIN32.KeyModifiers.None;
    if (m_ctrlhotkey)
     modifiers |= NativeWIN32.KeyModifiers.Control;
    if (m_shifthotkey)
     modifiers |= NativeWIN32.KeyModifiers.Shift;
    if (m_althotkey)
     modifiers |= NativeWIN32.KeyModifiers.Alt;
    if (m_winhotkey)
     modifiers |= NativeWIN32.KeyModifiers.Windows;   
    NativeWIN32.RegisterHotKey(Handle, 100, modifiers, c);
   }

   private void Form1_Load(object sender, System.EventArgs e)
   {
    //设置初始热键// default hotkey is Ctrl+Shift+J
//    m_hotkey = Keys.Home;
//    m_hotkey = Keys.J;
//    m_ctrlhotkey = true;
//    m_shifthotkey = true;
//    m_althotkey = false;
//    m_winhotkey = false;
//    SetHotKey(m_hotkey, m_ctrlhotkey, m_shifthotkey, m_althotkey, m_winhotkey);

    //读取配置热键
    LoadSetting();////读配置文件(读取热键到变量)
    ShowHotkey();//显示热键到文本框
   }
   //显示热键到文本框
   public void ShowHotkey()
   {
    String sHotKey = "";
    if (m_ctrlhotkey)
     sHotKey += "Ctrl";
    if (m_shifthotkey)
    {
     if (sHotKey.Length!=0)
      sHotKey += " + ";
     sHotKey += "Shift";
    }
    if (m_althotkey)
    {
     if (sHotKey.Length!=0)
      sHotKey += " + ";
     sHotKey += "Alt";
    }
    if (m_winhotkey)
    {
     if (sHotKey.Length!=0)
      sHotKey += " + ";
     sHotKey += "Win";
    }
    if (sHotKey.Length!=0)
     sHotKey += " + ";
    sHotKey += (char)(int)m_hotkey;
    this.textBox1.Text=sHotKey;
    this.textBox1.Select(0,0);
   }
     //读配置文件 方法2 (读取热键到变量)
   public void LoadSetting()
   {
    System.Xml.XmlTextReader reader = null;   
    if (!System.IO.File.Exists(m_sFilename)) return;
    try
    {              
     reader = new System.Xml.XmlTextReader(m_sFilename);
     reader.WhitespaceHandling = System.Xml.WhitespaceHandling.None;

     bool bEnablePageContent = false; //是否有page节点
     bool bEnableHotkeyContent = false; //是否有hotkey节点
    
     while (reader.Read())
     {
      switch (reader.NodeType)
      {
       case System.Xml.XmlNodeType.Element:// are we parsing a <page> element        
        bEnablePageContent = (reader.Name=="page");//是否有page节点
        bEnableHotkeyContent = (reader.Name=="hotkey");//是否有hotkey节点
        if (bEnableHotkeyContent)
        {
         if (reader["ctrl"]!=null)
          m_ctrlhotkey = (reader["ctrl"]=="true")?true:false;
         if (reader["shift"]!=null)
          m_shifthotkey = (reader["shift"]=="true")?true:false;
         if (reader["alt"]!=null)
          m_althotkey = (reader["alt"]=="true")?true:false;
         if (reader["windows"]!=null)
          m_winhotkey = (reader["windows"]=="true")?true:false;        
        }
        break;
       case System.Xml.XmlNodeType.Text:       
        if (bEnableHotkeyContent)
        {      
         m_hotkey = (Keys) System.Int32.Parse(reader.Value);
         SetHotKey(m_hotkey, m_ctrlhotkey, m_shifthotkey, m_althotkey, m_winhotkey); // register hotkey
        }
        bEnablePageContent = false;
        bEnableHotkeyContent = false;
        break;
       case System.Xml.XmlNodeType.Attribute:
        if (bEnableHotkeyContent)
        {
         if (reader.Name=="ctrl")
          m_ctrlhotkey = (reader.Value=="true")?true:false;
         if (reader.Name=="shift")
          m_shifthotkey = (reader.Value=="true")?true:false;
         if (reader.Name=="alt")
          m_althotkey = (reader.Value=="true")?true:false;
         if (reader.Name=="windows")
          m_winhotkey = (reader.Value=="true")?true:false;
        }
        break;
      }       
     } // end while      
    }
    catch( System.Xml.XmlException e)
    {
     e.ToString();
    }
    finally
    {
     if (reader!=null) reader.Close();
    }
   }
  
   // 存储热键到配置文件
   public void SaveSetting()
   {
    System.Xml.XmlTextWriter w = new System.Xml.XmlTextWriter(m_sFilename, new System.Text.UTF8Encoding());
    w.Formatting = System.Xml.Formatting.Indented;
    w.WriteStartDocument();
    w.WriteStartElement("setting");
    w.WriteStartElement("hotkey"); // <hotkey>
    w.WriteAttributeString("ctrl",m_ctrlhotkey?"true":"false");
    w.WriteAttributeString("shift",m_shifthotkey?"true":"false");
    w.WriteAttributeString("alt",m_althotkey?"true":"false");
    w.WriteAttributeString("windows",m_winhotkey?"true":"false");
    int n = (int) m_hotkey;
    w.WriteString( n.ToString() );
    w.WriteEndElement(); // </hotkey>
    w.WriteEndElement(); // </popupkiller>
    w.Close();
   }
   private void button1_Click(object sender, System.EventArgs e)
   {  
    SetHotKey(m_hotkey, m_ctrlhotkey, m_shifthotkey, m_althotkey, m_winhotkey);
    SaveSetting();
//    Close();
   }
   //设置热键
    private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
   {
//    SetHotKey(e.KeyCode,
//     (ModifierKeys&Keys.Control)>0?true:false,
//     (ModifierKeys&Keys.Shift)>0?true:false,
//     (ModifierKeys&Keys.Alt)>0?true:false,
//     ((ModifierKeys&Keys.LWin)>0||(ModifierKeys&Keys.RWin)>0)?true:false   );
    m_hotkey = e.KeyCode;
    m_ctrlhotkey = (ModifierKeys&Keys.Control)>0?true:false;
    m_shifthotkey = (ModifierKeys&Keys.Shift)>0?true:false;
    m_althotkey = (ModifierKeys&Keys.Alt)>0?true:false;
    m_winhotkey = ((ModifierKeys&Keys.LWin)>0||(ModifierKeys&Keys.RWin)>0)?true:false;
    ShowHotkey();//显示热键到文本框
  
   }
原文地址:https://www.cnblogs.com/MaxWoods/p/1708052.html