弹出窗口杀手(上)
来源:互联网 发布:千里眼软件 手机 编辑:程序博客网 时间:2024/04/29 03:24
弹出窗口杀手是一个可以自动关闭IE弹出窗口的程序,它工作在系统的托盘中,按照一定的间隔来检测IE窗口,然后关闭弹出窗体。最后,还提供了用热键来杀掉弹出窗口的功能。
虽然已经有类似的用C++写的程序,但是本文讲述的是用C#来实现这些功能,并且本文所讲的方案在查找窗口上的方法要比更快一些。
这是一个崭新的话题,在Internet上我们还可以看到许多类似的程序。但是我也还是要借这个机会来讲述一些下面的技术在C#中如何实现:
l 系统托盘
l 程序切换
l 计时控件
l 查找窗口
l 系统热键
生成一个系统托盘程序
首先,产生一个新的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)
{
// 用最小化来代替关闭操作d
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);
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
- 弹出窗口杀手(上)
- Maxthon弹出窗口杀手
- 弹出窗口杀手
- C#弹出窗口杀手
- C#弹出窗口杀手
- Visual C#弹出窗口杀手
- Visual C#弹出窗口杀手
- Visual C#弹出窗口杀手
- 抢先式弹出窗口杀手
- 抢先式弹出窗口杀手
- Visual C#弹出窗口杀手
- 用C#写弹出窗口杀手
- 第一次学习弹出广告窗口杀手
- Visual C#弹出窗口杀手(1)
- Visual C#弹出窗口杀手(2)
- Visual C#弹出窗口杀手(1)
- Visual C#弹出窗口杀手 (窗口显示隐藏)
- 弹出窗口杀手,加了注释的源代码
- 如何创建一个用弹出窗口来查看详细信息的超链接列
- 看《墨攻》理解IoC概念
- 怎么管
- Linux C 访问数据库操作
- C#农历
- 弹出窗口杀手(上)
- Bugfree2.0+apache+mysql+php在windows2003上配置成功
- 10.3.2 客户端
- dataset的使用方法
- 如何在C#中使用内嵌资源文件
- Hibernate的DAO实现
- 杂谈
- 应用WSDK - 实践WebServices的路由和路由选择(上)
- 启动一个进程并处理进程结束事件