A
A
Alexey Pavlov2017-11-23 18:29:37
WPF
Alexey Pavlov, 2017-11-23 18:29:37

How to properly open a window in another application?

I have two WPF applications. Through WCF, I send a message from the first application to the second to open a new window, moreover, the new window should appear on top of all other windows (including on top of the window of the first application).
If a new window is opened using the Show() method, then it is opened behind the current window (the window of the first application). The best way to open a new window is as follows:

window.Topmost = true;
window.Show();
window.Topmost = false;

The window appears on top of the first window and is activated. (It is interesting that the SetForegroundWindow, BringWindowToTop, SwitchToThisWindow winapi functions do not help, only .) The only problem remains is that the first window still considers itself activated and the focus remains on the first window - the keys work on the first window. Does not help. A mouse click on a new window transfers focus to it, and only then does the first window realize that it has lost focus and is deactivated. How to give focus to a new window? Topmost = true
window.Focus();

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Alexey Pavlov, 2017-12-01
@lexxpavlov

The description of the SetForegroundWindow function contains the conditions when this function works. In some cases, for some reason, the keyboard focus is not transferred to another window. More precisely, the second process that opens the window does not have focus. For some reason, in some cases this does not prevent it from opening the active window (apparently, one of the other conditions is triggered), but in some cases it cannot make the window active.
The solution is to simulate a keypress in a process that will open a window:

private const byte VK_LMENU = 0xA4;
private const byte KEYEVENTF_EXTENDEDKEY = 0x01;
private const byte KEYEVENTF_KEYUP = 0x02;
private const byte KEYSCAN_LALT = 0xB8;

[DllImport("user32.dll")]
internal static extern bool SetForegroundWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);

public static void BringWindowToFront(IntPtr hwnd)
{
    // симуляция нажатия клавиши ALT https://stackoverflow.com/a/13881647/1343405
    keybd_event(VK_LMENU, KEYSCAN_LALT, 0, 0);
    keybd_event(VK_LMENU, KEYSCAN_LALT, KEYEVENTF_KEYUP, 0);

    SetForegroundWindow(hwnd);
}

Useful links: question , article .

J
John_Nash, 2017-11-23
@John_Nash

Specially created a project and checked: SetForegroundWindow works great. I have a seven x64

A
Alexander Yudakov, 2017-11-24
@AlexanderYudakov

As far as I remember, SetForegroundWindow only works if it is called from the UI thread of the active application. Those. if one active application wants to make another application active - this is welcome. But if a background application wants to make itself active - no, no, the operating system will not allow any spammers to distract the user from work.
In our case, SetForegroundWindow(handle of application window 2) must be called from the application 1 UI thread.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question