C#。 WinAPI。借鉴 window
C#. WinApi. Draw on window
我需要编写一个 C# 程序来识别光标下的 window 并在其上绘制边框。
我可以轻松获得 windows 处理程序:
...
Point point;
WinApi.GetCursorPos(out point);
WinApi.WindowFromPoint(point);
...
但我无法借鉴 window...
public static void drawSelectionRectangle(IntPtr handler)
{
Rectangle rectangle;
WinApi.GetWindowRect(handler, out rectangle);
WinApi.PAINTSTRUCT paintProperties;
IntPtr paintContext = WinApi.BeginPaint(handler, out paintProperties);
IntPtr pen = WinApi.CreatePen(WinApi.PenStyle.PS_SOLID, 5, (uint) ColorTranslator.ToWin32(Color.Red));
WinApi.SelectObject(paintContext, pen);
WinApi.Rectangle(paintContext, rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom);
WinApi.ValidateRect(handler, IntPtr.Zero);
WinApi.EndPaint(handler, ref paintProperties);
}
我调用了 drawSelectionRectangle(IntPtr handler)
一次(通过单击按钮)并循环调用(通过 MyForm 的 onPaint()
方法,而不是我想要绘制的表单)。这似乎不起作用。
请帮帮我。我不知道该怎么办。
这不是我的问题的完整解决方案,但它确实有效。
我想在目标 window 上绘制(如果目标 window 位于其他 window 下方,边框也必须位于其他 window 下方)...但是这解决方案(当边框绘制高于所有 windows 时)总比没有好。
我希望我的问题和解决方案对某人有所帮助。谢谢大家^_^.
public partial class Form1 : Form
{
private IntPtr selectedWindowHandler;
...
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
Cursor.Current = new Cursor(Properties.Resources.aimImage.GetHicon());
mousePressed = true;
pictureBox_aimImage.Invalidate();
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
mousePressed = false;
invalidateAllWindows();
}
// this method for pictureBox1 which contain custom cursor
// to choose window for draw border you must click on this box
// and drag to targwt window
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (mousePressed)
{
Point point;
WinApi.GetCursorPos(out point);
IntPtr hWnd = Window.getHandler(point);
if (hWnd.Equals(selectedWindowHandler))
{
drawSelectionRectangle(selectedWindowHandler);
pictureBox_aimImage.Invalidate();
} else
{
selectedWindowHandler = hWnd;
invalidateAllWindows();
}
}
}
// when i once called InvalidateRect(...) not all border was cleared
// i don't know why
private static void invalidateAllWindows()
{
WinApi.InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
WinApi.InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
WinApi.InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
}
...
public static Rectangle getRectangle(IntPtr handler)
{
Rectangle rectangle;
WinApi.GetWindowRect(handler, out rectangle);
rectangle = new Rectangle(
rectangle.Location,
new Size(
rectangle.Size.Width - rectangle.Location.X,
rectangle.Size.Height - rectangle.Location.Y
)
);
return rectangle;
}
public static void drawSelectionRectangle(IntPtr handler)
{
//getting target window rectangle for GDI+
Rectangle rect = getRectangle(handler);
//getting context of desktop
Graphics g = Graphics.FromHwnd(IntPtr.Zero);
using (g)
{
//drawing borders
g.DrawRectangle(new Pen(Color.Red, 3), rect);
}
}
}
我需要编写一个 C# 程序来识别光标下的 window 并在其上绘制边框。
我可以轻松获得 windows 处理程序:
...
Point point;
WinApi.GetCursorPos(out point);
WinApi.WindowFromPoint(point);
...
但我无法借鉴 window...
public static void drawSelectionRectangle(IntPtr handler)
{
Rectangle rectangle;
WinApi.GetWindowRect(handler, out rectangle);
WinApi.PAINTSTRUCT paintProperties;
IntPtr paintContext = WinApi.BeginPaint(handler, out paintProperties);
IntPtr pen = WinApi.CreatePen(WinApi.PenStyle.PS_SOLID, 5, (uint) ColorTranslator.ToWin32(Color.Red));
WinApi.SelectObject(paintContext, pen);
WinApi.Rectangle(paintContext, rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom);
WinApi.ValidateRect(handler, IntPtr.Zero);
WinApi.EndPaint(handler, ref paintProperties);
}
我调用了 drawSelectionRectangle(IntPtr handler)
一次(通过单击按钮)并循环调用(通过 MyForm 的 onPaint()
方法,而不是我想要绘制的表单)。这似乎不起作用。
请帮帮我。我不知道该怎么办。
这不是我的问题的完整解决方案,但它确实有效。
我想在目标 window 上绘制(如果目标 window 位于其他 window 下方,边框也必须位于其他 window 下方)...但是这解决方案(当边框绘制高于所有 windows 时)总比没有好。
我希望我的问题和解决方案对某人有所帮助。谢谢大家^_^.
public partial class Form1 : Form
{
private IntPtr selectedWindowHandler;
...
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
Cursor.Current = new Cursor(Properties.Resources.aimImage.GetHicon());
mousePressed = true;
pictureBox_aimImage.Invalidate();
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
mousePressed = false;
invalidateAllWindows();
}
// this method for pictureBox1 which contain custom cursor
// to choose window for draw border you must click on this box
// and drag to targwt window
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (mousePressed)
{
Point point;
WinApi.GetCursorPos(out point);
IntPtr hWnd = Window.getHandler(point);
if (hWnd.Equals(selectedWindowHandler))
{
drawSelectionRectangle(selectedWindowHandler);
pictureBox_aimImage.Invalidate();
} else
{
selectedWindowHandler = hWnd;
invalidateAllWindows();
}
}
}
// when i once called InvalidateRect(...) not all border was cleared
// i don't know why
private static void invalidateAllWindows()
{
WinApi.InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
WinApi.InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
WinApi.InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
}
...
public static Rectangle getRectangle(IntPtr handler)
{
Rectangle rectangle;
WinApi.GetWindowRect(handler, out rectangle);
rectangle = new Rectangle(
rectangle.Location,
new Size(
rectangle.Size.Width - rectangle.Location.X,
rectangle.Size.Height - rectangle.Location.Y
)
);
return rectangle;
}
public static void drawSelectionRectangle(IntPtr handler)
{
//getting target window rectangle for GDI+
Rectangle rect = getRectangle(handler);
//getting context of desktop
Graphics g = Graphics.FromHwnd(IntPtr.Zero);
using (g)
{
//drawing borders
g.DrawRectangle(new Pen(Color.Red, 3), rect);
}
}
}