Как сохранить окно поверх другого окна в другом потоке? - PullRequest
0 голосов
/ 08 мая 2009

У меня есть форма WinForms (назовите ее «MyForm»), в которой размещается некоторый пользовательский интерфейс WPF (через ElementHost). Я показываю эту форму в отдельном потоке от основного потока пользовательского интерфейса.

Я хочу, чтобы «MyForm» оставалась поверх главного окна приложения, поэтому я показываю форму, используя перегрузку Show (IWin32Window) метода Show, а переданное IWin32Window является главным окном приложения.

Окно отображается косвенно через «форму запуска», которая является «формой приложения» отдельного потока STA (который передается в Application.Run). Причина этого заключается в том, что вы не можете указать окно владельца при запуске формы через Application.Run.

Вот код для запуска MyForm (используется как ThreadStart для потока STA):

void MyWindowThread()
{
  myForm = new MyForm();
  var launcherForm = new LauncherForm(myForm, mainWindow);
  Application.Run(new ApplicationContext(launcherForm));
  // launcherForm will Show myForm when it itself is shown.
}

Форма запуска:

public partial class LauncherForm : Form
{
  private readonly MyForm _myForm;
  private readonly IWin32Window _mainWindow;

  public WizardUILauncherForm(MyForm myForm, IWin32Window mainWindow)
  {
    _myForm = myForm;
    _mainWindow = mainWindow;
    InitializeComponent();
  }

  protected override void OnShown(EventArgs e)
  {
    // show the actual form that the user will interact with, on top of mainWindow.
    _myForm.Show(_mainWindow);
  }
}

Это почти работает. «MyForm» остается поверх главного окна приложения, но только до тех пор, пока я не наведу указатель мыши на элемент управления WPF. Когда отображается всплывающая подсказка, «MyForm» исчезает за основным окном приложения. Этого не происходит, когда я наведите курсор мыши на элемент управления WinForms в своей форме, чтобы отобразить его всплывающую подсказку - он кажется специфичным для элементов управления WPF.

Это также происходит, только когда MyForm является окном переднего плана.

Обратите внимание, что у меня возникает та же проблема, когда я использую MyForm в качестве формы приложения (пропуская панель запуска) и переопределяю метод OnLoad MyForm, чтобы установить его владельца с помощью SetWindowLong. Это менее сложный способ сделать это, но я хотел использовать механизм, который не использовал P-Invoke, чтобы посмотреть, будет ли это работать лучше. Оба метода ломаются одинаково.

Обновление Тестовое приложение подразумевает, что эта проблема относится только к отображению пользовательского интерфейса в расширении мастера Visual Studio. Что, я полагаю, делает его еще более нишевым и еще менее вероятным, чтобы на него ответили!

1 Ответ

0 голосов
/ 08 мая 2009

Следующая статья MSDN посвящена вызовам WinAPI, но, надеюсь, даст вам некоторое представление об активации окна между различными потоками (я предполагаю, что вам все равно придется напрямую вводить P / Invoke в WinAPI, если только вы не избежите использования пользовательского интерфейса в нескольких потоках). ):

Несколько потоков в пользовательском интерфейсе

(особенно см. Раздел Особенности фокусировки и активации окна )

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