Question

I am creating a Screen Recording app using Windows media encoder, i Can record the video and save it to a disk,now i need to draw a filled circle around the mouse click area when ever the mouse click event Fire( to high light the area that mouse press event occur), is there a way to do that? any code sample? thank you!!! sorry for not inserting the code here is my code

        public void CaptureMoni()
    {
        string dateTime = DateTime.Now.ToString("yyyy.MM.dd _ HH.mm");
        var dir = @"C:\VIDEOS\" + dateTime;
        try
        {
            System.Drawing.Rectangle _screenRectangle = Screen.PrimaryScreen.Bounds;
            _screenCaptureJob = new ScreenCaptureJob();
            _screenCaptureJob.CaptureRectangle = _screenRectangle;
            _screenCaptureJob.ShowFlashingBoundary = true;
            _screenCaptureJob.ScreenCaptureVideoProfile.FrameRate = 10;
            _screenCaptureJob.CaptureMouseCursor = true;

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
                _screenCaptureJob.OutputScreenCaptureFileName = string.Format(Path.Combine(dir, dateTime + ".wmv"));
            }
        }
        catch (Exception) 
        {
            MessageBox.Show("Screnn Capturing Failed!" );
        }
        string temPath = (_screenCaptureJob.OutputScreenCaptureFileName.ToString());
       // MessageBox.Show(temPath);
    }
    public ScreenCaptureJob _screenCaptureJob { get; set; }

finally i did what i need Special thanks to PacMani he direct me the right way,

NOTE : this is not a full code which include red circle in the video, this is only for having a red circle and making the transparent form on top of the all the other forms (sorry for the language mistakes)) thank you for the Help @ PacMAni

    public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        WindowState = FormWindowState.Maximized;
        this.TopMost = true;


    }
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == (int)RMouseListener.WM.WM_NCHITTEST)
            m.Result = (IntPtr)RMouseListener.WM.HTTRANSPARENT;
        else
            base.WndProc(ref m);
    }
    public void draw_circle()
    {

        int x = MousePosition.X;
        int y = MousePosition.Y;

        System.Drawing.SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Salmon);
        System.Drawing.Graphics formGraphics = this.CreateGraphics();
        formGraphics.FillEllipse(myBrush, new Rectangle(x - 60, y - 60, 60, 60));
        myBrush.Dispose();
        formGraphics.Dispose();
        Thread.Sleep(200);
        this.Invalidate();


    }
    RMouseListener _native;


    private void button1_Click(object sender, EventArgs e)
    {
        //_native = new RMouseListener();
        //_native.RButtonClicked += new EventHandler<SysMouseEventInfo>(_native_RButtonClicked);
        //_native.LButtonClicked += new EventHandler<SysMouseEventInfo>(_native_LButtonClicked);
    }

    private void button2_Click(object sender, EventArgs e)
    {
        _native.Close();
        this.Dispose();
    }
    void _native_RButtonClicked(object sender, SysMouseEventInfo e)
    {

        // listBox1.Items.Add(e.WindowTitle);
        draw_circle();
    }
    void _native_LButtonClicked(object sender, SysMouseEventInfo e)
    {

        // listBox2.Items.Add(e.WindowTitle);
        draw_circle();

    }

    // }


    public class SysMouseEventInfo : EventArgs
    {
        public string WindowTitle { get; set; }
    }

    public class RMouseListener
    {
        Form1 frm = new Form1();
        public RMouseListener()
        {

            this.CallBack += new HookProc(MouseEvents);
            //Module mod = Assembly.GetExecutingAssembly().GetModules()[0];
            //IntPtr hMod = Marshal.GetHINSTANCE(mod);
            using (Process process = Process.GetCurrentProcess())
            using (ProcessModule module = process.MainModule)
            {
                IntPtr hModule = GetModuleHandle(module.ModuleName);
                _hook = SetWindowsHookEx(WH_MOUSE_LL, this.CallBack, hModule, 0);
            }
        }
        int WH_MOUSE_LL = 14;
        int HC_ACTION = 0;
        HookProc CallBack = null;
        IntPtr _hook = IntPtr.Zero;

        public event EventHandler<SysMouseEventInfo> RButtonClicked;
        public event EventHandler<SysMouseEventInfo> LButtonClicked;

        int MouseEvents(int code, IntPtr wParam, IntPtr lParam)
        {
            //Console.WriteLine("Called");
            //MessageBox.Show("Called!");
            if (code < 0)
                return CallNextHookEx(_hook, code, wParam, lParam);

            if (code == this.HC_ACTION)
            {
                // Left button pressed somewhere
                if (wParam.ToInt32() == (uint)WM.WM_RBUTTONDOWN || wParam.ToInt32() == (uint)WM.WM_LBUTTONDOWN)
                {


                    MSLLHOOKSTRUCT ms = new MSLLHOOKSTRUCT();
                    ms = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
                    IntPtr win = WindowFromPoint(ms.pt);
                    string title = GetWindowTextRaw(win);

                    if (RButtonClicked != null || LButtonClicked != null)
                    {
                        RButtonClicked(this, new SysMouseEventInfo { WindowTitle = title });
                        LButtonClicked(this, new SysMouseEventInfo { WindowTitle = title });

                    }
                }
            }
            return CallNextHookEx(_hook, code, wParam, lParam);
        }

        public void Close()
        {
            if (_hook != IntPtr.Zero)
            {
                UnhookWindowsHookEx(_hook);
            }
        }
        public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);

        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowsHookEx", SetLastError = true)]
        public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);

        [DllImport("user32.dll")]
        static extern IntPtr WindowFromPoint(int xPoint, int yPoint);

        [DllImport("user32.dll")]
        static extern IntPtr WindowFromPoint(POINT Point);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, [Out] StringBuilder lParam);

        public static string GetWindowTextRaw(IntPtr hwnd)
        {
            // Allocate correct string length first
            //int length = (int)SendMessage(hwnd, (int)WM.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
            StringBuilder sb = new StringBuilder(65535);//THIS COULD BE BAD. Maybe you shoudl get the length
            SendMessage(hwnd, (int)WM.WM_GETTEXT, (IntPtr)sb.Capacity, sb);
            return sb.ToString();
        }



        [StructLayout(LayoutKind.Sequential)]
        public struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public int mouseData;
            public int flags;
            public int time;
            public UIntPtr dwExtraInfo;
        }
        public enum WM : uint
        {//all windows messages here
            WM_LBUTTONDOWN = 0x0201,
            WM_RBUTTONDOWN = 0x0204,
            WM_GETTEXT = 0x000D,
            WM_GETTEXTLENGTH = 0x000E,
            WM_MOUSE = 0x0200,
            WM_NCHITTEST = 0x84,
            HTTRANSPARENT 

        }


        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;

            public POINT(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        _native = new RMouseListener();
        _native.RButtonClicked += new EventHandler<SysMouseEventInfo>(_native_RButtonClicked);
        _native.LButtonClicked += new EventHandler<SysMouseEventInfo>(_native_LButtonClicked);
    }
Was it helpful?

Solution

Screen recording applications add this circle in their video file, not on the desktop.

If you still want to create a circle window, you need a form with the two things you have to implement:

Also you need to register a global mouse hook to detect global mouse clicks. I think you already did this, but your question does not show what you've done and what not.

If you received a mouse click, create a borderless window around the mouse coordinates and (with the background color being the same as the transparency key to make it invisible where the circle isn't drawn) draw an ellipse on it (hook the Paint-event and use the Graphics objects DrawEllipse method).

Start a timer after which this window disappears again (or the circle would be visible forever). If you want this circle to animate as in other screen recording apps, use the timer to animate the drawing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top