C#写个类操作窗口(句柄操作)
实现过程:
过程一:找到当前鼠标位置的句柄
您的使用 2 个 WinAPI(俺喜欢自己封装下来用):
View Code
[DllImport("user32.dll", EntryPoint = "GetCursorPos")]
public static extern bool GetCursorPos(out Point pt);
[DllImport("user32.dll", EntryPoint = "WindowFromPoint")]
public static extern IntPtr WindowFromPoint(Point pt);
//鼠标位置的坐标
public static Point GetCursorPosPoint()
{
Point p = new Point();
if (GetCursorPos(out p))
{
return p;
}
return default(Point);
}
///
/// 找到句柄
///
///
坐标
///
public static IntPtr GetHandle(Point p)
{
return WindowFromPoint(p);
}
过程二:改变窗口的 Text
您的使用 1 个 WinAPI:
View Code
[DllImport("user32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
///
/// 给窗口发送内容
///
///
句柄
///
要发送的内容
public static void SetText(IntPtr hWnd, string lParam)
{
SendMessage(hWnd, WM_SETTEXT, IntPtr.Zero, lParam);
}
private const int WM_SETTEXT = 0x000C;
通过这个方法就能改变 Text 的值了。
思考:如果俺把这个窗口的句柄记录下来,下次不用鼠标获取,直接就能改变值不蛮好的嘛。
例如:我有个桌面系统老叫我输入用户名,密码。我记录用户名和密码的窗口句柄,然后改变他们的输入值,这样多省事。(只是举例,不考虑安全性)
问题:你会告诉我,窗口句柄的每次重建会变的呀,咋办。
回答:类名不变呀。
过程三:您的准备一些工具吧,例如:句柄找类名呀,类名找句柄什么的等等,下面会用到一些 WinAPI
View Code
[DllImport("user32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string IpClassName, string IpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string
lpszClass, string lpszWindow);
[DllImport("user32.dll", EntryPoint = "GetParent")]
public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCoun
t);
///
/// 找到句柄
///
///
类名
///
public static IntPtr GetHandle(string IpClassName)
{
return FindWindow(IpClassName, null);
}
///
/// 子窗口句柄
///
///
父窗口句柄
///
前一个同目录级同名窗口句柄
///
类名
///
public static IntPtr GetChildHandle(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszCl
{
}
return FindWindowEx(hwndParent, hwndChildAfter, lpszClass, null);
ass)
///
/// 全部子窗口句柄
///
///
父窗口句柄
///
类名
///
public static List
GetChildHandles(IntPtr hwndParent, string className)
{
List resultList = new List();
for (IntPtr hwndClient = GetChildHandle(hwndParent, IntPtr.Zero, className); hwndClient !
= IntPtr.Zero; hwndClient = GetChildHandle(hwndParent, hwndClient, className))
{
resultList.Add(hwndClient);
}
return resultList;
}
///
/// 找类名
///
///
句柄
///
public static string GetClassName(IntPtr hWnd)
{
思考:遍历桌面上所有的窗口,然后找类名,然后改他的 Text,扯淡嘛,相同的类名太多了,找毛呀。
实现:不仅记录类名,而且记录类名在父窗口出现的位置,然后通过桌面一层层找下来,最后找到这个句柄。(虽然不是太准,但是一般的还是能解决了,如果
你有什么好方式一起研究)。
StringBuilder lpClassName = new StringBuilder(128);
if (GetClassName(hWnd, lpClassName, lpClassName.Capacity) == 0)
{
throw new Exception("not found IntPtr!");
}
return lpClassName.ToString();
}
过程四:实现一个 WinHWND 的类,可以把他的规则,他的父窗口类名,以及在父窗口中同类名出现的顺序记录下来,然后通过这些记
录的信息还原句柄。
View Code
public class WinHWND
{
public IntPtr HWND { get; set; }
public string ClassName { get; set; }
public WinHWND Parent { get; set; }
public int InParentSequence { get; set; }
private WinHWND() { }
public WinHWND(IntPtr hWnd)
{
this.HWND = hWnd;
this.ClassName = GetClassName();
this.Parent = GetParent();
this.InParentSequence = GetInParentSequence();
}
private string GetClassName()
{
return WinAPI.GetClassName(this.HWND);
}
private WinHWND GetParent()
{
if (WinAPI.GetParent(this.HWND) == null)
{
throw new Exception("not found IntPtr!");
if (WinAPI.GetParent(this.HWND) == IntPtr.Zero)
{
return null;
return new WinHWND(WinAPI.GetParent(this.HWND));
}
private int GetInParentSequence()
{
}
}
}
IntPtr IntprtParent = this.Parent == null ? IntPtr.Zero : this.Parent.HWND;
return WinAPI.GetChildHandles(IntprtParent, this.ClassName).IndexOf(this.HWND);
public override string ToString()
{
StringBuilder result = new StringBuilder();
for (WinHWND winHandle = this; winHandle != null; winHandle = winHandle.Parent)
{