SetForegroundWindow завершается ошибкой в ​​Windows Server 2008 - PullRequest
1 голос
/ 02 января 2012

Сценарий У меня есть основное приложение, изначально написанное на Borland C ++, которое запускается приложением C # .Net.Это основное приложение иногда открывает модальное диалоговое окно из процесса под названием BRWSEXE.После того, как появится модальное диалоговое окно, вы можете случайно щелкнуть где-нибудь в главном приложении (не в диалоге), в результате чего фокус ненадолго переключится на основное приложение, отправив модальное диалоговое окно позади него в Z-порядке.Но на самом деле вы ничего не можете сделать с основным приложением, оно заблокировано тем модальным диалоговым окном, которое должно быть закрыто в первую очередь, прежде чем вы сможете продолжить.

Проблема Использование приложения .netкоторый запускает все, я могу искать экземпляры BRWSEXE, которые связаны с основным приложением, и выводить их на передний план.Эта тактика работает безупречно везде, где я до сих пор ее тестировал (Windows XP, Windows 7, Windows Server 2003 R2), но она не работает на Windows Server 2008. Так что, насколько я могу судить, мой код работает нормально ...но что-то в этой среде сбрасывает это.

Мой код

[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);

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


private void PushBRWSEXEToFront()
{
    //Make sure MyApplication is running
    if (Process.GetProcessesByName("MyApplicationName").Length == 1)
    {
        Process[] brwsProc = Process.GetProcessesByName("BRWSEXE"); //Locate any processes for the browse dialog windows
        for (int x = brwsProc.Length - 1; x > -1; x--)
        {
            //Make sure the browse window we are looking at is associated with the active program we are looking at
            if (brwsProc[x].SessionId == Process.GetCurrentProcess().SessionId
                || brwsProc[x].SessionId == Process.GetProcessesByName("MyApplicationName")[0].SessionId)
            {
                //attach to the main applications thread
                AttachThreadInput(brwsProc[x].MainWindowHandle, Process.GetProcessesByName("MyApplicationName")[0].MainWindowHandle, true);

                //Call Set foreground window to push the browse window in front of the rest of the program.
                SetForegroundWindow(brwsProc[x].MainWindowHandle);

                //Detach from the main thread
                AttachThreadInput(brwsProc[x].MainWindowHandle, Process.GetProcessesByName("MyApplicationName")[0].MainWindowHandle, false);
            }
        }
    }
}

Ответы [ 2 ]

3 голосов
/ 02 января 2012

Ваша AttachThreadInput декларация полностью неверна. Возвращает bool, аргументы uint. И вы используете это неправильно, вы должны передать идентификатор потока, а не дескриптор окна. Вам понадобится GetWindowThreadProcessId().

И вы вообще не проверяете ошибки, поэтому, очевидно, не можете диагностировать сбой. Требуется SetLastError свойство, найдите ошибку с Marshal.GetLastWin32Error(). Используйте pinvoke.net для лучших объявлений pinvoke.

0 голосов
/ 02 января 2012

Я использовал SwitchToThisWindow(), и хотя MSDN говорит, что его можно удалить в будущих версиях Windows, он все еще работает для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...