SetForegroundWindow не устанавливает фокус

Привет, поэтому я пытаюсь сфокусироваться на приложении, и все, что я смог найти в Интернете, это метод SetForegroundWindow, поэтому я попытался реализовать его, но он вообще не устанавливает фокус на приложение, я также нашел несколько статей о том, что он ненадежен, поэтому хотел спросить, сделал ли я это неправильно или есть ли лучший способ вводить нажатия клавиш в приложение, спасибо!

[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

private void JumpRL(object sender, EventArgs e)
{
   Process[] processlist = Process.GetProcesses();
   var name = processlist.Where(x => x.ProcessName == "RocketLeague").FirstOrDefault();
            
   SetForegroundWindow(name.MainWindowHandle);
   SendKeys.SendWait("{BS}");
}

процесс правильный, я дважды проверил


person Pato Srna    schedule 18.07.2020    source источник
comment
Это ответ на ваш вопрос?   -  person aepot    schedule 18.07.2020
comment
я безуспешно пробовал sendmessage post message с Rocket League и Notepad, я еще не пробовал sendinput, но я довольно пессимистичен в этом отношении   -  person Pato Srna    schedule 18.07.2020


Ответы (1)


Итак, после долгих поисков в Интернете я нашел статья с примером кода переключения окон, так что я сказал, черт возьми, и пошел попробовать, и это действительно сработало, и он переключает фокус, вот фрагмент, надеюсь, это поможет

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

[DllImport("kernel32.dll")]
public static extern uint GetCurrentThreadId();

[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

[DllImport("user32.dll")]
public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

public static void SwitchWindow(IntPtr windowHandle)
        {
            if (GetForegroundWindow() == windowHandle)
                return;

            IntPtr foregroundWindowHandle = GetForegroundWindow();
            uint currentThreadId = GetCurrentThreadId();
            uint temp;
            uint foregroundThreadId = GetWindowThreadProcessId(foregroundWindowHandle, out temp);
            AttachThreadInput(currentThreadId, foregroundThreadId, true);
            SetForegroundWindow(windowHandle);
            AttachThreadInput(currentThreadId, foregroundThreadId, false);

            while (GetForegroundWindow() != windowHandle)
            {
            }
        }

после того, как вы сфокусируетесь, простой SendKeys.SendWait("<key>") работает как шарм

person Pato Srna    schedule 18.07.2020
comment
Добавьте что-то вроде Thread.Sleep(10) в последний цикл. В противном случае это вызовет 100% загрузку процессора во время цикла. - person aepot; 18.07.2020
comment
Этот код уже доступен в .NET Framework, в всеми любимом пространстве имен утилит, лучше всего использовать его как есть. docs.microsoft.com/ en-us/dotnet/api/ - person Hans Passant; 18.07.2020