예제 #1
0
        private Image CaptureAppScreen(IntPtr handle)
        {
            //const int HWND_BOTTOM = 1;
            const int HWND_NOTOPMOST = -2;
            //const int HWND_TOP = 0;
            const int HWND_TOPMOST = -1;

            // Put the app window on top of the screen
            IntPtr hForeWnd = User32.GetForegroundWindow();
            uint   dwForeID = User32.GetWindowThreadProcessId(hForeWnd, IntPtr.Zero);
            uint   dwCurID  = User32.GetCurrentThreadId();

            User32.AttachThreadInput(dwCurID, dwForeID, true);
            User32.ShowWindow(handle, User32.CMDSHOW.Normal);
            Thread.Sleep(250);
            User32.SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0, User32.UINT.SWP_NOSIZE | User32.UINT.SWP_NOMOVE);
            User32.SetWindowPos(handle, HWND_NOTOPMOST, 0, 0, 0, 0, User32.UINT.SWP_NOSIZE | User32.UINT.SWP_NOMOVE);
            User32.SetForegroundWindow(handle);
            Thread.Sleep(250);
            User32.AttachThreadInput(dwCurID, dwForeID, false);

            // Create a instance to store img
            Rectangle rect = new Rectangle();

            User32.GetWindowRect(handle, out rect);
            Image    img   = new Bitmap(rect.Width - rect.X, rect.Height - rect.Y);
            Graphics graph = Graphics.FromImage(img);

            graph.CopyFromScreen(rect.X, rect.Y, 0, 0, Screen.FromHandle(handle).Bounds.Size);

            return(img);
        }
예제 #2
0
        public static bool ForceForegroundWindow(int handle)
        {
            var foregroundWnd = User32.GetForegroundWindow();

            if (handle == foregroundWnd)
            {
                return(true);
            }

            int ret;

            var threadId1 = User32.GetWindowThreadProcessId(foregroundWnd, 0);
            var threadId2 = User32.GetWindowThreadProcessId(handle, 0);

            if (threadId1 != threadId2)
            {
                User32.AttachThreadInput(threadId1, threadId2, 1);
                ret = User32.SetForegroundWindow(handle);
                User32.AttachThreadInput(threadId1, threadId2, 0);
            }
            else
            {
                ret = User32.SetForegroundWindow(handle);
            }

            var showWindowMode = User32.IsIconic(handle) == 0 ? User32.Restore : User32.Show;

            User32.ShowWindow(handle, showWindowMode);
            User32.SetActiveWindow(handle);
            User32.BringWindowToTop(handle);

            return(ret != 0);
        }
예제 #3
0
        public override void ActivateForm(Window form, Window window, IntPtr hwnd)
        {
            var fHandle = (PresentationSource.FromVisual(form) as HwndSource).Handle;
            var wHandle = (PresentationSource.FromVisual(window) as HwndSource).Handle;

            if (window == null || wHandle != fHandle)
            {
                uint fgProcessId;
                uint spProcessId;
                User32.GetWindowThreadProcessId(User32.GetForegroundWindow(), out fgProcessId);
                User32.GetWindowThreadProcessId(fHandle, out spProcessId);

                if (fgProcessId != spProcessId)
                {
                    if (User32.AttachThreadInput(fgProcessId, spProcessId, true))
                    {
                        User32.SetForegroundWindow(fHandle);
                        User32.AttachThreadInput(fgProcessId, spProcessId, false);
                    }
                }
                else
                {
                    User32.SetForegroundWindow(fHandle);
                }

                // stop flashing...happens occassionally when switching quickly when activate manuver is fails
                Shell32.FlashWindow(fHandle, 0);
            }
        }
예제 #4
0
        public static bool DetachThreadInput(uint idAttach, uint idAttachTo)
        {
            var success = User32.AttachThreadInput(idAttach, idAttachTo, false);

            if (!success)
            {
                var hresult = Marshal.GetHRForLastWin32Error();
                Marshal.ThrowExceptionForHR(hresult);
            }

            return(success);
        }
예제 #5
0
        internal static IntPtr GetFocusedWindow()
        {
            var activeWindowHandle = User32.GetForegroundWindow();

            var activeWindowThread = User32.GetWindowThreadProcessId(activeWindowHandle, IntPtr.Zero);
            var currentThread      = Kernel32.GetCurrentThreadId();

            User32.AttachThreadInput(activeWindowThread, currentThread, true);
            var focusedControlHandle = User32.GetFocus();

            User32.AttachThreadInput(activeWindowThread, currentThread, false);

            return(focusedControlHandle);
        }
예제 #6
0
        public void Activate(IntPtr hWnd)
        {
            if (hWnd == User32.GetForegroundWindow())
            {
                return;
            }
            //cmd needs to be called synchronous.
            if (this.ProcessName.EndsWith("cmd.exe"))
            {
                if (User32.IsIconic(hWnd))
                {
                    User32.ShowWindow(hWnd, (int)WindowState.SW_RESTORE);
                }
                User32.SetForegroundWindow(hWnd);
                return;
            }

            var threadId1 = User32.GetWindowThreadProcessId(User32.GetForegroundWindow(), IntPtr.Zero);
            var threadId2 = User32.GetWindowThreadProcessId(hWnd, IntPtr.Zero);

            if (threadId1 != threadId2)
            {
                User32.AttachThreadInput(threadId1, threadId2, 1);
                User32.SetForegroundWindow(hWnd);
                User32.AttachThreadInput(threadId1, threadId2, 0);
            }
            else
            {
                User32.SetForegroundWindow(hWnd);
            }

            if (User32.IsIconic(hWnd))
            {
                User32.ShowWindowAsync(hWnd, (int)WindowState.SW_RESTORE);
            }
            else
            {
                if (User32.IsZoomed(hWnd))
                {
                    User32.ShowWindowAsync(hWnd, (int)WindowState.SW_SHOWMAXIMIZED);
                }
                else
                {
                    User32.ShowWindowAsync(hWnd, (int)WindowState.SW_SHOWNORMAL);
                }
            }
        }
예제 #7
0
        public static void ForceWindowIntoForeground(IntPtr window)
        {
            const uint LSFW_LOCK   = 1;
            const uint LSFW_UNLOCK = 2;
            const int  ASFW_ANY    = -1; // by MSDN

            uint currentThread = Native.GetCurrentThreadId();

            IntPtr activeWindow = User32.GetForegroundWindow();
            //uint activeProcess;
            uint activeThread = User32.GetWindowThreadProcessId(activeWindow, IntPtr.Zero);

            uint windowProcess;
            uint windowThread = User32.GetWindowThreadProcessId(window, IntPtr.Zero);

            if (currentThread != activeThread)
            {
                User32.AttachThreadInput(currentThread, activeThread, true);
            }
            if (windowThread != currentThread)
            {
                User32.AttachThreadInput(windowThread, currentThread, true);
            }

            uint oldTimeout = 0, newTimeout = 0;

            User32.SystemParametersInfo(User32.SPI_GETFOREGROUNDLOCKTIMEOUT, 0, ref oldTimeout, 0);
            User32.SystemParametersInfo(User32.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, ref newTimeout, 0);
            User32.LockSetForegroundWindow(LSFW_UNLOCK);
            User32.AllowSetForegroundWindow(ASFW_ANY);

            User32.SetForegroundWindow(window);
            User32.ShowWindow(window, User32.SW.SW_RESTORE);
            User32.SetFocus(window);

            User32.SystemParametersInfo(User32.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, ref oldTimeout, 0);

            if (currentThread != activeThread)
            {
                User32.AttachThreadInput(currentThread, activeThread, false);
            }
            if (windowThread != currentThread)
            {
                User32.AttachThreadInput(windowThread, currentThread, false);
            }
        }
예제 #8
0
        public static void RestoreWindow(WindowBase window)
        {
            try
            {
                // This is the only reliable method that also doesn't result in issues like this:
                // https://www.reddit.com/r/playnite/comments/f6d73l/bug_full_screen_ui_wont_respond_to_left_stick/
                // Adapted from https://ask.xiaolee.net/questions/1040342
                window.Show();
                if (!window.Activate())
                {
                    window.Topmost = true;
                    window.Topmost = false;
                }

                if (window.WindowState == WindowState.Minimized)
                {
                    window.WindowState = WindowState.Normal;
                }

                //Get the process ID for this window's thread
                var interopHelper      = new WindowInteropHelper(window);
                var thisWindowThreadId = User32.GetWindowThreadProcessId(interopHelper.Handle, IntPtr.Zero);

                //Get the process ID for the foreground window's thread
                var currentForegroundWindow         = User32.GetForegroundWindow();
                var currentForegroundWindowThreadId = User32.GetWindowThreadProcessId(currentForegroundWindow, IntPtr.Zero);

                //Attach this window's thread to the current window's thread
                User32.AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, true);

                //Set the window position
                User32.SetWindowPos(interopHelper.Handle, new IntPtr(0), 0, 0, 0, 0, SWP.NOSIZE | SWP.NOMOVE | SWP.SHOWWINDOW);

                //Detach this window's thread from the current window's thread
                User32.AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, false);
            }
            catch (Exception e)
            {
                logger.Error(e, "Failed to restore window.");
            }
        }
예제 #9
0
        /// <summary>
        /// Forces the window to the foreground by attaching to the foreground window thread
        /// </summary>
        private void ForceForeground()
        {
            // This is required as there's a few restrictions on when this can be called
            // Per https://msdn.microsoft.com/en-us/library/windows/desktop/ms633539%28v=vs.85%29.aspx

            var targetThread = User32.GetWindowThreadProcessId(User32.GetForegroundWindow(), IntPtr.Zero);
            var appThread    = Kernel32.GetCurrentThreadId();
            var attached     = false;

            try
            {
                if (targetThread == appThread)
                {
                    // already attached
                    return;
                }

                attached = User32.AttachThreadInput(targetThread, appThread, true);

                if (!attached)
                {
                    // hmm
                    Close();
                    return;
                }

                var ourHandle = new WindowInteropHelper(this).Handle;

                // force us to the forground
                User32.BringWindowToTop(ourHandle);
                User32.SetFocus(ourHandle);
            }
            finally
            {
                if (attached)
                {
                    // unattach
                    User32.AttachThreadInput(targetThread, appThread, false);
                }
            }
        }
예제 #10
0
 public static void ShowWindow(IntPtr hWnd)
 {
     if (User32.GetForegroundWindow() != hWnd)
     {
         IntPtr dwMyThreadID    = User32.GetWindowThreadProcessId(User32.GetForegroundWindow(), IntPtr.Zero);
         IntPtr dwOtherThreadID = User32.GetWindowThreadProcessId(hWnd, IntPtr.Zero);
         if (dwMyThreadID != dwOtherThreadID)
         {
             User32.AttachThreadInput(dwMyThreadID, dwOtherThreadID, true);
             User32.BringWindowToTop(hWnd);
             User32.SetForegroundWindow(hWnd);
             IntPtr hMain = User32.GetWindow(hWnd, WinBase.GW_ENABLEDPOPUP);
             User32.SetFocus(hMain);
             User32.AttachThreadInput(dwMyThreadID, dwOtherThreadID, false);
         }
         else
         {
             User32.SetForegroundWindow(hWnd);
         }
     }
 }
예제 #11
0
        /// <summary>
        /// Sets the focus by using the Win32 SetFocus() method.
        /// </summary>
        public void FocusNative()
        {
            if (Properties.NativeWindowHandle.IsSupported)
            {
                var windowHandle = Properties.NativeWindowHandle.ValueOrDefault;
                if (windowHandle != Win32Constants.FALSE)
                {
                    uint windowThreadId  = User32.GetWindowThreadProcessId(windowHandle, out _);
                    uint currentThreadId = Kernel32.GetCurrentThreadId();

                    // attach window to the calling thread's message queue
                    User32.AttachThreadInput(currentThreadId, windowThreadId, true);
                    User32.SetFocus(windowHandle);
                    // detach the window from the calling thread's message queue
                    User32.AttachThreadInput(currentThreadId, windowThreadId, false);

                    Wait.UntilResponsive(this);
                    return;
                }
            }
            // Fallback to the UIA Version
            SetFocus();
        }
예제 #12
0
        private static string GetWindowControlText(IntPtr hWnd)
        {
            string text = null;

            try
            {
                int cid = Kernel32.GetCurrentThreadId();
                int tid = User32.GetWindowThreadProcessId(hWnd, IntPtr.Zero);
                User32.AttachThreadInput(tid, cid, true);
                {
                    IntPtr hFocus = User32.GetFocus();
                    if (hFocus != IntPtr.Zero)
                    {
                        StringBuilder sb = new StringBuilder(4096);
                        User32.SendMessage(hFocus, User32.WM_GETTEXT, 4096, sb);
                        text = sb.ToString();
                    }
                }
                User32.AttachThreadInput(tid, cid, false);
            }
            catch (Exception ex) { TraceLogger.Instance.WriteException(ex); }
            return(text);
        }
예제 #13
0
        /// <summary>
        /// Convert VKCode to Unicode.
        /// <remarks>isKeyDown is required for because of keyboard state inconsistencies!</remarks>
        /// </summary>
        /// <param name="VKCode">VKCode</param>
        /// <param name="isKeyDown">Is the key down event?</param>
        /// <returns>String representing single unicode character.</returns>
        protected string VirtualKey2String(uint VKCode, bool isKeyDown)
        {
            // ToUnicodeEx needs StringBuilder, it populates that during execution.
            var sbString = new StringBuilder(5);

            byte[] bKeyState = new byte[255];
            bool   bKeyStateStatus;
            bool   isDead = false;

            // Gets the current windows window handle, threadID, processID
            IntPtr currentHWnd           = User32.GetForegroundWindow();
            uint   currentWindowThreadID = User32.GetWindowThreadProcessId(currentHWnd, out uint currentProcessID);

            // This programs Thread ID
            uint thisProgramThreadId = Kernel32.GetCurrentThreadId();

            // Attach to active thread so we can get that keyboard state
            if (User32.AttachThreadInput(thisProgramThreadId, currentWindowThreadID, true))
            {
                // Current state of the modifiers in keyboard
                bKeyStateStatus = User32.GetKeyboardState(bKeyState);

                // Detach
                User32.AttachThreadInput(thisProgramThreadId, currentWindowThreadID, false);
            }
            else
            {
                // Could not attach, perhaps it is this process?
                bKeyStateStatus = User32.GetKeyboardState(bKeyState);
            }

            // On failure we return empty string.
            if (!bKeyStateStatus)
            {
                return("");
            }

            // Gets the layout of keyboard
            IntPtr HKL = User32.GetKeyboardLayout(currentWindowThreadID);

            // Maps the virtual keycode
            uint lScanCode = User32.MapVirtualKeyEx(VKCode, (uint)MapVirtualKeyMapTypes.VirtualKey2ScanCode, HKL);

            // Keyboard state goes inconsistent if this is not in place. In other words, we need to call above commands in UP events also.
            if (!isKeyDown)
            {
                return("");
            }

            // Converts the VKCode to unicode
            int relevantKeyCountInBuffer = User32.ToUnicodeEx(VKCode, lScanCode, bKeyState, sbString, sbString.Capacity, (uint)0, HKL);

            var result = "";

            switch (relevantKeyCountInBuffer)
            {
            // Dead keys (^,`...)
            case -1:
                isDead = true;

                // We must clear the buffer because ToUnicodeEx messed it up, see below.
                ClearKeyboardBuffer(VKCode, lScanCode, HKL);
                break;

            case 0:
                break;

            // Single character in buffer
            case 1:
                result = sbString[0].ToString();
                break;

            // Two or more (only two of them is relevant)
            case 2:
            default:
                result = sbString.ToString().Substring(0, 2);
                break;
            }

            // We inject the last dead key back, since ToUnicodeEx removed it.
            // More about this peculiar behavior see e.g:
            //   http://www.experts-exchange.com/Programming/System/Windows__Programming/Q_23453780.html
            //   http://blogs.msdn.com/michkap/archive/2005/01/19/355870.aspx
            //   http://blogs.msdn.com/michkap/archive/2007/10/27/5717859.aspx
            if (_lastVKCode != 0 && _lastIsDead)
            {
                var sbTemp = new StringBuilder(5);
                User32.ToUnicodeEx(_lastVKCode, _lastScanCode, _lastKeyState, sbTemp, sbTemp.Capacity, 0, HKL);
                _lastVKCode = 0;

                return(result);
            }

            // Save these
            _lastScanCode = lScanCode;
            _lastVKCode   = VKCode;
            _lastIsDead   = isDead;
            _lastKeyState = (byte[])bKeyState.Clone();

            return(result);
        }
예제 #14
0
        public override void ActivateForm(Window form, Window window, IntPtr hwnd)
        {
            var fHandle = (PresentationSource.FromVisual(form) as HwndSource).Handle;
            var wHandle = window == null ? IntPtr.Zero : (PresentationSource.FromVisual(window) as HwndSource).Handle;

            if (window == null || wHandle != fHandle)
            {
                IntPtr Dummy = IntPtr.Zero;

                IntPtr hWnd = fHandle;
                if (User32.IsIconic(hWnd))
                {
                    User32.ShowWindowAsync(hWnd, SW_RESTORE);
                }
                else
                {
                    //User32.ShowWindowAsync(hWnd, SW_SHOW);
                    form.ShowActivated = true;
                    form.Show();
                }
                User32.SetForegroundWindow(hWnd);
                form.Activate();
                form.Topmost = true;
                form.Topmost = false;

                // Code from Karl E. Peterson, www.mvps.org/vb/sample.htm
                // Converted to Delphi by Ray Lischner
                // Published in The Delphi Magazine 55, page 16
                // Converted to C# by Kevin Gale
                IntPtr foregroundWindow = User32.GetForegroundWindow();
                if (foregroundWindow != hWnd)
                {
                    uint foregroundThreadId = User32.GetWindowThreadProcessId(foregroundWindow, Dummy);
                    uint thisThreadId       = User32.GetWindowThreadProcessId(hWnd, Dummy);

                    if (User32.AttachThreadInput(thisThreadId, foregroundThreadId, true))
                    {
                        form.Activate();
                        form.Topmost = true;
                        form.Topmost = false;
                        User32.BringWindowToTop(hWnd);                         // IE 5.5 related hack
                        User32.SetForegroundWindow(hWnd);
                        User32.AttachThreadInput(thisThreadId, foregroundThreadId, false);
                    }
                }

                if (User32.GetForegroundWindow() != hWnd)
                {
                    // Code by Daniel P. Stasinski
                    // Converted to C# by Kevin Gale
                    IntPtr Timeout = IntPtr.Zero;
                    User32.SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, Timeout, 0);
                    User32.SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Dummy, SPIF_SENDCHANGE);
                    User32.BringWindowToTop(hWnd);                     // IE 5.5 related hack
                    User32.SetForegroundWindow(hWnd);
                    form.Activate();
                    form.Topmost = true;
                    form.Topmost = false;
                    User32.SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Timeout, SPIF_SENDCHANGE);
                }

                Shell32.FlashWindow(fHandle, 0);
            }
        }