Необходимо активировать окно

У меня такая ситуация. У меня есть дескриптор окна приложения. Мне нужно его активировать. Я пробовал все эти функции, но не всегда работает. (В большинстве случаев это не работает в первый раз, и мне придется вручную щелкнуть по нему, чтобы активировать его. Вторая попытка и далее работает нормально) Причина, по которой я Я делаю это потому, что у меня есть код, написанный в событии Form.Activate формы, которую мне нужно выполнить. Приложение - это приложение с одним экземпляром. Когда создается новый экземпляр, он сначала проверяет наличие любого другого процесса. Если он найден, дескриптор старого процесса передается этим функциям, чтобы пользователь мог работать со старой формой. Приложение вызывается из другого приложения C. [DllImport ("user32.dll")] общедоступный статический внешний int ShowWindow (IntPtr hWnd, int nCmdShow);

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

    [DllImport("user32")]
    public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

person Ananth    schedule 24.09.2010    source источник


Ответы (3)


SetForgroundWindow работает только в том случае, если его процесс имеет фокус ввода. Вот что я использую:

public static void forceSetForegroundWindow( IntPtr hWnd, IntPtr mainThreadId )
{
    IntPtr foregroundThreadID = GetWindowThreadProcessId( GetForegroundWindow(), IntPtr.Zero );
    if ( foregroundThreadID != mainThreadId )
    {
        AttachThreadInput( mainThreadId, foregroundThreadID, true );
        SetForegroundWindow( hWnd );
        AttachThreadInput( mainThreadId, foregroundThreadID, false );
    }
    else
        SetForegroundWindow( hWnd );
}
person Dan Byström    schedule 24.09.2010
comment
+1 Конечно, гуру Windows Раймонд Чен говорит, что это может привести к зависанию вашего приложения - person MarkJ; 25.09.2012
comment
Где взять mainThreadId и что это значит? Спасибо! - person Anatolii Humennyi; 15.07.2014

Вам нужно найти окно, используя что-то вроде заголовка окна, а затем активировать его следующим образом:

public class Win32 : IWin32
{
    //Import the FindWindow API to find our window
    [DllImport("User32.dll", EntryPoint = "FindWindow")]
    private static extern IntPtr FindWindowNative(string className, string windowName);

    //Import the SetForeground API to activate it
    [DllImport("User32.dll", EntryPoint = "SetForegroundWindow")]
    private static extern IntPtr SetForegroundWindowNative(IntPtr hWnd);

    public IntPtr FindWindow(string className, string windowName)
    {
        return FindWindowNative(className, windowName);
    }

    public IntPtr SetForegroundWindow(IntPtr hWnd)
    {
        return SetForegroundWindowNative(hWnd);
    }
}

public class SomeClass
{
    public void Activate(string title)
    {
        //Find the window, using the Window Title
        IntPtr hWnd = win32.FindWindow(null, title);
        if (hWnd.ToInt32() > 0) //If found
        {
            win32.SetForegroundWindow(hWnd); //Activate it
        }
    }
}
person TheCodeKing    schedule 24.09.2010

Вы должны получить форму с помощью FromHandle:

f = Control.FromHandle(handle)

тогда вы можете вызвать Activate по результату:

 f.Activate()
person vulkanino    schedule 24.09.2010
comment
Проблема в том, что это работает только для элементов управления в одном приложении. Чтобы активировать окно в другом процессе, вам необходимо использовать функции PInvoke. - person TheCodeKing; 24.09.2010