1

Form1:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Draw_on_desktop
{
    public partial class Form1 : Form
    {
        bool IsColorDialogOpened = false;
        int px = 0, py = 0;

        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!chkDraw.Checked || IsColorDialogOpened)
                return;
            int x = Cursor.Position.X;
            int y = Cursor.Position.Y;
            DesktopDrawing.DrawALine(px, py, x, y, 50, lblDrawingColor.BackColor);
            px = x;
            py = y;
        }

        private void lblDrawingColor_Click(object sender, EventArgs e)
        {
            IsColorDialogOpened = true;
            cld.Color = lblDrawingColor.BackColor;
            cld.AllowFullOpen = true;
            cld.ShowDialog(this);
            lblDrawingColor.BackColor = cld.Color;
            IsColorDialogOpened = false;
        }

        private void chkDraw_CheckedChanged(object sender, EventArgs e)
        {
            px = Cursor.Position.X;
            py = Cursor.Position.Y;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

DesktopDrawing class:

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace Draw_on_desktop
{
    public static class DesktopDrawing
    {
        [DllImport("GDI32.dll")]
        private static extern bool DeleteDC(int hdc);
        [DllImport("GDI32.dll")]
        private static extern bool DeleteObject(int hObject);
        [DllImport("GDI32.dll")]
        private static extern int SelectObject(int hdc, int hgdiobj);
        [DllImport("User32.dll")]
        private static extern int GetDesktopWindow();
        [DllImport("User32.dll")]
        private static extern int GetWindowDC(int hWnd);
        [DllImport("GDI32.dll")]
        private static extern int LineTo(int hdc, int x, int y);
        [DllImport("GDI32.dll")]
        private static extern int MoveToEx(int hdc, int x, int y, ref Point lppoint);
        [DllImport("GDI32.dll")]
        private static extern int CreatePen(int penstyle, int width, int color);


        public static void DrawALine(int x1, int y1, int x2, int y2, int width, Color clr)
        {
            Point p = new Point();
            int hdcSrc = GetWindowDC(GetDesktopWindow());
            int newcolor = System.Drawing.ColorTranslator.ToWin32(clr);

            int newpen = CreatePen(0, width, newcolor);
            SelectObject(hdcSrc, newpen);
            MoveToEx(hdcSrc, x1, y1, ref p);
            LineTo(hdcSrc, x2, y2);
            DeleteDC(hdcSrc);
            DeleteObject(newpen);
        }
    }
}

The form1 designer:

namespace Draw_on_desktop
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.chkDraw = new System.Windows.Forms.CheckBox();
            this.lblDrawingColor = new System.Windows.Forms.Label();
            this.cld = new System.Windows.Forms.ColorDialog();
            this.SuspendLayout();
            // 
            // timer1
            // 
            this.timer1.Enabled = true;
            this.timer1.Interval = 1;
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            // 
            // chkDraw
            // 
            this.chkDraw.AutoSize = true;
            this.chkDraw.Location = new System.Drawing.Point(375, 132);
            this.chkDraw.Name = "chkDraw";
            this.chkDraw.Size = new System.Drawing.Size(74, 17);
            this.chkDraw.TabIndex = 0;
            this.chkDraw.Text = "Draw Line";
            this.chkDraw.UseVisualStyleBackColor = true;
            this.chkDraw.CheckedChanged += new System.EventHandler(this.chkDraw_CheckedChanged);
            // 
            // lblDrawingColor
            // 
            this.lblDrawingColor.AutoSize = true;
            this.lblDrawingColor.Location = new System.Drawing.Point(174, 133);
            this.lblDrawingColor.Name = "lblDrawingColor";
            this.lblDrawingColor.Size = new System.Drawing.Size(73, 13);
            this.lblDrawingColor.TabIndex = 1;
            this.lblDrawingColor.Text = "Drawing Color";
            this.lblDrawingColor.Click += new System.EventHandler(this.lblDrawingColor_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Controls.Add(this.lblDrawingColor);
            this.Controls.Add(this.chkDraw);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Timer timer1;
        private System.Windows.Forms.CheckBox chkDraw;
        private System.Windows.Forms.Label lblDrawingColor;
        private System.Windows.Forms.ColorDialog cld;
    }
}

On Form1 the timer enabled true and the interval is set to 1

When drawing over the desktop/screen when it's moving over some places on the form it self or other icons or taskbar it's making spaces or deleting the drawing so far.

Drawing

And if for example I will try to draw over the form1 top right X or the resize it will delete the whole drawing so far.

Dubi Duboni
  • 813
  • 2
  • 17
  • 33
  • 1
    Is this your actual requirement? Do you need to let a user paint over the entire desktop DC? Can you explain what is this application for (to have some context)? – Jimi Dec 22 '18 at 19:43
  • @Jimi I'm using ffmpeg to record the desktop as video if for tutorial or just for showing to others and I like to mark some places on the screen to paint or delete them so they won't show. For example some text I want to paint over and not show it. That's the main idea. The main usage. – Dubi Duboni Dec 22 '18 at 20:32
  • @Jimi I tested it now again on another application window in many spots and areas it's not drawing or deleting the whole drawing. – Dubi Duboni Dec 22 '18 at 20:57
  • 1
    Yes, of course. The Desktop and the applications/controls/other objects are redrawn constantly. This will overwrite your drawing. You'll need a transparent overlay where you can paint and refresh the drawing each time it's necessary. In WinForms, each time a `WM_PAINT` is received, thus in Paint event of the overlay. – Jimi Dec 22 '18 at 21:01
  • @Jimi This lines make the form transparent but then it's hollow I mean I can't draw over it. It's like empty. this.BackColor = Color.Green; this.TransparencyKey = Color.Green; – Dubi Duboni Dec 22 '18 at 21:53
  • That's not really a *solid* Form anymore, it's more a ghost. It's complicated in WinForms to achieve this kind of *transparency* if you haven't done it before (and if you have, too :). You don't have a real *layer* and you can't *talk* to the Graphics card driver. You have to *fake* it, in a way. See these: [Translucent circle with text](https://stackoverflow.com/a/51435842/7444103) -- [Transparent Overlapping Circular Progress Bars](https://stackoverflow.com/a/53379442/7444103). **But** those are child Controls on a Form. The Form itself supports this *transparency* feature (...) – Jimi Dec 23 '18 at 00:03
  • (...) When you have a Form alone, nothing is helping it to maintain its *transparent* status. It can't ask a Parent control to redraw itself. You have to do it yourself, repainting its background from scratch whenever it's necessary. That's the hard part: receiving and handling the notifications and seamlessly redraw the background and what's already drawn on it. Maybe it's a good idea to move to WPF for this. You have DirectX support, at least. – Jimi Dec 23 '18 at 00:04
  • 2
    Are you looking for something like [this](https://stackoverflow.com/q/32389571/3110834)? – Reza Aghaei Dec 23 '18 at 02:52
  • @RezaAghaei Yes more or less. I wonder if I want to show a video here I created how do ppl mark and hide not showing part of the screen ? For example let's say I want to show a video of something I did without showing a small are with the name of the program I'm showing like Unity project name so I want to mark this specific place in the video so it will not show. But I want to keep make things when recording the video. – Dubi Duboni Dec 23 '18 at 05:05
  • 1
    @RezaAghaei Something like this software: http://www.presentation-assistant.com/assistant/index.htm and mostly the Live button in this software. I wonder how they did the Live part. – Dubi Duboni Dec 23 '18 at 05:06

0 Answers0