Мне было поручено создать модуль запуска приложений, на котором размещаются приложения Winforms и WPF, а также веб-приложения с несколько иной методологией.Пользователю предоставляется список приложений, которые они могут запустить, и они «захватываются» при запуске и помещаются в панель на форме с помощью SetParent, чтобы сделать панель родителем процессов MainWindowHandle.Похоже, этот бит работает хорошо, и приложения при запуске захватываются и отображаются на данной панели.
У меня есть особая проблема в том, что не все захваченные приложения изначально рады нарисовать себя на панели.,Кажется, что он изолирован от тех приложений, которые основаны на WPF, но это не гарантируется.
В действительности получается, что если приложение WPF запускается, оно захватывается и перемещается на панель, а панель остаетсяпусто, пока я не нажму на панель, и в этот момент приложение будет счастливо перекрашено.С этого момента приложение выглядит достаточно счастливым, перерисовывая себя, как требуется, без вмешательства.
По сути, теперь я в своем уме и попробовал следующие собственные методы User32 и .NET;Invalidate (в форме, на панели, на элементе управления вкладками, на котором размещены оба из них) Обновите Refresh SendMessage с множеством параметров, включая попытку «вам не следует этого делать» WM_PAINT.RedrawWindow с флагами UpdateNow и Invalidate.
Ничто из вышеперечисленного не имеет какого-либо видимого различия, и только когда я физически щелкаю по панели или перемещаю окно, приложение будет вести себя и перерисовывать себя.
Кто-нибудь еще произвел что-нибудь подобное и нашел решение проблемы перерисовки / перерисовки?Я обыскивал все сферы Google / Bing / Duck Duck Go, пытаясь найти ответ, но безрезультатно.
Надеюсь, у одного из вас есть ответ.
Следующий код представляетОсновная часть функции заключается в том, что он запускает процесс и захватывает дескриптор главного окна процесса и устанавливает его родительский элемент для элемента управления панели в стандартном окне WinForms.Я, вероятно, должен отметить, что стандартное окно WinForms «болота» само «размещено» внутри приложения с использованием библиотеки ( EasyTabs ).Что, я считаю, не вызывает никаких проблем.
Пример:
// Try to acquire a the process.
ProcessStartInfo startInfo = new ProcessStartInfo(path);
try
{
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
Process.StartInfo = startInfo;
Process.EnableRaisingEvents = true;
Process.Exited += TabManagerContainerForm_ProcessExited;
Process.Start();
if (Process != null)
{
// Wait until the process has created a main window or exited.
while (Process.MainWindowHandle == IntPtr.Zero && !Process.HasExited)
{
Thread.Sleep(100);
Process.Refresh();
}
if (!Process.HasExited) // We have acquired a MainWindowHandle
{
// Capture the Process's main window and show it inside the applicationPanel panel control.
SetParent(Process.MainWindowHandle, applicationPanel.Handle);
// Change the captured Process's window to one without the standard chrome. Itʼs provided by our tabbed application.
SetWindowLong(Process.MainWindowHandle, (int)WindowLongFlags.GWL_STYLE, (int)WindowStyles.WS_VISIBLE);
}
else // Process has exited.
{
if (Process.MainWindowHandle == IntPtr.Zero) Log.Information("{0} failed to execute.", Process.ProcessName);
throw new FailedProcessException(string.Format("{0} failed to execute.", path));
}
}
else
{
throw new Exception(string.Format("Invalid path: {0}", path));
}
}
catch (Exception ex) when (!(ex is FailedProcessException)) // Catch everything but FailedProcessExceptions. FPEs are simply passed up the chain.
{
Log.Error(ex.Message);
throw;
}