예제 #1
0
        protected override void ProcessRecord()
        {
            if (hWnd == IntPtr.Zero)
            {
                hWnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
            }


            WindowInformation result = new WindowInformation();

            Rectangle rect = GetWindowRectangle(hWnd);

            result.X      = rect.X;
            result.Y      = rect.Y;
            result.Height = rect.Height;
            result.Width  = rect.Width;

            if (USER32.IsIconic(hWnd))
            {
                result.State = WindowState.Minimized;
            }
            else if (USER32.IsZoomed(hWnd))
            {
                result.State = WindowState.Maximized;
            }


            WriteObject(result);
        }
예제 #2
0
파일: KeyInput.cs 프로젝트: wljsfw/Overmind
        /// <summary>
        /// Generates a key press event
        /// </summary>
        /// <param name="vkCode">Virtual code of key</param>
        /// <param name="alt">ALT is pressed</param>
        /// <param name="ctrl">CTRL is pressed</param>
        /// <param name="shift">SHIFT is pressed</param>
        public void KeyPress(Keys vkCode, bool alt, bool ctrl, bool shift)
        {
            USER32.INPUT[] inputs = new USER32.INPUT[2];

            USER32.INPUT si = new USER32.INPUT();
            si.type       = USER32.INPUTFlags.INPUT_KEYBOARD;
            si.ki         = new USER32.KEYBDINPUT();
            si.ki.wVk     = (ushort)vkCode;
            si.ki.wScan   = (ushort)USER32.MapVirtualKey((ushort)vkCode, USER32.MapType.MAPVK_VK_TO_VSC);
            si.ki.time    = 0;
            si.ki.dwFlags = 0;
            //si.ki.dwExtraInfo = USER32.GetMessageExtraInfo();
            inputs[0] = si;

            si            = new USER32.INPUT();
            si.type       = USER32.INPUTFlags.INPUT_KEYBOARD;
            si.ki         = new USER32.KEYBDINPUT();
            si.ki.wVk     = (ushort)vkCode;
            si.ki.wScan   = (ushort)USER32.MapVirtualKey((ushort)vkCode, USER32.MapType.MAPVK_VK_TO_VSC);
            si.ki.time    = 0;
            si.ki.dwFlags = (uint)USER32.INPUTFlags.KEYEVENTF_KEYUP;
            //si.ki.dwExtraInfo = USER32.GetMessageExtraInfo();
            inputs[1] = si;

            USER32.SendInput(2, inputs, Marshal.SizeOf(si));
            // ALTERNATE:
            //this.KeyDown(vkCode);
            //this.KeyUp(vkCode);
        }
예제 #3
0
        /// <summary>
        /// Generates a mouse move event
        /// </summary>
        /// <param name="x">X position/offset of screen</param>
        /// <param name="y">Y position/offset of screen</param>
        /// <param name="absolute">Use absolute coordinates or relative coordinates</param>
        public void MouseMove(int x, int y, bool absolute = true)
        {
            USER32.INPUT[] inputs = new USER32.INPUT[1];

            USER32.INPUT si = new USER32.INPUT();
            si.type           = USER32.INPUTFlags.INPUT_MOUSE;
            si.mi             = new USER32.MOUSEINPUT();
            si.mi.dx          = x;
            si.mi.dy          = y;
            si.mi.mouseData   = 0;
            si.mi.time        = 0;
            si.mi.dwExtraInfo = USER32.GetMessageExtraInfo();

            if (absolute)
            {
                int _v = USER32.GetSystemMetrics(SystemMetric.SM_CXSCREEN);
                _v = USER32.GetSystemMetrics(SystemMetric.SM_CYSCREEN);
                float wpx = 65535.0f / USER32.GetSystemMetrics(SystemMetric.SM_CXSCREEN);
                float hpx = 65535.0f / USER32.GetSystemMetrics(SystemMetric.SM_CYSCREEN);
                si.mi.dx      = (int)(si.mi.dx * wpx);
                si.mi.dy      = (int)(si.mi.dy * hpx);
                si.mi.dwFlags = (uint)(USER32.INPUTFlags.MOUSEEVENTF_MOVE | USER32.INPUTFlags.MOUSEEVENTF_ABSOLUTE | USER32.INPUTFlags.MOUSEEVENTF_VIRTUALDESK);
            }
            else
            {
                si.mi.dwFlags = (uint)USER32.INPUTFlags.MOUSEEVENTF_MOVE;
            }

            inputs[0] = si;
            USER32.SendInput(1, inputs, Marshal.SizeOf(si));
        }
예제 #4
0
        /// <summary>
        /// Takes the snapshot of the window owned by a process
        /// </summary>
        /// <param name="name">The process name</param>
        /// <returns>Bitmap object</returns>
        public static Bitmap ProcessSnapshot(string name)
        {
            IntPtr hwnd = IntPtr.Zero;

            foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName(name))
            {
                if (p.MainWindowHandle != IntPtr.Zero)
                {
                    hwnd = p.MainWindowHandle;
                    break;
                }
            }

            if (hwnd == IntPtr.Zero)
            {
                return(null);
            }
            else
            {
                USER32.RECT rc;
                USER32.GetWindowRect(hwnd, out rc);
                Rectangle r      = ApiConverter.ToRectangle(rc);
                Bitmap    bitmap = new Bitmap(r.Width, r.Height, PixelFormat.Format24bppRgb);
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    IntPtr hdcBitmap = g.GetHdc();
                    USER32.PrintWindow(hwnd, hdcBitmap, 0);
                }
                return(bitmap);
            }
        }
예제 #5
0
        }                                                                     // end method Desktop

        /// <summary>
        /// Captures the desktop work area to a bitmap image
        /// </summary>
        /// <returns>bitmap image of desktop work area</returns>
        public static Bitmap DesktopWA(Control ctl)
        {
            Rectangle wa          = Screen.GetWorkingArea(ctl);                 // working area of screen
            IntPtr    desktopHWND = USER32.GetDesktopWindow();                  // window handle for desktop

            return(Window(desktopHWND, wa.X, wa.Y, wa.Width, wa.Height));       // return bitmap for desktop
        }
예제 #6
0
        public static Size GetDesktopSize()
        {
            int width  = USER32.GetSystemMetrics(USER32.SM_CXSCREEN);   // width of desktop
            int height = USER32.GetSystemMetrics(USER32.SM_CYSCREEN);   // height of desktop

            return(new Size(width, height));
        }
예제 #7
0
        /// <summary>
        /// Draws cursor onto the bitmap
        /// </summary>
        /// <param name="bmp">Source bitmap</param>
        /// <returns>Bitmap object</returns>
        public static Bitmap PlaceCursor(Bitmap bmp)
        {
            Graphics g = Graphics.FromImage(bmp);
            {
                USER32.CURSORINFO ci = new USER32.CURSORINFO();
                ci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(ci);
                USER32.GetCursorInfo(out ci);

                USER32.ICONINFO icInfo;
                if (ci.flags == USER32.CURSORINFOFlags.CURSOR_SHOWING && ci.hCursor.ToInt32() != 0)
                {
                    IntPtr hicon = USER32.CopyIcon(ci.hCursor);
                    int    x     = System.Windows.Forms.Cursor.Position.X;
                    int    y     = System.Windows.Forms.Cursor.Position.Y;

                    if (USER32.GetIconInfo(hicon, out icInfo))
                    {
                        x = ci.ptScreenPos.X - ((int)icInfo.xHotspot);
                        y = ci.ptScreenPos.Y - ((int)icInfo.yHotspot);
                    }

                    try
                    {
                        //ic.ToBitmap();
                        //g.DrawImage(ic.ToBitmap(), System.Windows.Forms.Cursor.Position.X, System.Windows.Forms.Cursor.Position.Y);
                        g.DrawIcon(Icon.FromHandle(ci.hCursor), x, y);
                        USER32.DestroyIcon(hicon);
                    }
                    catch (Exception) {}
                }
                return(bmp);
            }
        }
예제 #8
0
            /// <summary>
            /// Captures the window or part thereof to a bitmap image.
            /// </summary>
            /// <param name="wndHWND">window handle</param>
            /// <param name="x">x location in window</param>
            /// <param name="y">y location in window</param>
            /// <param name="width">width of capture area</param>
            /// <param name="height">height of capture area</param>
            /// <returns>window bitmap</returns>
            public static Bitmap Window(IntPtr wndHWND, int x, int y, int width, int height)
            {
                IntPtr wndHDC = USER32.GetDC(wndHWND);          // get context for window

                //	create compatibile capture context and bitmap
                IntPtr capHDC = GDI32.CreateCompatibleDC(wndHDC);
                IntPtr capBMP = GDI32.CreateCompatibleBitmap(wndHDC, width, height);

                //	make sure bitmap non-zero
                if (capBMP == IntPtr.Zero)                      // if no compatible bitmap
                {
                    USER32.ReleaseDC(wndHWND, wndHDC);          //   release window context
                    GDI32.DeleteDC(capHDC);                     //   delete capture context
                    return(null);                               //   return null bitmap
                }

                //	select compatible bitmap in compatible context
                //	copy window context to compatible context
                //  select previous bitmap back into compatible context
                IntPtr prvHDC = (IntPtr)GDI32.SelectObject(capHDC, capBMP);

                GDI32.BitBlt(capHDC, 0, 0, width, height, wndHDC, x, y, GDI32.SRCCOPY);
                GDI32.SelectObject(capHDC, prvHDC);

                //	create GDI+ bitmap for window
                Bitmap bmp = System.Drawing.Image.FromHbitmap(capBMP);

                //	release window and capture resources
                USER32.ReleaseDC(wndHWND, wndHDC);                      // release window context
                GDI32.DeleteDC(capHDC);                                 // delete capture context
                GDI32.DeleteObject(capBMP);                             // delete capture bitmap

                //	return bitmap image to user
                return(bmp);                                                                     // return bitmap
            }
예제 #9
0
        /// <summary>
        /// Generates a mouse down event
        /// </summary>
        /// <param name="button">Mouse button</param>
        public void MouseDown(MouseButtons button)
        {
            USER32.INPUT[] inputs = new USER32.INPUT[1];

            USER32.INPUT si = new USER32.INPUT();
            si.type           = USER32.INPUTFlags.INPUT_MOUSE;
            si.mi             = new USER32.MOUSEINPUT();
            si.mi.dx          = 0;
            si.mi.dy          = 0;
            si.mi.mouseData   = 0;
            si.mi.time        = 0;
            si.mi.dwExtraInfo = USER32.GetMessageExtraInfo();

            switch (button)
            {
            case MouseButtons.Left:
                si.mi.dwFlags = (uint)USER32.INPUTFlags.MOUSEEVENTF_LEFTDOWN;
                break;

            case MouseButtons.Middle:
                si.mi.dwFlags = (uint)USER32.INPUTFlags.MOUSEEVENTF_MIDDLEDOWN;
                break;

            case MouseButtons.Right:
                si.mi.dwFlags = (uint)USER32.INPUTFlags.MOUSEEVENTF_RIGHTDOWN;
                break;
            }

            inputs[0] = si;
            USER32.SendInput(1, inputs, Marshal.SizeOf(si));
        }
예제 #10
0
        /// <summary>
        /// Captures the desktop to a bitmap image
        /// </summary>
        /// <returns>bitmap image of the desktop</returns>
        public static Bitmap Desktop()
        {
            int    width       = USER32.GetSystemMetrics(USER32.SM_CXSCREEN); // width of desktop
            int    height      = USER32.GetSystemMetrics(USER32.SM_CYSCREEN); // height of desktop
            IntPtr desktopHWND = USER32.GetDesktopWindow();                   // window handle for desktop

            return(Window(desktopHWND, 0, 0, width, height));                 // return bitmap for desktop
        }                                                                     // end method Desktop
예제 #11
0
        public void SetPosition(IntPtr hWnd, int x, int y, int width, int height)
        {
            USER32.SWP param = USER32.SWP.NOACTIVATE;
            if (width + height <= 0)
            {
                param |= USER32.SWP.NOSIZE;
            }

            USER32.SetWindowPos(hWnd, IntPtr.Zero, x, y, width, height, USER32.SWP.NOACTIVATE);
        }
예제 #12
0
        /// <summary>
        /// Enables the hook
        /// </summary>
        /// <returns>True if hook is enabled</returns>
        public bool EnableHook()
        {
            if (this.mseHook != IntPtr.Zero)
            {
                return(true);
            }

            this.mseHook = USER32.SetWindowsHookEx(HookType.WH_MOUSE_LL, this.mseCallbackDelegate, KERNEL32.GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
            return(this.mseHook != IntPtr.Zero);
        }
예제 #13
0
        /***************************************************************************/
        public void ChangeExStyle(USER32.WindowStylesEx eAddedStyles, USER32.WindowStylesEx eRemovedStyles)
        {
            USER32.WindowStylesEx eExtendedStyle = (USER32.WindowStylesEx)USER32.GetWindowLong(m_hWin32Window, USER32.GWL_EXSTYLE);

            eExtendedStyle |= eAddedStyles;
            eExtendedStyle &= ~(eRemovedStyles);

            USER32.SetWindowLong(m_hWin32Window, USER32.GWL_EXSTYLE, (int)eExtendedStyle);
            return;
        }
예제 #14
0
        internal static bool TrySetFormChildWindowStyle(Form form)
        {
            long newStyle = (long)USER32.GetWindowLongPtr(form.Handle, GWL_STYLE);

            if (newStyle == 0)
            {
                return(false);
            }
            newStyle = (newStyle | WS_CHILD) & ~WS_POPUP;
            return(USER32.SetWindowLongPtr(form.Handle, GWL_STYLE, (IntPtr)newStyle) != IntPtr.Zero);
        }
예제 #15
0
        public static Bitmap Control(System.Windows.Forms.Control ctl, bool client, bool under)
        {
            Bitmap    bmp;                                              // capture bitmap
            Rectangle ctlR;                                             // capture area rectangle in control coordinates
            Rectangle scrR;                                             // capture area rectangle in screen coordinates

            //	get capture rectangle in control
            //	coordinates and in screen coordinates
            if (client)                                         // if capturing client area
            {
                ctlR = ctl.ClientRectangle;                     //   get rectangle in control coordinates
                scrR = ctl.RectangleToScreen(ctlR);             //   get rectangle in screen coordinates
            }
            else                                                // if capturing entire control
            {
                scrR = ctl.Bounds;                              //   get rectangle in parent coordinates
                if (ctl.Parent != null)                         //   if parent exists
                {
                    scrR = ctl.Parent.RectangleToScreen(scrR);  //     map to screen coordinates
                }
                ctlR = ctl.RectangleToClient(scrR);             //   get rectangle in control coordinates
            }

            //	capture an area under the control
            if (under)                                                  // if capture area is under control
            {
                bool prvV = ctl.Visible;                                //   save control visibility
                if (prvV)                                               //   if control visible
                {
                    ctl.Visible = false;                                //     make control invisible
                    Thread.Sleep(m_HDelay);                             //     allow time for control to become invisible
                    //     prior to image capture
                }

                //	Capture the bitmap using desktop window handle and screen coordinates
                //	for the capture area. Note, the control window handle can NOT be used
                //  for capturing an area under the control.
                IntPtr desktopHWND = USER32.GetDesktopWindow(); // get window handle for desktop
                bmp = Window(desktopHWND, scrR);                // get bitmap for capture area under control
                if (ctl.Visible != prvV)                        //   if control visibility was changed
                {
                    ctl.Visible = prvV;                         //     restore previous visibility
                }
            }

            //	capture an area on the control
            else                                                                                // if capture area not under control
            {
                //	Capture the bitmap using control window handle and control coordinates
                //	for capture area.
                bmp = Window(ctl.Handle, ctlR);                 //   get bitmap using control window handle
            }
            return(bmp);                                        // return requested bitmap
        }
예제 #16
0
파일: AviCap.cs 프로젝트: ricksam/Framework
        /// <summary>
        /// Stops the video capture
        /// </summary>
        public override void Stop()
        {
            // stop the timer
            this.Tmr.Stop();

            // disconnect from the video source
            Application.DoEvents();
            USER32.SendMessage(mCapHwnd, IMAGECAPTURE.WM_CAP_DRIVER_DISCONNECT, DriverIndex, 0);
            USER32.DestroyWindow(mCapHwnd);
            base.Stop();
        }
예제 #17
0
        internal static bool TrySetFormBoundsToMatchParent(Form form, IntPtr parentHandle)
        {
            Rectangle parentBounds;

            if (!USER32.GetClientRect(parentHandle, out parentBounds))
            {
                return(false);
            }
            form.Bounds = parentBounds;
            return(true);
        }
예제 #18
0
 public static Bitmap GetDesktopImage()
 {
     return(GetImageFromHandle(
                //Here we get the handle to the desktop device context.
                USER32.GetDesktopWindow(),
                //We pass SM_CXSCREEN constant to GetSystemMetrics to get the X coordinates of screen.
                USER32.GetSystemMetrics(SCREENCAPTURE.SM_CXSCREEN),
                //We pass SM_CYSCREEN constant to GetSystemMetrics to get the Y coordinates of screen.
                USER32.GetSystemMetrics(SCREENCAPTURE.SM_CYSCREEN)
                ));
 }
예제 #19
0
        protected override void ProcessRecord()
        {
            if (hWnd == IntPtr.Zero)
            {
                hWnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
            }

            IntPtr hMenu = USER32.GetSystemMenu(hWnd, false);

            USER32.EnableMenuItem(hMenu, USER32.SC_CLOSE, USER32.MF_GRAYED); // Disables controlbox
            USER32.RemoveMenu(hMenu, USER32.SC_CLOSE, USER32.MF_BYCOMMAND);  // Disables the exit menu
        }
예제 #20
0
        protected override void ProcessRecord()
        {
            if (hWnd == IntPtr.Zero)
            {
                hWnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
            }

            IntPtr hMenu = USER32.GetSystemMenu(hWnd, false);

            USER32.EnableMenuItem(hMenu, USER32.SC_CLOSE, USER32.MF_ENABLED);              //Enables controlbox
            USER32.AppendMenu(hMenu, USER32.MenuFlags.MF_STRING, USER32.SC_CLOSE, "Exit"); // Enables the exit menu
        }
예제 #21
0
 internal static Rectangle GetWindowRectangle(IntPtr hWnd)
 {
     USER32.Rect rect = new USER32.Rect();
     if (USER32.GetWindowRect(hWnd, ref rect))
     {
         return(rect.ToRectangle());
     }
     else
     {
         return(new Rectangle());
     }
 }
예제 #22
0
        public static bool UnhookKeyboard()
        {
            bool result = true;

            if (_hHook != IntPtr.Zero)
            {
                result = USER32.UnhookWindowsHookEx(_hHook);
                _hHook = IntPtr.Zero;
            }

            return(result);
        }
예제 #23
0
파일: Mouse.cs 프로젝트: ricksam/Framework
 public static void Click(enmMouseButton Button)
 {
     if (Button == enmMouseButton.Left)
     {
         USER32.mouse_event((uint)MOUSEEVENT.LEFTDOWN, 0, 0, 0, UIntPtr.Zero);
         USER32.mouse_event((uint)MOUSEEVENT.LEFTUP, 0, 0, 0, UIntPtr.Zero);
     }
     else
     {
         USER32.mouse_event((uint)MOUSEEVENT.RIGHTDOWN, 0, 0, 0, UIntPtr.Zero);
         USER32.mouse_event((uint)MOUSEEVENT.RIGHTUP, 0, 0, 0, UIntPtr.Zero);
     }
 }
예제 #24
0
        internal CbtEventArgs(IntPtr wParam, IntPtr lParam)
        {
            // cache the parameters
            this.wParam = wParam;
            this.lParam = lParam;

            // cache the window's class name
            StringBuilder sb = new StringBuilder();

            sb.Capacity = 256;
            USER32.GetClassName(wParam, sb, 256);
            className = sb.ToString();
            IsDialog  = (className == "#32770");
        }
예제 #25
0
        public void WndProcRet(object sender, WndProcRetEventArgs e)
        {
            if (e.cw.message == WndMessage.WM_INITDIALOG ||
                e.cw.message == WndMessage.WM_UNKNOWINIT)
            {
                USER32.MoveWindow(e.cw.hwnd, rect.Left, rect.Top, rect.Width, rect.Height, 1);

                // uninstall this hook
                WindowsHook wndHook = (WindowsHook)sender;
                Debug.Assert(wndProcRetHook == wndHook);
                wndProcRetHook.Uninstall();
                wndProcRetHook = null;
            }
        }
예제 #26
0
        public static bool ShutdownLocalhost(ShutdownEnum.ExitWindows options, ShutdownEnum.ShutdownReason reason)
        {
            TokPriv1Luid tp;
            IntPtr       hproc   = KERNEL32.getCurrentProcess();
            IntPtr       zeroPtr = IntPtr.Zero;

            ADVAPI32.OpenProcessToken(hproc, ADVAPI32.TOKEN_ADJUST_PRIVILEGES | ADVAPI32.TOKEN_QUERY, ref zeroPtr);
            tp.Count = 1;
            tp.Luid  = 0;
            tp.Attr  = ADVAPI32.SE_PRIVILEGE_ENABLED;
            ADVAPI32.LookupPrivilegeValue(null, ADVAPI32.SE_SHUTDOWN_NAME, ref tp.Luid);
            ADVAPI32.AdjustTokenPrivileges(zeroPtr, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
            return(USER32.exitWindowsEx(options, reason));
        }
예제 #27
0
        /// <summary>
        /// Disables the hook
        /// </summary>
        /// <returns>True if hook is disabled</returns>
        public bool DisableHook()
        {
            if (this.mseHook == IntPtr.Zero)
            {
                return(true);
            }

            if (USER32.UnhookWindowsHookEx(this.mseHook))
            {
                this.mseHook = IntPtr.Zero;
                return(true);
            }

            return(false);
        }
예제 #28
0
파일: KeyInput.cs 프로젝트: wljsfw/Overmind
        /// <summary>
        /// Generates a key up event
        /// </summary>
        /// <param name="vkCode">Virtual code of key</param>
        public void KeyUp(Keys vkCode)
        {
            USER32.INPUT[] inputs = new USER32.INPUT[1];
            USER32.INPUT   si     = new USER32.INPUT();
            si.type           = USER32.INPUTFlags.INPUT_KEYBOARD;
            si.ki             = new USER32.KEYBDINPUT();
            si.ki.wVk         = (ushort)vkCode;
            si.ki.wScan       = (ushort)(USER32.MapVirtualKey((ushort)vkCode, USER32.MapType.MAPVK_VK_TO_VSC) | (ushort)(this.IsExtendedKey(vkCode) ? 0x100 : 0)); // Set Extended Bit
            si.ki.time        = 0;
            si.ki.dwFlags     = (uint)USER32.INPUTFlags.KEYEVENTF_KEYUP | (this.IsExtendedKey(vkCode) ? (uint)USER32.INPUTFlags.KEYEVENTF_EXTENDEDKEY : 0);
            si.ki.dwExtraInfo = USER32.GetMessageExtraInfo();
            inputs[0]         = si;

            USER32.SendInput(1, inputs, Marshal.SizeOf(si));
        }
예제 #29
0
        /// <summary>
        /// Checks if the cursor has changed sice the last invokation and returns the serialized new cursor icon
        /// </summary>
        /// <returns>Serialized data bytes if icon has changed else null</returns>
        public static IntPtr CheckCursorChanged()
        {
            USER32.CURSORINFO ci = new USER32.CURSORINFO();
            ci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(ci);
            USER32.GetCursorInfo(out ci);

            int val = ci.hCursor.ToInt32();

            if (val != ScreenSnap._previousCursor)
            {
                ScreenSnap._previousCursor = val;
                //return CaptureCursor();
                return(ci.hCursor);
            }
            return(IntPtr.Zero);
        }
예제 #30
0
        /// <summary>
        /// Generates a mouse click event
        /// </summary>
        /// <param name="button">Mouse button</param>
        /// <param name="clickCount">Number of clicks</param>
        /// <param name="delayMs">Delay between each click, default is 50ms</param>
        public void MouseClick(MouseButtons button, int clickCount, int delayMs = 50)
        {
            USER32.INPUT[] inputs = new USER32.INPUT[2];

            USER32.INPUT si_down = new USER32.INPUT();
            si_down.type           = USER32.INPUTFlags.INPUT_MOUSE;
            si_down.mi             = new USER32.MOUSEINPUT();
            si_down.mi.dx          = 0;
            si_down.mi.dy          = 0;
            si_down.mi.mouseData   = 0;
            si_down.mi.time        = 0;
            si_down.mi.dwExtraInfo = USER32.GetMessageExtraInfo();

            USER32.INPUT si_up = new USER32.INPUT();
            si_up.type           = USER32.INPUTFlags.INPUT_MOUSE;
            si_up.mi             = new USER32.MOUSEINPUT();
            si_up.mi.dx          = 0;
            si_up.mi.dy          = 0;
            si_up.mi.mouseData   = 0;
            si_up.mi.time        = 0;
            si_up.mi.dwExtraInfo = USER32.GetMessageExtraInfo();

            if (button == MouseButtons.Left)
            {
                si_down.mi.dwFlags = (uint)USER32.INPUTFlags.MOUSEEVENTF_LEFTDOWN;
                si_up.mi.dwFlags   = (uint)USER32.INPUTFlags.MOUSEEVENTF_LEFTUP;
            }
            else if (button == MouseButtons.Middle)
            {
                si_down.mi.dwFlags = (uint)USER32.INPUTFlags.MOUSEEVENTF_MIDDLEDOWN;
                si_up.mi.dwFlags   = (uint)USER32.INPUTFlags.MOUSEEVENTF_MIDDLEUP;
            }
            else if (button == MouseButtons.Right)
            {
                si_down.mi.dwFlags = (uint)USER32.INPUTFlags.MOUSEEVENTF_RIGHTDOWN;
                si_up.mi.dwFlags   = (uint)USER32.INPUTFlags.MOUSEEVENTF_RIGHTUP;
            }

            inputs[0] = si_down;
            inputs[1] = si_up;

            for (int i = 0; i < clickCount; i++)
            {
                USER32.SendInput(2, inputs, Marshal.SizeOf(si_down));
                System.Threading.Thread.Sleep(delayMs);
            }
        }