Вопрос по c# – Прикрепить окно формы к другому окну в C #

16

Я хочу прикрепить форму к другому окну (другого процесса). Я пытаюсь сделать это с помощью

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

setParentWindow(myWindowHwnd, newParentHwnd);

При этом моя форма привязывается, но такжеinvisible, Вопрос& quot; Прикрепить окно .. & quot; решает эту проблему для окна WPF, в основном с помощью

HwndSourceParameters parameters = new HwndSourceParameters();
...
HwndSource src = new HwndSource(parameters);

Я пытался перенести это в мою форму, но я не могу этого сделать (например, как справитьсяsrc.RootVisual = (Visual)window.Content; ? - & GT;Полный источник).

Еще один комментарий говорит, мне нужно изменить стиль окон:

For compatibility reasons, SetParent does not modify the WS_CHILD or WS_POPUP window styles of the window whose parent is being changed. Therefore, if hWndNewParent is NULL, you should also clear the WS_CHILD bit and set the WS_POPUP style after calling SetParent. Conversely, if hWndNewParent is not NULL and the window was previously a child of the desktop, you should clear the WS_POPUP style and set the WS_CHILD style before calling SetParent.

Здесь я пропускаю соответствующий API для этого, могу ли я сделать это непосредственно из C # или я должен использовать другойDllImport снова?

Добро или зло - SetParent () Win32 API между различными процессами не советует вообще прикреплять окна в разных процессах, но, по крайней мере, я хочу попробовать.

Question:

Что мне нужно сделать, чтобы окно формы было видно? Если подход сWS_Child правильный, как бы это установить? Или этоWPF подход путь, но как бы я применить его к форме окна?

- Выводы (позже добавлено) -

Изменить стиль Windows другого приложения, используя winAPI показывает, как изменить стиль из C # / PInvoke

Найти всестили окон здесь синтаксис C # внизу.

- Выводы из-за обсуждения с Аланом -

Я запустил мою программу на Win XP для перекрестной проверки (см. Ответ Алана ниже и комментарии). По крайней мере, я сейчас что-то вижу. Поскольку я добавил координаты, как в примерах Алана, мое окно теперь просвечивает в блокноте при перемещении по другому окну около левого верхнего угла. Вы все еще можете видеть текст, набранный в блокноте, как наложение. Под Win 7 (32) я вообще ничего не вижу.

Now I need to find out whether this can be written in a stable way, appearing on Win 7 as well. Nevertheless, I still cannot click any buttons on my form, needs to be solved too.

WinXP WinForm attached to notepad

Конечно, нет проблем, всего на секунду. Alan
Из любопытства я следовал этим рекомендациям и реализовал примитивное решение, которое, кажется, работает, конечно, с обычными предостережениями (например, указатели недействительны в другом процессе и т. Д.). Итак, ваш вопрос по-прежнему актуален, теперь, когда вы, по сути, ответили на него сами? Alan
Я все еще не вижу свое окно формы. Я попытался установить значения, как в "комментарии WS_Child", но безуспешно. Если у вас есть работающий / работающий пример на C #, я буду признателен, если вы опубликуете его. Это много следов и ошибок, может быть, я что-то пропустил. Я просто не могу вывести окно формы вперед / назад. Horst Walter

Ваш Ответ

2   ответа
3

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

Для меня проблема заключалась в прозрачности главной формы, которую вы хотите внутри другой формы.

Просто отключите прозрачность, и она должна работать.

Error: User Rate Limit Exceeded
13

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

Обычные предостережения, связанные с вопросом OP, также применимы к этому.

public partial class GuestForm: Form
{
  [DllImport("user32.dll")]
  public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

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

  [DllImport("user32.dll", SetLastError = true)]
  private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

  public static int GWL_STYLE = -16;
  public static int WS_CHILD = 0x40000000; 

  public GuestForm()
  {
    InitializeComponent();
  }

  private void button1_Click(object sender, EventArgs e)
  {
    MessageBox.Show("done");
  }

  private void button2_Click(object sender, EventArgs e)
  {
    Process hostProcess = Process.GetProcessesByName("HostFormApp").FirstOrDefault();
    if (hostProcess != null)
    {
      Hide();
      FormBorderStyle = FormBorderStyle.None;
      SetBounds(0, 0, 0, 0, BoundsSpecified.Location);

      IntPtr hostHandle = hostProcess.MainWindowHandle;
      IntPtr guestHandle = this.Handle;
      SetWindowLong(guestHandle, GWL_STYLE, GetWindowLong(guestHandle, GWL_STYLE) | WS_CHILD);
      SetParent(guestHandle, hostHandle);

      Show();
    }
  }
}
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Horst Walter
Error: User Rate Limit Exceeded Horst Walter
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Horst Walter

Похожие вопросы