C# 允许用户从另一个进程中选择控件/窗口
如何使用户能够从任何窗口选择控件?类似inspect.exe或WinySpy++的程序可以完成(参见屏幕截图) 编辑:C# 允许用户从另一个进程中选择控件/窗口,c#,.net,winforms,winapi,C#,.net,Winforms,Winapi,如何使用户能够从任何窗口选择控件?类似inspect.exe或WinySpy++的程序可以完成(参见屏幕截图) 编辑: “选择一个控件”是指如何在鼠标指针下获得控件的句柄,以便对其进行操作(例如,在其周围绘制框,获取其位置和名称)。我知道我需要使用WinAPI,只是不知道从哪里开始(如何在鼠标指针下获取控件的句柄)。使用GetCursorPos函数获取当前光标位置 使用WindowFromPoint获取包含指定点的窗口 至于画一个矩形,请看。这里有一个开始:(这非常粗糙,需要更多的工作!) 在
“选择一个控件”是指如何在鼠标指针下获得控件的句柄,以便对其进行操作(例如,在其周围绘制框,获取其位置和名称)。我知道我需要使用WinAPI,只是不知道从哪里开始(如何在鼠标指针下获取控件的句柄)。使用
GetCursorPos
函数获取当前光标位置
使用WindowFromPoint
获取包含指定点的窗口
至于画一个矩形,请看。这里有一个开始:(这非常粗糙,需要更多的工作!)
代码>向上显示在
使用
语句与其他进行编码
public partial class Form1 : Form
{
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public const int WM_GETTEXT = 0xD;
public const int WM_GETTEXTLENGTH = 0x000E;
[DllImport("user32.dll")]
public static extern IntPtr WindowFromPoint(Point point);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetClassName(IntPtr handle, StringBuilder ClassName, int MaxCount);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr handle, int msg, int Param1, int Param2);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr handle, int msg, int Param, System.Text.StringBuilder text);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr handle, out RECT Rect);
public class WindowInfo
{
public IntPtr Handle;
public string ClassName;
public string Text;
public Rectangle Rect;
public WindowInfo(IntPtr Handle)
{
this.Handle = Handle;
this.ClassName = GetWindowClassName(Handle);
this.Text = GetWindowText(Handle);
this.Rect = GetWindowRectangle(Handle);
}
}
WindowInfo LastWindow = null;
WindowInfo CurWindow;
public Form1()
{
InitializeComponent();
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
pictureBox1.Cursor = Cursors.Cross;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Point pt = Cursor.Position;
this.Text = "Mouse Position: " + pt.ToString();
this.CurWindow = new WindowInfo(WindowFromPoint(pt));
label1.Text = "Handle: " + this.CurWindow.Handle.ToString("X");
label2.Text = "Class: " + this.CurWindow.ClassName;
label3.Text = "Text: " + this.CurWindow.Text;
label4.Text = "Rectangle: " + this.CurWindow.Rect.ToString();
if (this.LastWindow == null)
{
ControlPaint.DrawReversibleFrame(this.CurWindow.Rect, Color.Black, FrameStyle.Thick);
}
else if (!this.CurWindow.Handle.Equals(this.LastWindow.Handle))
{
ControlPaint.DrawReversibleFrame(this.LastWindow.Rect, Color.Black, FrameStyle.Thick);
ControlPaint.DrawReversibleFrame(this.CurWindow.Rect, Color.Black, FrameStyle.Thick);
}
this.LastWindow = this.CurWindow;
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
pictureBox1.Cursor = Cursors.Default;
if (this.LastWindow != null)
{
ControlPaint.DrawReversibleFrame(this.LastWindow.Rect, Color.Black, FrameStyle.Thick);
// ... do something with "this.LastWindow" ...
}
}
}
public static string GetWindowClassName(IntPtr handle)
{
StringBuilder buffer = new StringBuilder(128);
GetClassName(handle, buffer, buffer.Capacity);
return buffer.ToString();
}
public static string GetWindowText(IntPtr handle)
{
StringBuilder buffer = new StringBuilder(SendMessage(handle, WM_GETTEXTLENGTH,0,0) + 1);
SendMessage(handle, WM_GETTEXT, buffer.Capacity, buffer);
return buffer.ToString();
}
public static Rectangle GetWindowRectangle(IntPtr handle)
{
RECT rect = new RECT();
GetWindowRect(handle, out rect);
return new Rectangle(rect.Left, rect.Top, (rect.Right - rect.Left) + 1, (rect.Bottom - rect.Top) + 1);
}
}
“选择控件”是什么意思?把焦点放在它身上?调用它的关联命令?还有别的吗?它检查操作系统消息。您必须检查Windows API以了解这一点。我已经更新了这个问题,很抱歉没有从一开始就更好地解释它。
GetCursorPos
,WindowFromPoint
。创建一个无边框的最大化表单,将其BackgroundImage属性设置为您使用Graphics.CopyFromScreen()制作的屏幕截图。使用绘制事件绘制矩形。您需要的基本代码在中。其他有用的API调用:GetWindowText、GetClassName、GetWindowLongA、GetWindowRect。。。请访问pinvoke.net获取声明。谢谢。救了我一天