最近写了一个winform程序,里面有个splash窗口,因为是新开了一个窗口显示的,结果导致了后续出现的login窗口虽然显示在了最前面,但是却没法获取输入焦点,我进行了大量的搜索,使用winapi进行setforeground,返回总是false, 结果通过bing在国外网站找到了一段代码,翻译了一些win32常量,发现挺好用,在.net5下能正确运行,代码如下
最好新开个timer,在timeer里执行一次
[DllImport("User32.dll")] private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow); [DllImport("User32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] private static extern bool SetWindowPos(IntPtr hWnd, int hWndlnsertAfter, int X, int Y, int cx, int cy, uint Flags); [DllImport("user32.dll", EntryPoint = "SystemParametersInfo")] public static extern int SystemParametersInfo(int uAction, int uParam, IntPtr lpvParam, int fuWinIni); [DllImport("User32.dll", SetLastError = true)] public static extern int GetForegroundWindow(); [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID); [DllImport("User32.dll", SetLastError = true)] static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); [DllImport("user32.dll")] internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll")] private static extern int AttachThreadInput(int CurrentForegroundThread, int MakeThisThreadForegrouond, bool boolAttach); [DllImport("kernel32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] public static extern int GetCurrentThreadId(); [DllImport("user32", CharSet = CharSet.Auto)] static extern bool SystemParametersInfo(int uiAction, int uiParam, ref int pvParam, int fWinIni); [DllImport("user32", CharSet = CharSet.Auto)] static extern bool LockSetForegroundWindow(int a); [DllImport("user32", CharSet = CharSet.Auto)] static extern bool AllowSetForegroundWindow(int a); public static void ForceWindowIntoForeground(IntPtr window) { int currentThread = GetCurrentThreadId(); int activeWindow = GetForegroundWindow(); int activeThread = GetWindowThreadProcessId((IntPtr)activeWindow, out int activeProcess); int windowThread = GetWindowThreadProcessId(window, out int windowProcess); if (currentThread != activeThread) AttachThreadInput(currentThread, activeThread, true); if (windowThread != currentThread) AttachThreadInput(windowThread, currentThread, true); int oldTimeout = 0, newTimeout = 0; SystemParametersInfo(0x2000, 0, ref oldTimeout, 0); SystemParametersInfo(0x2000, 0, ref newTimeout, 0); LockSetForegroundWindow(2); AllowSetForegroundWindow(-1); SetForegroundWindow(window); ShowWindow(window, 9); SystemParametersInfo(0x2000, 0, ref oldTimeout, 0); if (currentThread != activeThread) AttachThreadInput(currentThread, activeThread, false); if (windowThread != currentThread) AttachThreadInput(windowThread, currentThread, false); }