在Winform外面画一个圆圈

时间:2014-04-16 11:04:35

标签: c# transparency

我正在使用Windows媒体编码器创建一个屏幕录制应用程序,我可以录制视频并将其保存到磁盘,现在我需要在鼠标点击事件消息时向鼠标点击区域绘制一个实心圆圈(到高点亮鼠标按下事件发生的区域,有没有办法做到这一点?任何代码示例?谢谢!!!抱歉没有在这里插入代码是我的代码

        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; }

最后我做了我需要的东西特别感谢PacMani他指导我正确的方式,

注意:这不是一个完整的代码,其中包含视频中的红色圆圈,这只是为了拥有一个红色圆圈并使透明表单位于所有其他表单之上(对不起)语言错误))谢谢你帮助@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);
    }

1 个答案:

答案 0 :(得分:2)

屏幕录制应用程序将此圈添加到其视频文件中,而不是桌面上。

如果您仍想创建一个圆形窗口,您需要一个表单,其中包含您必须实现的两件事:

您还需要注册一个全局鼠标钩子来检测全局鼠标点击。我想你已经这样做了,但你的问题没有表明你做了什么,不做什么。

如果您单击鼠标,则在鼠标坐标周围创建一个无边框窗口(背景颜色与透明度键相同,以使其在未绘制圆圈时不可见)在其上绘制一个椭圆(钩子) Paint-event并使用Graphics对象DrawEllipse方法)。

启动计时器,此时此窗口再次消失(或者圆圈将永远可见)。如果您希望此圆圈像其他屏幕录制应用程序一样进行动画处理,请使用计时器为绘图设置动画。