First of all, hello, this will be my first question. I wish you a good day. Coming to my question, creating a special crosshair is supported in CSGO or CS2, but unfortunately, this is not supported in old CS games such as CS 1.6. For this reason, I want to draw a special crosshair directly on the monitor using C#. I did what I wanted, but the only problem is that when an application is full screen, the program stops drawing crosses on the screen. How can I solve this problem? How can I draw on the screen even if an application is full screen? I leave my code below, thank you in advance.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace AimChanger
{
public partial class Form1 : Form
{
private bool dragging = false;
private Point dragCursorPoint;
private Point dragFormPoint;
private Timer drawTimer;
private IntPtr desktopPtr;
private Graphics desktopGraphics;
[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("user32.dll")]
public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
[DllImport("gdi32.dll")]
public static extern IntPtr CreatePen(int fnObject, int nWidth, int color);
[DllImport("gdi32.dll")]
public static extern bool SelectObject(IntPtr hdc, IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("user32.dll")]
public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int nWidth, int nHeight, IntPtr hdcSrc, int xSrc, int ySrc, uint dwRop);
public Form1()
{
this.TopMost = true;
InitializeComponent();
InitializeDirectDraw();
pictureBox2.Paint += PictureBox2_Paint;
pictureBox2.MouseDown += PictureBox2_MouseDown;
pictureBox2.MouseMove += PictureBox2_MouseMove;
pictureBox2.MouseUp += PictureBox2_MouseUp;
ApplyRoundedCornersToPictureBox();
textBox1.Text = trackBar1.Value.ToString();
textBox2.Text = trackBar2.Value.ToString();
textBox3.Text = trackBar3.Value.ToString();
textBox4.Text = trackBar4.Value.ToString();
textBox5.Text = trackBar5.Value.ToString();
textBox6.Text = trackBar6.Value.ToString();
textBox7.Text = trackBar7.Value.ToString();
textBox8.Text = trackBar8.Value.ToString();
checkBox2.CheckedChanged += checkBox2_CheckedChanged;
}
private void InitializeDirectDraw()
{
drawTimer = new Timer()
{
Interval = 16
};
drawTimer.Tick += DrawTimer_Tick;
desktopPtr = GetDC(IntPtr.Zero);
desktopGraphics = Graphics.FromHdc(desktopPtr);
}
private void DrawTimer_Tick(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
DrawCustomCrosshair(desktopGraphics);
}
}
private void DrawCustomCrosshair(Graphics g)
{
int screenCenterX = Screen.PrimaryScreen.Bounds.Width / 2;
int screenCenterY = Screen.PrimaryScreen.Bounds.Height / 2;
int size = trackBar1.Value;
int thickness = trackBar2.Value;
int gap = trackBar3.Value;
int alpha = trackBar4.Value;
int outline = trackBar5.Value;
Color crosshairColor = Color.FromArgb(alpha, trackBar6.Value, trackBar7.Value, trackBar8.Value);
g.SmoothingMode = SmoothingMode.AntiAlias;
if (outline > 0)
{
using (Pen outlinePen = new Pen(Color.FromArgb(alpha, Color.Black), thickness + outline * 2))
{
g.DrawLine(outlinePen, screenCenterX - size - gap, screenCenterY, screenCenterX - gap, screenCenterY);
g.DrawLine(outlinePen, screenCenterX + gap, screenCenterY, screenCenterX + size + gap, screenCenterY);
g.DrawLine(outlinePen, screenCenterX, screenCenterY - size - gap, screenCenterX, screenCenterY - gap);
g.DrawLine(outlinePen, screenCenterX, screenCenterY + gap, screenCenterX, screenCenterY + size + gap);
}
}
using (Pen crosshairPen = new Pen(crosshairColor, thickness))
{
g.DrawLine(crosshairPen, screenCenterX - size - gap, screenCenterY, screenCenterX - gap, screenCenterY);
g.DrawLine(crosshairPen, screenCenterX + gap, screenCenterY, screenCenterX + size + gap, screenCenterY);
g.DrawLine(crosshairPen, screenCenterX, screenCenterY - size - gap, screenCenterX, screenCenterY - gap);
g.DrawLine(crosshairPen, screenCenterX, screenCenterY + gap, screenCenterX, screenCenterY + size + gap);
}
if (checkBox2.Checked)
{
int dotSize = 5;
using (Brush dotBrush = new SolidBrush(Color.FromArgb(alpha, trackBar6.Value, trackBar7.Value, trackBar8.Value)))
{
g.FillEllipse(dotBrush, screenCenterX - dotSize / 2, screenCenterY - dotSize / 2, dotSize, dotSize);
}
}
}
private void PictureBox2_Paint(object sender, PaintEventArgs e)
{
DrawGradientText(e.Graphics, pictureBox2.ClientRectangle);
}
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
private static extern IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse);
private void ApplyRoundedCornersToPictureBox()
{
int radius = 30;
IntPtr region = CreateRoundRectRgn(0, 0, pictureBox3.Width, pictureBox3.Height, radius, radius);
pictureBox3.Region = Region.FromHrgn(region);
}
private void DrawGradientText(Graphics g, Rectangle bounds)
{
string text1 = "Crosshair";
string text2 = "Changer";
Font font = new Font("Consolas", 18, FontStyle.Bold);
Point text1Location = new Point(bounds.Left + 10, bounds.Top + 15);
Point text2Location = new Point(bounds.Left + 135, bounds.Top + 15);
using (SolidBrush whiteBrush = new SolidBrush(Color.White))
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.DrawString(text1, font, whiteBrush, text1Location);
}
Rectangle gradientRect = new Rectangle(text2Location, new Size(200, 50));
Color[] colors = { Color.Purple, Color.Red, Color.Orange };
using (LinearGradientBrush brush = new LinearGradientBrush(gradientRect, Color.White, Color.Red, LinearGradientMode.Horizontal))
{
ColorBlend blend = new ColorBlend
{
Colors = colors,
Positions = new float[] { 0f, 0.5f, 1f }
};
brush.InterpolationColors = blend;
g.DrawString(text2, font, brush, text2Location);
}
}
private void ApplyRoundedCorners()
{
int radius = 50;
Region = new Region(new GraphicsPath());
GraphicsPath path = new GraphicsPath();
path.AddArc(0, 0, radius, radius, 180, 90);
path.AddArc(Width - radius, 0, radius, radius, 270, 90);
path.AddArc(Width - radius, Height - radius, radius, radius, 0, 90);
path.AddArc(0, Height - radius, radius, radius, 90, 90);
path.CloseFigure();
Region = new Region(path);
}
private void Form1_Load(object sender, EventArgs e)
{
ApplyRoundedCorners();
}
private void Form1_Resize(object sender, EventArgs e)
{
ApplyRoundedCorners();
}
private void PictureBox2_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
dragging = true;
dragCursorPoint = Cursor.Position;
dragFormPoint = this.Location;
}
}
private void PictureBox2_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
Point diff = new Point(Cursor.Position.X - dragCursorPoint.X, Cursor.Position.Y - dragCursorPoint.Y);
this.Location = new Point(dragFormPoint.X + diff.X, dragFormPoint.Y + diff.Y);
}
}
private void PictureBox2_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
}
private void label2_Click(object sender, EventArgs e)
{
Environment.Exit(0);
}
private void label3_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
textBox1.Text = trackBar1.Value.ToString();
}
private void trackBar2_Scroll(object sender, EventArgs e)
{
textBox2.Text = trackBar2.Value.ToString();
}
private void trackBar3_Scroll(object sender, EventArgs e)
{
textBox3.Text = trackBar3.Value.ToString();
}
private void trackBar4_Scroll(object sender, EventArgs e)
{
textBox4.Text = trackBar4.Value.ToString();
}
private void trackBar5_Scroll(object sender, EventArgs e)
{
textBox5.Text = trackBar5.Value.ToString();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
drawTimer.Start();
}
else
{
drawTimer.Stop();
InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
}
}
[DllImport("user32.dll")]
private static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase);
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (drawTimer != null)
{
drawTimer.Dispose();
}
if (desktopGraphics != null)
{
desktopGraphics.Dispose();
}
if (desktopPtr != IntPtr.Zero)
{
ReleaseDC(IntPtr.Zero, desktopPtr);
}
base.OnFormClosing(e);
}
private void trackBar6_Scroll(object sender, EventArgs e)
{
textBox6.Text = trackBar6.Value.ToString();
}
private void trackBar7_Scroll(object sender, EventArgs e)
{
textBox7.Text = trackBar7.Value.ToString();
}
private void trackBar8_Scroll(object sender, EventArgs e)
{
textBox8.Text = trackBar8.Value.ToString();
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
Invalidate();
}
}
}
Solving the problem and learning the truth
First of all, hello, this will be my first question. I wish you a good day. Coming to my question, creating a special crosshair is supported in CSGO or CS2, but unfortunately, this is not supported in old CS games such as CS 1.6. For this reason, I want to draw a special crosshair directly on the monitor using C#. I did what I wanted, but the only problem is that when an application is full screen, the program stops drawing crosses on the screen. How can I solve this problem? How can I draw on the screen even if an application is full screen? I leave my code below, thank you in advance.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace AimChanger
{
public partial class Form1 : Form
{
private bool dragging = false;
private Point dragCursorPoint;
private Point dragFormPoint;
private Timer drawTimer;
private IntPtr desktopPtr;
private Graphics desktopGraphics;
[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("user32.dll")]
public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
[DllImport("gdi32.dll")]
public static extern IntPtr CreatePen(int fnObject, int nWidth, int color);
[DllImport("gdi32.dll")]
public static extern bool SelectObject(IntPtr hdc, IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("user32.dll")]
public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int nWidth, int nHeight, IntPtr hdcSrc, int xSrc, int ySrc, uint dwRop);
public Form1()
{
this.TopMost = true;
InitializeComponent();
InitializeDirectDraw();
pictureBox2.Paint += PictureBox2_Paint;
pictureBox2.MouseDown += PictureBox2_MouseDown;
pictureBox2.MouseMove += PictureBox2_MouseMove;
pictureBox2.MouseUp += PictureBox2_MouseUp;
ApplyRoundedCornersToPictureBox();
textBox1.Text = trackBar1.Value.ToString();
textBox2.Text = trackBar2.Value.ToString();
textBox3.Text = trackBar3.Value.ToString();
textBox4.Text = trackBar4.Value.ToString();
textBox5.Text = trackBar5.Value.ToString();
textBox6.Text = trackBar6.Value.ToString();
textBox7.Text = trackBar7.Value.ToString();
textBox8.Text = trackBar8.Value.ToString();
checkBox2.CheckedChanged += checkBox2_CheckedChanged;
}
private void InitializeDirectDraw()
{
drawTimer = new Timer()
{
Interval = 16
};
drawTimer.Tick += DrawTimer_Tick;
desktopPtr = GetDC(IntPtr.Zero);
desktopGraphics = Graphics.FromHdc(desktopPtr);
}
private void DrawTimer_Tick(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
DrawCustomCrosshair(desktopGraphics);
}
}
private void DrawCustomCrosshair(Graphics g)
{
int screenCenterX = Screen.PrimaryScreen.Bounds.Width / 2;
int screenCenterY = Screen.PrimaryScreen.Bounds.Height / 2;
int size = trackBar1.Value;
int thickness = trackBar2.Value;
int gap = trackBar3.Value;
int alpha = trackBar4.Value;
int outline = trackBar5.Value;
Color crosshairColor = Color.FromArgb(alpha, trackBar6.Value, trackBar7.Value, trackBar8.Value);
g.SmoothingMode = SmoothingMode.AntiAlias;
if (outline > 0)
{
using (Pen outlinePen = new Pen(Color.FromArgb(alpha, Color.Black), thickness + outline * 2))
{
g.DrawLine(outlinePen, screenCenterX - size - gap, screenCenterY, screenCenterX - gap, screenCenterY);
g.DrawLine(outlinePen, screenCenterX + gap, screenCenterY, screenCenterX + size + gap, screenCenterY);
g.DrawLine(outlinePen, screenCenterX, screenCenterY - size - gap, screenCenterX, screenCenterY - gap);
g.DrawLine(outlinePen, screenCenterX, screenCenterY + gap, screenCenterX, screenCenterY + size + gap);
}
}
using (Pen crosshairPen = new Pen(crosshairColor, thickness))
{
g.DrawLine(crosshairPen, screenCenterX - size - gap, screenCenterY, screenCenterX - gap, screenCenterY);
g.DrawLine(crosshairPen, screenCenterX + gap, screenCenterY, screenCenterX + size + gap, screenCenterY);
g.DrawLine(crosshairPen, screenCenterX, screenCenterY - size - gap, screenCenterX, screenCenterY - gap);
g.DrawLine(crosshairPen, screenCenterX, screenCenterY + gap, screenCenterX, screenCenterY + size + gap);
}
if (checkBox2.Checked)
{
int dotSize = 5;
using (Brush dotBrush = new SolidBrush(Color.FromArgb(alpha, trackBar6.Value, trackBar7.Value, trackBar8.Value)))
{
g.FillEllipse(dotBrush, screenCenterX - dotSize / 2, screenCenterY - dotSize / 2, dotSize, dotSize);
}
}
}
private void PictureBox2_Paint(object sender, PaintEventArgs e)
{
DrawGradientText(e.Graphics, pictureBox2.ClientRectangle);
}
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
private static extern IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse);
private void ApplyRoundedCornersToPictureBox()
{
int radius = 30;
IntPtr region = CreateRoundRectRgn(0, 0, pictureBox3.Width, pictureBox3.Height, radius, radius);
pictureBox3.Region = Region.FromHrgn(region);
}
private void DrawGradientText(Graphics g, Rectangle bounds)
{
string text1 = "Crosshair";
string text2 = "Changer";
Font font = new Font("Consolas", 18, FontStyle.Bold);
Point text1Location = new Point(bounds.Left + 10, bounds.Top + 15);
Point text2Location = new Point(bounds.Left + 135, bounds.Top + 15);
using (SolidBrush whiteBrush = new SolidBrush(Color.White))
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.DrawString(text1, font, whiteBrush, text1Location);
}
Rectangle gradientRect = new Rectangle(text2Location, new Size(200, 50));
Color[] colors = { Color.Purple, Color.Red, Color.Orange };
using (LinearGradientBrush brush = new LinearGradientBrush(gradientRect, Color.White, Color.Red, LinearGradientMode.Horizontal))
{
ColorBlend blend = new ColorBlend
{
Colors = colors,
Positions = new float[] { 0f, 0.5f, 1f }
};
brush.InterpolationColors = blend;
g.DrawString(text2, font, brush, text2Location);
}
}
private void ApplyRoundedCorners()
{
int radius = 50;
Region = new Region(new GraphicsPath());
GraphicsPath path = new GraphicsPath();
path.AddArc(0, 0, radius, radius, 180, 90);
path.AddArc(Width - radius, 0, radius, radius, 270, 90);
path.AddArc(Width - radius, Height - radius, radius, radius, 0, 90);
path.AddArc(0, Height - radius, radius, radius, 90, 90);
path.CloseFigure();
Region = new Region(path);
}
private void Form1_Load(object sender, EventArgs e)
{
ApplyRoundedCorners();
}
private void Form1_Resize(object sender, EventArgs e)
{
ApplyRoundedCorners();
}
private void PictureBox2_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
dragging = true;
dragCursorPoint = Cursor.Position;
dragFormPoint = this.Location;
}
}
private void PictureBox2_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
Point diff = new Point(Cursor.Position.X - dragCursorPoint.X, Cursor.Position.Y - dragCursorPoint.Y);
this.Location = new Point(dragFormPoint.X + diff.X, dragFormPoint.Y + diff.Y);
}
}
private void PictureBox2_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
}
private void label2_Click(object sender, EventArgs e)
{
Environment.Exit(0);
}
private void label3_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
textBox1.Text = trackBar1.Value.ToString();
}
private void trackBar2_Scroll(object sender, EventArgs e)
{
textBox2.Text = trackBar2.Value.ToString();
}
private void trackBar3_Scroll(object sender, EventArgs e)
{
textBox3.Text = trackBar3.Value.ToString();
}
private void trackBar4_Scroll(object sender, EventArgs e)
{
textBox4.Text = trackBar4.Value.ToString();
}
private void trackBar5_Scroll(object sender, EventArgs e)
{
textBox5.Text = trackBar5.Value.ToString();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
drawTimer.Start();
}
else
{
drawTimer.Stop();
InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
}
}
[DllImport("user32.dll")]
private static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase);
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (drawTimer != null)
{
drawTimer.Dispose();
}
if (desktopGraphics != null)
{
desktopGraphics.Dispose();
}
if (desktopPtr != IntPtr.Zero)
{
ReleaseDC(IntPtr.Zero, desktopPtr);
}
base.OnFormClosing(e);
}
private void trackBar6_Scroll(object sender, EventArgs e)
{
textBox6.Text = trackBar6.Value.ToString();
}
private void trackBar7_Scroll(object sender, EventArgs e)
{
textBox7.Text = trackBar7.Value.ToString();
}
private void trackBar8_Scroll(object sender, EventArgs e)
{
textBox8.Text = trackBar8.Value.ToString();
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
Invalidate();
}
}
}
Solving the problem and learning the truth
Share Improve this question edited Feb 14 at 12:36 Olivier Jacot-Descombes 113k14 gold badges147 silver badges198 bronze badges asked Feb 14 at 11:28 kidprogramerkidprogramer 112 bronze badges 9- 1 I don't think there is any easy way to do this, and c# is probably not the best tool to do it. There are several tools that draw overlays. But they tend to be tightly integrated with the direct 3d render pipeline. I'm fairly sure that your current approach is just not applicable with a full screen application. – JonasH Commented Feb 14 at 12:04
- stackoverflow/questions/4388492/… – Denis Schaf Commented Feb 14 at 12:25
- Thanks for help but still idk how can i do that any code suggest? – kidprogramer Commented Feb 14 at 13:16
- 1 You should probably do some research into Direct3D/DirectX. But unless you are already very familiar with graphics APIs, or your time is worthless, it is probably better to just find some existing software that does this, its not like it is a new idea. – JonasH Commented Feb 14 at 15:14
- 1 This question is similar to: WPF and DirectX - Game Overlay. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – Starship Commented Feb 14 at 18:35
1 Answer
Reset to default 0In WinForms, you can set a custom mouse cursur. First create a cursor from an image:
var cursor = new Cursor(Properties.Resources.paintcan_png_cur.GetHicon());
then assign it to a control (your game background or game canvas):
_polygonCanvas.Cursor = cursor;
you can restore the normal cursor with:
_polygonCanvas.Cursor = Cursors.Arrow;
There is a long list of standard cursors exposed as static properties in the Cursor
class.
My cursor from the example above looks like this and displays even colors:
I tried another thing by using the WS_EX_Layered style:
private const int GWL_ExStyle = -20;
private const int WS_EX_Layered = 0x80000;
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
public Form1()
{
InitializeComponent();
FormBorderStyle = FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
TopMost = true;
int initialStyle = GetWindowLong(Handle, GWL_ExStyle);
_ = SetWindowLong(Handle,
GWL_ExStyle, initialStyle | WS_EX_Layered);
Cursor = Cursors.Cross;
}
This displays a crosshair on top of another maximized application; however, it is not possible to interact with the other application.