admin 管理员组

文章数量: 1087139


2024年3月21日发(作者:什么是web应用)

C#写个类操作窗口(句柄操作)

实现过程:

过程一:找到当前鼠标位置的句柄

您的使用2个WinAPI(俺喜欢自己封装下来用):

View Code

[DllImport("", EntryPoint = "GetCursorPos")]

public static extern bool GetCursorPos(out Point pt);

[DllImport("", 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("", 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, , lParam);

}

private const int WM_SETTEXT = 0x000C;

通过这个方法就能改变Text的值了。

思考:如果俺把这个窗口的句柄记录下来,下次不用鼠标获取,直接就能改变值不蛮好的嘛。

例如:我有个桌面系统老叫我输入用户名,密码。我记录用户名和密码的窗口句柄,然后改变他们的输入值,这样多省事。(只是举例,不考虑安全性)

问题:你会告诉我,窗口句柄的每次重建会变的呀,咋办。

回答:类名不变呀。

过程三:您的准备一些工具吧,例如:句柄找类名呀,类名找句柄什么的等等,下面会用到一些WinAPI

View Code

[DllImport("", EntryPoint = "FindWindow")]

private static extern IntPtr FindWindow(string IpClassName, string IpWindowName);

[DllImport("", EntryPoint = "FindWindowEx")]

private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string

lpszClass, string lpszWindow);

[DllImport("", EntryPoint = "GetParent")]

public static extern IntPtr GetParent(IntPtr hWnd);

[DllImport("", CharSet = )]

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

ass)

{

return FindWindowEx(hwndParent, hwndChildAfter, lpszClass, null);

}

///

/// 全部子窗口句柄

///

/// 父窗口句柄

/// 类名

///

public static List GetChildHandles(IntPtr hwndParent, string className)

{

List resultList = new List();

for (IntPtr hwndClient = GetChildHandle(hwndParent, , className); hwndClient !

= ; hwndClient = GetChildHandle(hwndParent, hwndClient, className))

{

(hwndClient);

}

return resultList;

}

///

/// 找类名

///

/// 句柄

///

public static string GetClassName(IntPtr hWnd)

{

StringBuilder lpClassName = new StringBuilder(128);

if (GetClassName(hWnd, lpClassName, ty) == 0)

{

throw new Exception("not found IntPtr!");

}

return ng();

}

思考:遍历桌面上所有的窗口,然后找类名,然后改他的Text,扯淡嘛,相同的类名太多了,找毛呀

实现:不仅记录类名,而且记录类名在父窗口出现的位置,然后通过桌面一层层找下来,最后找到这个句柄。(虽然不是太准,但是一般的还是能解决了,如果

你有什么好方式一起研究)。

过程四:实现一个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)

{

= hWnd;

ame = GetClassName();

= GetParent();

ntSequence = GetInParentSequence();

}

private string GetClassName()

{

return ssName();

}

private WinHWND GetParent()

{

if (ent() == null)

{

throw new Exception("not found IntPtr!");

}

if (ent() == )

{

return null;

}

return new WinHWND(ent());

}

private int GetInParentSequence()

{

IntPtr IntprtParent = == null ? : ;

return ldHandles(IntprtParent, ame).IndexOf();

}

public override string ToString()

{

StringBuilder result = new StringBuilder();

for (WinHWND winHandle = this; winHandle != null; winHandle = )

{

(("{0}:{1};", Escape(ame),

ng()));

if (ntSequence == -1) break;

}

return ng().TrimEnd(';');

}

private static string GetBaseMark(string sMark)

{

string[] sMarks = (';');

return sMarks[ - 1].Split(':')[0];

}

private static string[] GetChildMarks(string sMark)

{

string[] sMarks = (';');

string[] sChildMarks = new string[ - 1];

for (int i = 0; i < ; i ++ )

{

sChildMarks[i] = sMarks[i ];

}

return sChildMarks;

}

//我一直觉得这段写很丑陋,谁能帮帮我改改

public static WinHWND GetWinHWND(string sMark)

{

List baseHwnds = ldHandles(, GetBaseMark(sMark));

string[] sChildMarks = GetChildMarks(sMark);

//由于主窗口在桌面出现所以很可能同名,所以要看看他的儿子和孙子...是不是都匹配

foreach (IntPtr baseHwnd in baseHwnds)

{

IntPtr handle = baseHwnd;

for (int i = - 1; i >= 0; i--)

{

string[] sChildMark = sChildMarks[i].Split(':');

try

{

handle = ldHandles(handle, UnEscape(sChildMark[0]))[(sC

hildMark[1])];

}

catch

{

break;

}

if (i == 0) return new WinHWND(handle);

}

continue;

}

return null;

}

#region 转义

private static string Escape(string arg)

{

return e(":", ":").Replace(";",";");

}

private static string UnEscape(string arg)

{

return e(":", ":").Replace(";", ";");

}

#endregion

public static WinHWND GetWinHWND()

{

return new WinHWND(dle(sorPosPoint()));

}

}

上全部代码,里面加了窗口的部分属性,扩展其他的属性,自己发挥吧,就是搞WinAPI

View Code

using System;

using c;

using ;

using ;

using pServices;

using g;

using tions;

namespace InformationCollectionDataFill

{

public class WinAPI

{

#region WinodwsAPI

[DllImport("", EntryPoint = "FindWindow")]

private static extern IntPtr FindWindow(string IpClassName, string IpWindowName);

[DllImport("", EntryPoint = "FindWindowEx")]

private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string

lpszClass, string lpszWindow);

[DllImport("", EntryPoint = "SendMessage")]

private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

[DllImport("", EntryPoint = "GetParent")]

public static extern IntPtr GetParent(IntPtr hWnd);

[DllImport("", EntryPoint = "GetCursorPos")]

public static extern bool GetCursorPos(out Point pt);

[DllImport("", EntryPoint = "WindowFromPoint", CharSet = , ExactSpell

ing = true)]

public static extern IntPtr WindowFromPoint(Point pt);

[DllImport("", CharSet = )]

public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCoun

t);

[DllImport("", CharSet = )]

public static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs()]

StringBuilder lpString, int nMaxCount);

[DllImport("", CharSet = )]

public static extern int GetWindowRect(IntPtr hwnd, ref Rectangle rc);

[DllImport("", CharSet = )]

public static extern int GetClientRect(IntPtr hwnd, ref Rectangle rc);

[DllImport("", CharSet = )]

public static extern int MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, bool

bRepaint);

[DllImport("", CharSet = , SetLastError = true, ExactSpelling = true)]

public static extern int ScreenToClient(IntPtr hWnd, ref Rectangle rect);

#endregion

#region 封装API方法

///

/// 找到句柄

///

/// 类名

///

public static IntPtr GetHandle(string IpClassName)

{

return FindWindow(IpClassName, null);

}

///

/// 找到句柄

///

/// 坐标

///

public static IntPtr GetHandle(Point p)

{

return WindowFromPoint(p);

}

//鼠标位置的坐标

public static Point GetCursorPosPoint()

{

Point p = new Point();

if (GetCursorPos(out p))

{

return p;

}

return default(Point);

}

///

/// 子窗口句柄

///

/// 父窗口句柄

/// 前一个同目录级同名窗口句柄

/// 类名

///

public static IntPtr GetChildHandle(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszCl

ass)

{

return FindWindowEx(hwndParent, hwndChildAfter, lpszClass, null);

}

///

/// 全部子窗口句柄

///

/// 父窗口句柄

/// 类名

///

public static List GetChildHandles(IntPtr hwndParent, string className)

{

List resultList = new List();

for (IntPtr hwndClient = GetChildHandle(hwndParent, , className); hwndClient !

= ; hwndClient = GetChildHandle(hwndParent, hwndClient, className))

{

(hwndClient);

}

return resultList;

}

///

/// 给窗口发送内容

///

/// 句柄

/// 要发送的内容

public static void SetText(IntPtr hWnd, string lParam)

{

SendMessage(hWnd, WM_SETTEXT, , lParam);

}

private const int WM_SETTEXT = 0x000C;

///

/// 获得窗口内容或标题

///

/// 句柄

///

public static string GetText(IntPtr hWnd)

{

StringBuilder result = new StringBuilder(128);

GetWindowText(hWnd, result, ty);

return ng();

}

///

/// 找类名

///

/// 句柄

///

public static string GetClassName(IntPtr hWnd)

{

StringBuilder lpClassName = new StringBuilder(128);

if (GetClassName(hWnd, lpClassName, ty) == 0)

{

throw new Exception("not found IntPtr!");

}

return ng();

}

///

/// 窗口在屏幕位置

///

/// 句柄

///

public static Rectangle GetWindowRect(IntPtr hWnd)

{

Rectangle result = default(Rectangle);

GetWindowRect(hWnd, ref result);

return result;

}

///

/// 窗口相对屏幕位置转换成父窗口位置

///

///

///

///

public static Rectangle ScreenToClient(IntPtr hWnd, Rectangle rect)

{

Rectangle result = rect;

ScreenToClient(hWnd, ref result);

return result;

}

///

/// 窗口大小

///

///

///

public static Rectangle GetClientRect(IntPtr hWnd)

{

Rectangle result = default(Rectangle);

GetClientRect(hWnd, ref result);

return result;

}

#endregion

}

public class WinHWND

{

public IntPtr HWND { get; set; }

public string ClassName { get; set; }

public WinHWND Parent { get; set; }

public int InParentSequence { get; set; }

private Rectangle _currentRect;

private string _Text;

private int _Left;

private int _Top;

private int _Width;

private int _Height;

public string Text

{

get

{

return _Text == default(string) ? t() : _Text;

}

set

{

_Text = value;

t(, value);

}

}

public int Left

{

get

{

return _Left == default(int) ? _ : _Left;

}

set

{

_Left = value;

ndow(, value, , , , true);

}

}

public int Top

{

get

{

return _Top == default(int) ? _ : _Top;

}

set

{

_Top = value;

ndow(, , value, , , true);

}

}

public int Width

{

get

{

return _Width == default(int) ? _ : _Width;

}

set

{

_Width = value;

ndow(, , , value, , true);

}

}

public int Height

{

get

{

return _Height == default(int) ? _ : _Height;

}

set

{

_Height = value;

ndow(, , , , value, true);

}

}

private WinHWND() { }

public WinHWND(IntPtr hWnd)

{

= hWnd;

ame = GetClassName();

= GetParent();

ntSequence = GetInParentSequence();

this._currentRect = GetRect();

}

private string GetClassName()

{

return ssName();

}

private WinHWND GetParent()

{

if (ent() == null)

{

throw new Exception("not found IntPtr!");

}

if (ent() == )

{

return null;

}

return new WinHWND(ent());

}

private int GetInParentSequence()

{

IntPtr IntprtParent = == null ? : ;

return ldHandles(IntprtParent, ame).IndexOf();

}

private Rectangle GetRect()

{

if ( == null) return default(Rectangle);

Rectangle clientSize = entRect();

Rectangle clientPoint = ToClient(, dowRect(th

));

return new Rectangle(clientPoint.X, clientPoint.Y, , );

}

public static WinHWND GetWinHWND()

{

return new WinHWND(dle(sorPosPoint()));

}

public override string ToString()

{

StringBuilder result = new StringBuilder();

for (WinHWND winHandle = this; winHandle != null; winHandle = )

{

(("{0}:{1};", Escape(ame),

ng()));

if (ntSequence == -1) break;

}

return ng().TrimEnd(';');

}

private static string GetBaseMark(string sMark)

{

string[] sMarks = (';');

return sMarks[ - 1].Split(':')[0];

}

private static string[] GetChildMarks(string sMark)

{

string[] sMarks = (';');

string[] sChildMarks = new string[ - 1];

for (int i = 0; i < ; i ++ )

{

sChildMarks[i] = sMarks[i];

}

return sChildMarks;

}

//我一直觉得这段写很丑陋,谁能帮帮我改改

public static WinHWND GetWinHWND(string sMark)

{

List baseHwnds = ldHandles(, GetBaseMark(sMark));

string[] sChildMarks = GetChildMarks(sMark);

//由于主窗口在桌面出现所以很可能同名,所以要看看他的儿子和孙子...是不是都匹配

foreach (IntPtr baseHwnd in baseHwnds)

{

IntPtr handle = baseHwnd;

for (int i = - 1; i >= 0; i--)

{

string[] sChildMark = sChildMarks[i].Split(':');

try

{

handle = ldHandles(handle, UnEscape(sChildMark[0]))[(sC

hildMark[1])];

}

catch

{

break;

}

if (i == 0) return new WinHWND(handle);

}

continue;

}

return null;

}

#region 转义

private static string Escape(string arg)

{

return e(":", ":").Replace(";",";");

}

private static string UnEscape(string arg)

{

return e(":", ":").Replace(";", ";");

}

#endregion

}

}

效果

:


本文标签: 句柄 位置 类名 出现 同名