Kalyani Kailasamoni Ответов: 4

Вывести процесс на передний план


Привет
В приложении C#, как я могу привести экземпляр приложения, которое было создано с помощью Process.Start () на передний план?

Спасибо
К

4 Ответов

Рейтинг:
21

LanFanNinja

Решение 1 будет работать просто отлично для ваших нужд. Но я просто хотел добавить, что если окна будут свернуты, вам нужно будет использовать что-то вроде этого:

[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr handle);
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool ShowWindow(IntPtr handle, int nCmdShow);
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool IsIconic(IntPtr handle);

const int SW_RESTORE = 9;

Process proc = Process.Start("cmd.exe");

private void button1_Click(object sender, EventArgs e)
{
    IntPtr handle = proc.MainWindowHandle;
    if (IsIconic(handle))
    {
        ShowWindow(handle, SW_RESTORE);
    }

    SetForegroundWindow(handle);
}


ridoy

5ед.

Рейтинг:
2

OriginalGriff

Попробуй:

[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
private IntPtr handle;
private Process process;
private void button1_Click(object sender, EventArgs e)
    {
    process = Process.Start("cmd");
    }

private void button2_Click(object sender, EventArgs e)
    {
    handle = process.MainWindowHandle;
    SetForegroundWindow(handle);
    }


Рейтинг:
1

Kalyani Kailasamoni

Спасибо за ваши ответы. Я попробовал решение, упомянутое выше, с моим приложением. И все же я не в состоянии вывести вновь созданный процесс на передний план, он все еще находится на заднем плане. Когда я порождаю новый процесс с помощью cmd.exe используя предоставленное решение, он действительно выводит командную строку на forgeround.

Но когда я делаю то же самое с моим собственным приложением, оно все еще находится в фоновом режиме. Суть того, что я пытаюсь сделать, заключается в создании второго экземпляра приложения, порожденного, когда пользователь выбирает опцию File->Open в приложении, когда файл уже открыт. Таким образом, второй файл будет открыт в другом экземпляре приложения (аналогично MS Word). Ниже приведен мой код, где MainForm - это основная форма моего приложения MDI. Флаг true указывает на необходимость создания второго экземпляра приложения.

IntPtr handle;
Process process = 
    Process.Start(typeof(MainForm).Assembly.Location, "true");
    handle = process.MainWindowHandle;
SetForegroundWindow(handle);



Любая идея/предложение, почему я не могу вывести второй экземпляр моего приложения на передний план, очень ценится!

Заранее спасибо
К


LanFanNinja

- Не знаю? Этот код полностью работает для меня

частный недействительными обработчика button1_click(объект отправителя, EventArgs в электронной)
{
Ручка IntPtr;
Процесс proc =
Процесс.Start(typeof(MainForm).Собрание.Местоположение, " правда");
ручка = тез.Докл.MainWindowHandle;

if (IsIconic (handle))
{
ShowWindow(handle, SW_RESTORE);
}

SetForegroundWindow (ручка);
}

на самом деле он работает правильно без вызова SetForegroundWindow (handle);

Рейтинг:
0

ShlomiO

Привет, была такая же проблема, надеюсь, это поможет:

Хитрость заключается в том, чтобы заставить windows "думать", что наш процесс и целевое окно (hwnd) связаны, прикрепив потоки (используя API AttachThreadInput) и используя альтернативный API: BringWindowToTop.


Принудительное перемещение окна / Internet Explorer на передний план:

private static void ForceForegroundWindow(IntPtr hWnd)
{
    uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
    uint appThread = GetCurrentThreadId();
    const uint SW_SHOW = 5;
 
    if (foreThread != appThread)
    {
        AttachThreadInput(foreThread, appThread, true);
        BringWindowToTop(hWnd);
        ShowWindow(hWnd, SW_SHOW);
        AttachThreadInput(foreThread, appThread, false);
    }
    else
    {
        BringWindowToTop(hWnd);
        ShowWindow(hWnd, SW_SHOW);
    }
}


Более продвинутая реализация шаблона AttachedThreadInputAction

Идея состоит в том, чтобы прикрепиться к целевому потоку процесса и предварительно сформировать действие.

фрагмент кода
public static void AttachedThreadInputAction(Action action)
{
    var foreThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
    var appThread = GetCurrentThreadId();
    bool threadsAttached = false;
    try
    {
        threadsAttached =
            foreThread == appThread ||
            AttachThreadInput(foreThread, appThread, true);
        if (threadsAttached) action();
        else throw new ThreadStateException("AttachThreadInput failed.");
    }
    finally
    {
        if (threadsAttached)
            AttachThreadInput(foreThread, appThread, false);
    }
}

Использование

фрагмент кода
public const uint SW_SHOW = 5;

///<summary>
/// Forces the window to foreground.
///</summary>
///hwnd">The HWND.</param>
public static void ForceWindowToForeground(IntPtr hwnd)
{
    AttachedThreadInputAction(
        () =>
        {
            BringWindowToTop(hwnd);
            ShowWindow(hwnd, SW_SHOW);
        });
}

public static IntPtr SetFocusAttached(IntPtr hWnd)
{
    var result = new IntPtr();
    AttachedThreadInputAction(
        () =>
        {
            result = SetFocus(hWnd);
        });
    return result;
}


Besic Denis

А как насчет большой записки, окрашенной в красный цвет поверх статьи? Были ли у вас проблемы со стабильностью приложения?

ShlomiO

Да, в конце концов у нас действительно были проблемы с этим решением.
Похоже, что обновления windows приводят к тому, что это решение не является стабильным.