Visual C sharp 弹出窗口杀手.doc_第1页
Visual C sharp 弹出窗口杀手.doc_第2页
Visual C sharp 弹出窗口杀手.doc_第3页
Visual C sharp 弹出窗口杀手.doc_第4页
Visual C sharp 弹出窗口杀手.doc_第5页
免费预览已结束,剩余10页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Visual C#弹出窗口杀手弹出窗口杀手是一个可以自动关闭IE弹出窗口的程序,它工作在系统的托盘中,按照一定的间隔来检测IE窗口,然后关闭弹出窗体。最后,还提供了用热键来杀掉弹出窗口的功能。 虽然已经有类似的用C+写的程序,但是本文讲述的是用C#来实现这些功能,并且本文所讲的方案在查找窗口上的方法要比更快一些。 这是一个崭新的话题,在Internet上我们还可以看到许多类似的程序。但是我也还是要借这个机会来讲述一些下面的技术在C#中如何实现: 系统托盘 程序切换 计时控件 查找窗口 系统热键 生成一个系统托盘程序 首先,产生一个新的C# Windows Form程序, 将NotifyIcon控件从工具箱中拖到窗体中,如下图所示: 在C# windows Form程序中添加托盘 为了保证系统托盘的图标和应用程序的图标一致,我们用一个共同的图标文件a.ico来设置系统托盘的图标和应用程序的图标。 为了使程序不显示在工具栏上,我们可以设置窗体的visible属性为false. 这个可以在窗体属性窗口中直接实现。this.ShowInTaskbar = false; 到目前为止,系统托盘已基本好了,但是我们还没有设置右键菜单,也没有使程序显示和隐藏的功能。程序切换 首先,程序的主窗体可以根据不同的状态来选择显示或者是隐藏,除此之外,我们可以用WindowState设置窗体的状态: public void HideApp() this.WindowState = FormWindowState.Minimized; Hide(); public void ShowApp() Show(); this.WindowState = FormWindowState.Normal; 一个非常有趣的功能是让用户关闭窗体的时候程序并不是退出,为了实现这个功能,我们必须要重写窗体的OnClosing事件。protected override void OnClosing(CancelEventArgs e) / 用最小化来代替关闭操作 e.Cancel = true; / 最小化,并且隐藏窗体 this.WindowState = FormWindowState.Minimized; Hide(); 当然,我们必须要提供一个必须的退出方法.这个可以在托盘的右键菜单的exit中实现, private void menu_App_Exit(object sender, System.EventArgs e) NativeWIN32.UnregisterHotKey(Handle, 100); /隐藏托盘 notifyIcon1.Visible = false; Application.Exit(); 添加右键菜单 添加一个右键菜单和添加托盘基本一样,从工具箱中添加context menu就可以.右键菜单在你鼠标右键按下的时候是会自动弹出的。当设置好右键菜单以后,我们必要要根据不同的情况来启用或停用右键菜单,这个可以通过在菜单的BeforePopup设置。Enabled属性来实现。 private void menu_App_BeforePopup(object sender, System.EventArgs e) if ( this.WindowState = FormWindowState.Minimized ) App_Show.Enabled = true; App_Hide.Enabled = false; else App_Show.Enabled = false; App_Hide.Enabled = true; 计时工具 .Net Framework的 Timer能和系统的Win32 timer实现一样的功能。我们要做的就是设置一个timer,然后合理的设置属性。m_Timer = new System.Timers.Timer(); / explicit namespace (Timer also in System.Threading) m_Timer.Elapsed += new ElapsedEventHandler(OnTimerKillPopup); m_Timer.Interval = m_nInterval; / for instance 3000 milliseconds m_Timer.Enabled = true; / start timer protected void OnTimerKillPopup(Object source, ElapsedEventArgs e) m_Timer.Enabled = false; / pause the timer FindPopupToKill(); m_Timer.Enabled = true; 本地win32窗体查找 本程序的实现原理是这样,先检查所有的IE窗口标题,然后于已经有的列表来比较,如果有相同的,我们就关闭这个窗口。按照上面的方法,我们每n妙使用KillPopup()来检查。比较遗憾的是我们无法使用安全代码来完成所有的工作。我们可以使用 System.Diagnostics.Proces来检查所有的IE进程,然后得到主窗体。但是每一个IE进程可以打开好几个窗口,虽然每一个窗体都于一个进程相关,但是还没有办法来使每一个窗体于进程对应起来。一个可行的办法使用System.Diagnostics.Process列举出所有的运行的进程,然后System.Diagnostics.ProcessThreadCollection 来得到他们的.Threads属性,为了得到thread Id,我们使用Win32 API EnumThreadWindows(DWORD threadId,WNDENUMPROC lpfn,LPARAM lParam) 来实现,这是一个回调(call back)函数,他可以列举出于进程相关的窗体。当我们得到了窗体的句柄以后,我们可以使用另一个API函数 GetWindowText(HWND hwnd,/*out*/LPTSTR lpString,int nMaxCount)来得到窗体的标题,然后根据已经有的窗体,调用API函数SendMessage(HWND hWnd,int msg,int wParam,int lParam)来关闭窗口。下面使演示代码 Process myProcesses = Process.GetProcessesByName(IEXPLORE); foreach(Process myProcess in myProcesses) FindPopupToKill(myProcess); protected void FindPopupToKill(Process p) / traverse all threads and enum all windows attached to the thread foreach (ProcessThread t in p.Threads) int threadId = t.Id; NativeWIN32.EnumThreadProc callbackProc = new NativeWIN32.EnumThreadProc(MyEnumThreadWindowsProc); NativeWIN32.EnumThreadWindows(threadId, callbackProc, IntPtr.Zero /*lParam*/); / callback used to enumerate Windows attached to one of the threads bool MyEnumThreadWindowsProc(IntPtr hwnd, IntPtr lParam) public const int WM_SYSCOMMAND = 0x0112; public const int SC_CLOSE = 0xF060; / get window caption NativeWIN32.STRINGBUFFER sLimitedLengthWindowTitle; NativeWIN32.GetWindowText(hwnd, out sLimitedLengthWindowTitle, 256); String sWindowTitle = sLimitedLengthWindowTitle.szText; if (sWindowTitle.Length=0) return true; / find this caption in the list of banned captions foreach (ListViewItem item in listView1.Items) if ( sWindowTitle.StartsWith(item.Text) ) NativeWIN32.SendMessage(hwnd, NativeWIN32.WM_SYSCOMMAND, NativeWIN32.SC_CLOSE, IntPtr.Zero); / try soft kill return true; public class NativeWIN32 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); / used for an output LPCTSTR parameter on a method call 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); 上面的方法在性能上是不错的,因为他过滤了其他非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); / weve 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.Length0) / 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 Ke

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论