I have used the information from the following SO posts to make the parent of a Picture control in my C++ Desktop app, the child of a Panel control in my C# app. The C++ and C# apps are separate apps running in their own process:
Various issues using SetParent to embed window into external process
Embedding HWND into external process using SetParent
I am using the code shown below to do the re-parenting. The C# app launches the C++ app, passing it on the command line the Windows handle of the Panel control that should host the C++ app's Picture control. When I run the C# app I do see the outline of the C++ Picture control on the designated Panel control that is native to the C# app.
However, I am having the following problems:
1) Both the C++ and C# apps flicker terribly like they are both being repainted many times a second.
2) The picture control in the C++ app normally shows a video feed from my WebCam. I BitBlt() the frames from the webcam into the C++ Picture control. It works fine without the re-parenting but with it, I don't see any frames at all.
NOTE: The flicker is definitely the result of drawing into the now re-parented child window. If I disable the that operation, the flicker doesn't happen.
Does anyone know what is wrong and how I can fix it? Here is the code in the C++ app that does the re-parenting and the attachment of the C++ main input thread (the thread that owns the Picture control) to the input thread belonging to the main thread of the C# app (the thread that owns the Panel control):
// 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)