Прежде чем задавать этот вопрос, я забыл специально искать проблемы, связанные с функцией SetForegroundWindow
, поэтому пропустил два вопроса, говорящих по существу об одной и той же проблеме.
В первом вопросе есть два вопроса Ответы с опротестованием в основном используют тот же хак, который технически работает, но не является выполнимым решением. Использование keybd_event(0, 0, 0, 0)
для имитации нажатия Keys.NONE
имеет задержку около половины секунды и по какой-то причине также запускает Nvidia Shadowplay, чтобы начать запись. (Вероятно, это связано с тем, что Nvidia неправильно интерпретирует Keys.NONE
как один из их горячих клавиш).
Очень недавний ответ на второй вопрос представляется правильным решением с использованием ассоциаций потоков. Это рабочий C# код, основанный на примере C ++:
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();
[DllImport("user32.dll")]
static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
[DllImport("user32.dll", SetLastError = true)]
static extern bool BringWindowToTop(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern int ShowWindow(IntPtr hWnd, uint Msg);
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
public static void ForceForegroundWindow(IntPtr hwnd)
{
uint windowThreadProcessId = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
uint currentThreadId = GetCurrentThreadId();
uint CONST_SW_SHOW = 5;
AttachThreadInput(windowThreadProcessId, currentThreadId, true);
BringWindowToTop(hwnd);
ShowWindow(hwnd, CONST_SW_SHOW);
AttachThreadInput(windowThreadProcessId, currentThreadId, false);
}