2015-07-21 7 views
0

Мне нужно, чтобы мое окно было поверх другого окна. Это «другое» окно (приложение) принадлежит другому разработчику. У меня нет исходных кодов. Я могу использовать Spy ++ только для получения информации об этом.Не могу заставить мое окно быть наверху

Я использую Windows 7.

я судимый несколько вещей, но они не работали.

Это то, что я судимый до сих пор:

1) Таймер + BringWindowToTop

2) Я изменил владелец моего окна

 IntPtr handle = User32.FindWindow("Vega Prime", "Vega Prime"); 

     NativeWindow win = new NativeWindow(); 
     win.AssignHandle(handle); 

     ChildForm form = new ChildForm(); 
     form.Show(win); 

Когда я говорю, что он не работает I означают это:

1) сначала все выглядит хорошо: мое окно наверху

2), то я нажимаю на окно (Vega Prime), который находится ниже шахты

3) мое окно исчезает

4) я нажимаю на месте, где мое окно должно быть, и это вновь появляется (!!!!!!)

Что это? Как это вообще возможно?

UPDATE:

Я провел некоторое время, пытаясь найти решение моей проблемы. Вот что я нашел:

TopMost window going behind non-TopMost fullscreen window sometimes

https://social.msdn.microsoft.com/Forums/vstudio/en-US/92e66584-6cb8-4976-9531-eab3b9a129e3/mfc-window-with-wsextopmost-hidden-by-full-screen-window?forum=vcgeneral

Я уверен, что моя проблема имеет что-то делать с «Full Screen Issue» в Windows 7 (иногда, когда не самое верхнее окно становится в полноэкранном режиме он заставляет верхние окна большинства скрываться). Это объясняет описанное выше странное поведение, не так ли?

+1

'this.TopMost = true;' –

ответ

0

Оказалось, что «другое» приложение (которое я пытаюсь объединить с моим приложением) использует полноэкранный эксклюзивный режим. Это объясняет, почему мое верхнее окно исчезло из виду и никогда не появлялось (если я не выключу полноэкранный режим с помощью мыши).

Подробнее о полноэкранном режиме монопольного здесь:

https://docs.oracle.com/javase/tutorial/extra/fullscreen/exclusivemode.html

Основная идея заключается в том, что Full-Screen Exclusive Mode «позволяет программисту приостановить оконную систему так, что рисунок может быть сделано непосредственно к экран». Я считаю, что это означает, что во время полноэкранного эксклюзивного режима (некоторые эксперты называют это «реальным полноэкранным») OS игнорирует разные окна (для экономии ресурсов).

Единственное решение в такой ситуации - настроить «другое» приложение для отключения полноэкранного режима.

Это помогло в моем случае - я изучил документацию и нашел место в файле конфигурации, где для установки полноэкранного режима на значение false.

0

я понял, что это пример того, что, кажется, сделать трюк:

public partial class Form1 : Form 
{ 
    IntPtr hWndToStayOver = User32.FindWindow("Vega Prime", "Vega Prime"); 
    private System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer(); 

    public Form1() 
    { 
     InitializeComponent(); 
     this.Load += new EventHandler(this.Form1_Load); 
     this.FormClosing += new FormClosingEventHandler(Form1_FormClosing); 
     this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     timer1.Start(); // Routine starts now that I'm sure my Form exists 
    } 

    void Form1_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     timer1.Stop(); // Stop routine (my Form doesn't exist anymore) 
    } 

    private bool AmIAboveOtherWindow() 
    { 
     IntPtr tmpHwnd = User32.GetNextWindow(hWndToStayOver, User32.GetNextWindowCmd.GW_HWNDPREV); 
     while (tmpHwnd != (IntPtr)0) 
     { 
      if (tmpHwnd == this.Handle) 
       return true; 

      tmpHwnd = User32.GetNextWindow(tmpHwnd, User32.GetNextWindowCmd.GW_HWNDPREV); 
     } 
     return false; 
    } 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     timer1.Stop(); 
     if (!AmIAboveOtherWindow()) // Check if I am behind the target window 
     { 
      User32.SetWindowPos(this.Handle, hWndToStayOver, 0, 0, 0, 0, // Move my Form behind the target 
       User32.SetWindowPosFlags.SWP_NOMOVE | 
       User32.SetWindowPosFlags.SWP_NOSIZE | 
       User32.SetWindowPosFlags.SWP_SHOWWINDOW | 
       User32.SetWindowPosFlags.SWP_NOACTIVATE | 
       User32.SetWindowPosFlags.SWP_ASYNCWINDOWPOS); 

      User32.SetWindowPos(hWndToStayOver, this.Handle, 0, 0, 0, 0, // Move target behind my Form 
       User32.SetWindowPosFlags.SWP_NOMOVE | 
       User32.SetWindowPosFlags.SWP_NOSIZE | 
       User32.SetWindowPosFlags.SWP_SHOWWINDOW | 
       User32.SetWindowPosFlags.SWP_NOACTIVATE | 
       User32.SetWindowPosFlags.SWP_ASYNCWINDOWPOS); 
     } 
     timer1.Start(); 
    } 
} 

User32 класс

public class User32 
{ 
    [Flags] 
    public enum SetWindowPosFlags : uint 
    { 
     SWP_ASYNCWINDOWPOS = 0x4000, 
     SWP_DEFERERASE = 0x2000, 
     SWP_DRAWFRAME = 0x0020, 
     SWP_FRAMECHANGED = 0x0020, 
     SWP_HIDEWINDOW = 0x0080, 
     SWP_NOACTIVATE = 0x0010, 
     SWP_NOCOPYBITS = 0x0100, 
     SWP_NOMOVE = 0x0002, 
     SWP_NOOWNERZORDER = 0x0200, 
     SWP_NOREDRAW = 0x0008, 
     SWP_NOREPOSITION = 0x0200, 
     SWP_NOSENDCHANGING = 0x0400, 
     SWP_NOSIZE = 0x0001, 
     SWP_NOZORDER = 0x0004, 
     SWP_SHOWWINDOW = 0x0040, 
    } 

    public enum GetNextWindowCmd : uint 
    { 
     GW_HWNDNEXT = 2, 
     GW_HWNDPREV = 3, 
    } 

    [DllImport("user32.dll", SetLastError = true)] 
    public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags); 
    [DllImport("user32.dll", SetLastError = true)] 
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 
    [DllImport("user32.dll", SetLastError = true, EntryPoint = "GetWindow")] 
    public static extern IntPtr GetNextWindow(IntPtr hWnd, GetNextWindowCmd uCmd); 
} 

Очевидно, что вы должны добавить к этому коду некоторые проверки на целевой ручки: Этот пример работает только если целевое окно существует, когда форма загружена и если она не закрыта до конца

+0

Пожалуйста, взгляните на мое обновление. – walruz

+0

Спасибо - я дам ему попробовать – walruz

+0

@walruz: это определенно не путь. Решение состоит в том, чтобы установить права собственности на b/w 2 окна с помощью одного окна api: SetWindowLong или SetWindowLongPtr. –

0

Убедитесь, что вы установили владельца окна в другое окно. Это позволит убедиться, что ваше окно всегда находится на вершине владельца. Here Как импортировать appr. нативные функции, просто измените «Get» на «Set» повсюду.

Тогда вы можете вызвать его так:

SetWindowLong(handle_of_owned_window, -8, handle_of_owner_window); 

Подсказку # 1: это легко установить владелец B/W 2 случаев Формы через Form.Owner собственности, однако у вас нет доступа к одному из их Формы.

Подсказка № 2: чтобы получить доступ к ручке окна, она должна отображаться как минимум один раз.

+0

Пожалуйста, взгляните на обновление моего вопроса. – walruz

+0

Исправьте меня, если я ошибаюсь, но вы не хотите, чтобы ваше окно располагалось поверх всего (например, блокнот). Вы только хотите быть на вершине определенного окна, чей дескриптор вы получаете с помощью FindWindow api ... –

+0

Для меня это не имеет значения. Я сделал свое окно TopMost в самом начале. Тем не менее мое окно исчезло из виду. Что вы думаете об этом «Full Screen Issue» в Windows 7 ??? – walruz

Смежные вопросы