所有要用到的API
[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern int EnumWindows(EnumWindowsProc hWnd, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpText, int nCount);
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam);
WM_GETTEXT消息常量:
private const int WM_GETTEXT = 0x00D;
由于每打开一个网页谷歌浏览器的标题就会发生一次变化所以,我们不能用FindWindow来获取谷歌浏览器的句柄。
这里我使用了EnumWindows这个API,具体请自行百度。
声明一个委托(回调函数)
delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
定义委托内容:
static bool FindChrom(IntPtr hWnd, IntPtr lParam)
{
//分配空间
var sb = new StringBuilder(256);
GetWindowText(hWnd, sb, sb.Capacity);
//注意某些窗口没有标题
if (sb.ToString() != String.Empty)
{
if ((sb.ToString().IndexOf("Google Chrome")) != -1)
{
if (hWnd != IntPtr.Zero)
{
IntPtr tb = FindWindowEx(hWnd, new IntPtr(0), "Chrome_OmniboxView", "");
StringBuilder strbld = new StringBuilder(2083);
SendMessage(tb, WM_GETTEXT, 2083, strbld);
_url = strbld.ToString();
}
return false;
}
}
//回调函数有返回值
return true;
}
这里的_url用来存放地址栏的地址,其中2083是url地址有效长度。通过枚举所有顶层窗口,并通过标题判断,获取谷歌浏览器的句柄。其中hWnd参数表示当前枚举窗口的句柄。返回值为true则继续枚举,返回值为false则停止枚举。
完整代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace 禁止登陆指定网站
{
class WindowControlsText
{
//函数指针类型
delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern int EnumWindows(EnumWindowsProc hWnd, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpText, int nCount);
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam);
private const int WM_GETTEXT = 0x00D;
private static string _url;
public string GetWindowText()
{
//IntPtr chrom = FindWindow("Chrome_WidgetWin_1", "百度一下,你就知道 - Google Chrome");
IntPtr chrom=IntPtr.Zero;
EnumWindowsProc enwdproc=new EnumWindowsProc(FindChrom);
if (EnumWindows(enwdproc, IntPtr.Zero) >= 0)
return _url;
else
return null;
}
static bool FindChrom(IntPtr hWnd, IntPtr lParam)
{
//分配空间
var sb = new StringBuilder(256);
GetWindowText(hWnd, sb, sb.Capacity);
//注意某些窗口没有标题
if (sb.ToString() != String.Empty)
{
if ((sb.ToString().IndexOf("Google Chrome")) != -1)
{
if (hWnd != IntPtr.Zero)
{
IntPtr tb = FindWindowEx(hWnd, new IntPtr(0), "Chrome_OmniboxView", "");
StringBuilder strbld = new StringBuilder(2083);
SendMessage(tb, WM_GETTEXT, 2083, strbld);
_url = strbld.ToString();
}
return false;
}
}
//回调函数有返回值
return true;
}
}
}
这里的Chrome_OmniboxView是谷歌浏览器地址栏控件的所属类,通过spy++找到的。
窗口部分实现代码,通过定时器捕捉地址变化:
DispatcherTimer timer2 = new DispatcherTimer();
private void Button_Click_2(object sender, RoutedEventArgs e)
{
timer2.Interval = TimeSpan.FromMilliseconds(500); //获取或设置计时器刻度之间的时间段。
timer2.Tick += timer_Tick2; //超过计时器间隔时发生。
timer2.Start();
}
private void timer_Tick2(object sender, object e)
{
WindowControlsText wct = new WindowControlsText();
string url = wct.GetWindowText();
tbUrl.Text = url;
}