调用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()
  {}
  
 
  [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);
 

  
 
  [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
  } [Page]
 

 }
}
________________________________________
窗体代码:
  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 )
  
   const int WM_HOTKEY 0x0312;  
            
   switch(m.Msg) 
   
    case WM_HOTKEY:  
     MessageBox.Show("您点了热键!"); 
     break;
 
    
   base.WndProc(ref );
  }
  //注册热键
  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; [Page]
//   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节点 [Page]
    
    while (reader.Read())
    {
     switch (reader.NodeType)
     {
      case System.Xml.XmlNodeType.Element:// are we parsing <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: [Page]
       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 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 (int) m_hotkey;
   w.WriteString( n.ToString() );
   w.WriteEndElement(); // </hotkey> [Page]
 
   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();//显示热键到文本框

  }
posted @ 2009-08-18 15:10  oraclejava  阅读(424)  评论(0)    收藏  举报