Visual C#弹出窗口杀手之三(转)

本地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);

// 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);

}

代码下载:

演示程序:

[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/79548/viewspace-925508/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/79548/viewspace-925508/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值