上面的方法在性能上是不错的,因为他过滤了其他非IE的窗口.但是我们可以用一个更简单的方法来实现,就是调用API FindWindowEx(HWND hWndParent, HWND hWndNext, /*in*/LPCTSTR szClassName, /*in*/LPCTSTR szWindowTitle)方法.比较有用的是这句,我们可以使用registered window class name来找到IE窗口(IEFrame是所有打开的IE的标识).
protected void FindPopupToKill() { IntPtr hParent = IntPtr.Zero; IntPtr hNext = IntPtr.Zero; String sClassNameFilter = "IEFrame"; // 所有IE窗口的类 do { hNext = NativeWIN32.FindWindowEx(hParent,hNext,sClassNameFilter,IntPtr.Zero); // we've got a hwnd to play with if ( !hNext.Equals(IntPtr.Zero) ) { // get window caption NativeWIN32.STRINGBUFFER sLimitedLengthWindowTitle; NativeWIN32.GetWindowText(hNext, out sLimitedLengthWindowTitle, 256); String sWindowTitle = sLimitedLengthWindowTitle.szText; if (sWindowTitle.Length>0) { // find this caption in the list of banned captions foreach (ListViewItem item in listView1.Items) { if ( sWindowTitle.StartsWith(item.Text) ) NativeWIN32.SendMessage(hNext, NativeWIN32.WM_SYSCOMMAND, NativeWIN32.SC_CLOSE, IntPtr.Zero); // try soft kill } } } } while (!hNext.Equals(IntPtr.Zero)); } public class NativeWIN32 { [DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern IntPtr FindWindowEx(IntPtr parent /*HWND*/, IntPtr next /*HWND*/, string sClassName, IntPtr sWindowTitle); } |
注册系统热键
系统热键用在像弹出窗口杀手这种应用程序非常有用, Ctrl+Shift+J是缺省热键。
说道实现,我们继续用RegisterHotkey(HWND hWnd, int id, UINT fsModifiers, UINT vkey)。完成,代码如下:
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; // update hotkey 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, m_hotkey); //Keys.J); } 一般的,注册热键要一下几步 /* ------- using HOTKEYs in a C# application ------- -- code snippet by James J Thompson -- 在Form的load 中 : Ctrl+Shift+J bool success = RegisterHotKey(Handle, 100, KeyModifiers.Control | KeyModifiers.Shift, Keys.J); |
在 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"); ProcessHotkey(); break; } base.WndProc(ref m ); } public class NativeWIN32 { [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 } } ------- using HOTKEYs in a C# application ------- */ |
当我们按下热键以后,流程是这样:首先用HWND GetForegroundWindow()来得到窗体,然后要抓出窗体的标题, GetWindowText(HWND hwnd, /*out*/LPTSTR lpString, int nMaxCount). 具体如下:
protected void ProcessHotkey() { IntPtr hwnd = NativeWIN32.GetForegroundWindow(); if (!hwnd.Equals(IntPtr.Zero)) { NativeWIN32.STRINGBUFFER sWindowTitle; NativeWIN32.GetWindowText(hwnd, out sWindowTitle, 256); if (sWindowTitle.szText.Length>0) AddWindowTitle( sWindowTitle.szText ); // add to the ListView (Form) } } |