李天平的博客


天道酬勤
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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

Posted on 2005-12-03 00:44  李天平  阅读(3565)  评论(2编辑  收藏  举报
      这是在做客服呼叫中心的项目时用到的,是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();//显示热键到文本框
  
  }