次の SO 投稿の情報を使用して、C++ デスクトップ アプリの Picture コントロールの親を、C# アプリの Panel コントロールの子にしました。C++ アプリと C# アプリは、独自のプロセスで実行される個別のアプリです。
SetParent を使用してウィンドウを外部プロセスに埋め込むさまざまな問題
SetParent を使用して HWND を外部プロセスに埋め込む
以下に示すコードを使用して、親を再設定しています。C# アプリは C++ アプリを起動し、コマンド ラインで、C++ アプリの Picture コントロールをホストする Panel コントロールの Windows ハンドルを渡します。C# アプリを実行すると、C# アプリ固有の指定された Panel コントロールに C++ Picture コントロールのアウトラインが表示されます。
ただし、次の問題があります。
1) C++ と C# の両方のアプリが、1 秒間に何度も再描画されているように、ひどくちらつきます。
2) C++ アプリの画像コントロールは通常、WebCam からのビデオ フィードを表示します。I BitBlt() で Web カメラからのフレームを C++ ピクチャ コントロールに渡します。親を再設定しなくても問題なく動作しますが、フレームがまったく表示されません。
注: ちらつきは、間違いなく、親が変更された子ウィンドウに描画した結果です。その操作を無効にすると、ちらつきは発生しません。
誰が何が間違っているのか、どうすれば修正できるのか知っていますか? C# アプリのメイン スレッド (Picture コントロールを所有するスレッド) に属する入力スレッドに、C++ メイン入力スレッド (Picture コントロールを所有するスレッド) の再親化とアタッチを行う C++ アプリのコードを次に示します。パネル コントロール):
// The following code executes in the wWinMain() function of the C++
// app after the main dialog window and it's child controls have been
// setup and initialized. The value assigned to g_VideoHostContainerHWnd
// was passed to the C++ app by the C# app that launched it, as a
// command line argument, using the Panel control's Handle property
// converted to an unsigned integer.
g_OurMainThreadID = GetCurrentThreadId();
if (g_VideoHostContainerHWnd > 0)
{
// Make our video stream window a parent of the designated window
// in the HiveMind client.
// Get the window handle for the video stream window: IDC_PANEL_PICTURE.
HWND videoStreamWindow =
GetDlgItem(
g_HwndDlg,
IDC_PANEL_PICTURE);
if (videoStreamWindow > 0)
{
// Get the thread ID for the thread that owns the video host container window.
g_VideoHostThreadID = GetWindowThreadProcessId(
g_VideoHostContainerHWnd,
&g_VideoHostProcessID);
if (g_VideoHostThreadID > 0)
{
// Make the video stream window a child of the HiveMindClient window.
if (NULL == SetParent(videoStreamWindow, g_VideoHostContainerHWnd))
OutputDebugString(L"The reparenting of the video stream window FAILED.");
else
OutputDebugString(L"The reparenting of the video stream window SUCCEEDED.");
// Attach the our input thread to the thread ID for the process that launched us
// (i.e. - owns the video host window).
if (AttachThreadInput(g_OurMainThreadID, g_VideoHostThreadID, true))
OutputDebugString(L"Attaching our input thread to the video host thread SUCCEEDED.");
else
OutputDebugString(L"Attaching our input thread to the video host thread FAILED.");
}
else
{
OutputDebugString(L"The thread ID of the video host container's owner thread is ZERO.");
} // else - if (g_VideoHostThreadID > 0)
}
else
OutputDebugString(L"The video stream window handle is INVALID.");
} // if (g_VideoHostContainerHWnd > 0)