using System.Runtime.InteropServices; namespace Vanara.PInvoke { public static partial class User32 { /// Attaches or detaches the input processing mechanism of one thread to that of another thread. /// /// The identifier of the thread to be attached to another thread. The thread to be attached cannot be a system thread. /// /// /// The identifier of the thread to which idAttach will be attached. This thread cannot be a system thread. /// A thread cannot attach to itself. Therefore, idAttachTo cannot equal idAttach. /// /// /// If this parameter is TRUE, the two threads are attached. If the parameter is FALSE, the threads are detached. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// Windows Server 2003 and Windows XP: There is no extended error information; do not call GetLastError. This behavior /// changed as of Windows Vista. /// /// /// /// /// By using the AttachThreadInput function, a thread can share its input states (such as keyboard states and the current /// focus window) with another thread. Keyboard and mouse events received by both threads are processed in the order they were /// received until the threads are detached by calling AttachThreadInput a second time and specifying FALSE for the /// fAttach parameter. /// /// /// The AttachThreadInput function fails if either of the specified threads does not have a message queue. The system creates /// a thread's message queue when the thread makes its first call to one of the USER or GDI functions. The AttachThreadInput /// function also fails if a journal record hook is installed. Journal record hooks attach all input queues together. /// /// /// Note that key state, which can be ascertained by calls to the GetKeyState or GetKeyboardState function, is reset after a call to /// AttachThreadInput. You cannot attach a thread to a thread in another desktop. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-attachthreadinput BOOL AttachThreadInput( DWORD idAttach, // DWORD idAttachTo, BOOL fAttach ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "0c343fab-56ae-4c70-a79e-0c5f827158a3")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, [MarshalAs(UnmanagedType.Bool)] bool fAttach); /// /// Determines whether the process belongs to a Windows Store app. /// /// /// Target process handle. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-isimmersiveprocess BOOL IsImmersiveProcess( HANDLE // hProcess ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "E95FD9C0-8E4A-44FA-BBA6-0A7F53A0E584")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsImmersiveProcess(HPROCESS hProcess); /// /// /// Exempts the calling process from restrictions preventing desktop processes from interacting with the Windows Store app /// environment. This function is used by development and debugging tools. /// /// /// This function only succeeds if a developer license is present on the system. Once successful the calling process will be able to /// perform the following actions, subject to User Interface Privilege Isolation (UIPI) restrictions: /// /// /// /// Attach global hooks (and event hooks) to Windows Store app processes. /// /// /// /// Attach input queues between Windows Store app processes, Windows Store app browsers, system processes, and desktop application processes. /// /// /// /// Change foreground arbitrarily between the Windows Store app and desktop environments. /// /// /// /// When set to TRUE, indicates a request to disable exemption for the calling process. /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// Any process can call this function, including desktop and Windows Store app processes and processes that use IL code. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessrestrictionexemption BOOL // SetProcessRestrictionExemption( BOOL fEnableExemption ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "CC7EE5D7-ADFC-4859-88F8-C5C21AEBF315")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetProcessRestrictionExemption([MarshalAs(UnmanagedType.Bool)] bool fEnableExemption); /// /// Waits until the specified process has finished processing its initial input and is waiting for user input with no input pending, /// or until the time-out interval has elapsed. /// /// /// A handle to the process. If this process is a console application or does not have a message queue, WaitForInputIdle /// returns immediately. /// /// /// The time-out interval, in milliseconds. If dwMilliseconds is INFINITE, the function does not return until the process is idle. /// /// /// The following table shows the possible return values for this function. /// /// /// Return code/value /// Description /// /// /// 0 /// The wait was satisfied successfully. /// /// /// WAIT_TIMEOUT /// The wait was terminated because the time-out interval elapsed. /// /// /// WAIT_FAILED /// An error occurred. /// /// /// /// /// /// The WaitForInputIdle function enables a thread to suspend its execution until the specified process has finished its /// initialization and is waiting for user input with no input pending. If the process has multiple threads, the /// WaitForInputIdle function returns as soon as any thread becomes idle. /// /// /// WaitForInputIdle can be used at any time, not just during application startup. However, WaitForInputIdle waits only /// once for a process to become idle; subsequent WaitForInputIdle calls return immediately, whether the process is idle or busy. /// /// /// WaitForInputIdle can be useful for synchronizing a parent process and a newly created child process. When a parent process /// creates a child process, the CreateProcess function returns without waiting for the child process to finish its initialization. /// Before trying to communicate with the child process, the parent process can use the WaitForInputIdle function to determine /// when the child's initialization has been completed. For example, the parent process should use the WaitForInputIdle /// function before trying to find a window associated with the child process. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-waitforinputidle DWORD WaitForInputIdle( HANDLE hProcess, // DWORD dwMilliseconds ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "2a684921-36f1-438c-895c-5bebc242635a")] public static extern uint WaitForInputIdle(HPROCESS hProcess, uint dwMilliseconds); } }