質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

7461閲覧

WPFで別アプリケーションを子ウィンドウとして貼り付けたい

taruto_11

総合スコア4

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

1グッド

1クリップ

投稿2020/02/27 13:51

現在WPFを使ってエディターを作成しています。
別アプリケーションはC++で作成しています。
・WindowsFormsHostを使ってウィンドウを用意
・Processクラスで別アプリケーションを起動

ここまでは行けたのですが、SetParent()を通るとウィンドウが消えてしまいます。
ですが、タスクマネージャーで確認すると起動しています。

アプリケーションは単体で起動することは確認していて、エラーを出すことはありません。

C#

1 2 3[System.Runtime.InteropServices.DllImport("user32.dll")] 4static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 5 6[DllImport("user32.dll", SetLastError = true)] 7private static extern int MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, int bRepaint); 8 9 10 11void Test() 12{ 13 Process p = new Process(); 14 p = Process.Start(file_directory + "/game.exe"); 15 16 p.WaitForInputIdle(); 17 SetParent(p.MainWindowHandle, gameWindow_Handle); 18 p.WaitForInputIdle(); 19 MoveWindow(p.MainWindowHandle, 0, 0, 500, 600, 1); 20} 21 22
TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

WPFにそのような機能はありません。
また私が知る限り、WPF以外でも別プロセスを統合するような機能を持ったフレームワークもありません。
技術的に不可能ではありませんが、OSの仕組みから理解し地味で面倒な作業が沢山必要になります。
根本的に何がやりたいかは不明ですが、そのアプローチは恐ろしく遠回りであることは間違いありません。

投稿2020/02/28 01:34

hihijiji

総合スコア4150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

この手法は裏技?だと思うので、アプリごとに試行錯誤が必要になると思います。
APIの呼び出し順やパラメータがシビアで、ちょっとの違いでできたりできなかったりします。

xml

1<Window 2 x:Class="Questions243916.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:forms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" 6 Width="800" 7 Height="450"> 8 <Grid> 9 <Grid.ColumnDefinitions> 10 <ColumnDefinition /> 11 <ColumnDefinition Width="Auto" /> 12 <ColumnDefinition /> 13 </Grid.ColumnDefinitions> 14 <WindowsFormsHost> 15 <forms:Control x:Name="notepad" /> 16 </WindowsFormsHost> 17 <GridSplitter 18 Grid.Column="1" 19 Width="8" 20 HorizontalAlignment="Stretch" 21 Background="DarkGray" /> 22 <WindowsFormsHost Grid.Column="2"> 23 <forms:Control x:Name="paint" /> 24 </WindowsFormsHost> 25 </Grid> 26</Window>

cs

1using System; 2using System.Diagnostics; 3using System.Runtime.InteropServices; 4using System.Threading; 5using System.Windows; 6 7namespace Questions243916 8{ 9 public partial class MainWindow : Window 10 { 11 [DllImport("user32")] private static extern int GetWindowLong(IntPtr hWnd, int nIndex); 12 [DllImport("user32")] private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 13 [DllImport("user32")] private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 14 [DllImport("user32")] private static extern int MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, int bRepaint); 15 16 private const int GWL_STYLE = -16; 17 private const int WS_THICKFRAME = 0x00040000; 18 private const int WS_CAPTION = 0x00C00000; 19 private const int WS_CHILD = 0x40000000; 20 21 22 public MainWindow() 23 { 24 InitializeComponent(); 25 26 { 27 var p = Process.Start(new ProcessStartInfo 28 { 29 FileName = "notepad", 30 31 // HiddenとしたいがMainWindowHandleが0になる 32 // FindWindowで探す必要あり 面倒なのでMinimized 33 //WindowStyle = ProcessWindowStyle.Hidden, 34 WindowStyle = ProcessWindowStyle.Minimized, 35 }); 36 p.WaitForInputIdle(); 37 38 var style = GetWindowLong(p.MainWindowHandle, GWL_STYLE); 39 style = style & ~WS_CAPTION & ~WS_THICKFRAME; 40 //style |= WS_CHILD; // メニュー有無 41 SetWindowLong(p.MainWindowHandle, GWL_STYLE, style); 42 43 SetParent(p.MainWindowHandle, notepad.Handle); 44 45 notepad.SizeChanged += (s, e) 46 => MoveWindow(p.MainWindowHandle, 0, 0, notepad.Width, notepad.Height, 1); 47 } 48 49 { 50 var p = Process.Start(new ProcessStartInfo 51 { 52 FileName = "mspaint", 53 WindowStyle = ProcessWindowStyle.Minimized, 54 }); 55 p.WaitForInputIdle(); 56 Thread.Sleep(500); // ウェイトがないと入らなかった 57 58 var style = GetWindowLong(p.MainWindowHandle, GWL_STYLE); 59 style = style & ~WS_CAPTION & ~WS_THICKFRAME; 60 SetWindowLong(p.MainWindowHandle, GWL_STYLE, style); 61 62 SetParent(p.MainWindowHandle, paint.Handle); 63 64 // なんかずれる それっぽくなったが根拠なし 65 var offset = (int)SystemParameters.MenuHeight 66 + (int)SystemParameters.ResizeFrameHorizontalBorderHeight * 2; 67 paint.SizeChanged += (s, e) 68 => MoveWindow(p.MainWindowHandle, 0, -offset, paint.Width, paint.Height + offset, 1); 69 } 70 } 71 } 72}

メモ帳とペイントを入れるだけでかなり苦労しました^^;

投稿2020/02/28 10:31

編集2023/07/20 15:33
TN8001

総合スコア9326

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taruto_11

2020/03/26 07:54

WindowStyle = "None" AllowsTransparency = "False" がついているとSetParent()が反応しないっぽいです。 比較するときに役に立ちました。ありがとうございます!
taruto_11

2020/03/26 07:57

すいません間違えました。 AllowsTransparency = "True" でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問