简体   繁体   English

当子窗口成为 C# 桌面应用程序的子窗口时,C++ Windows 桌面应用程序中的持续闪烁?

[英]Constant flickering in C++ Windows desktop app when a child window is made the child of a C# desktop app?

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.我已经使用以下 SO 帖子中的信息在我的 C++ 桌面应用程序中创建图片控件的父级,在我的 C# 应用程序中创建面板控件的子级。 The C++ and C# apps are separate apps running in their own process: C++ 和 C# 应用程序是在自己的进程中运行的独立应用程序:

Various issues using SetParent to embed window into external process 使用 SetParent 将窗口嵌入外部进程的各种问题

Embedding HWND into external process using SetParent 使用 SetParent 将 HWND 嵌入到外部进程中

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. C# 应用程序启动 C++ 应用程序,在命令行上将面板控件的 Windows 句柄传递给它,该控件应该承载 C++ 应用程序的图片控件。 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.当我运行 C# 应用程序时,我确实在 C# 应用程序本机的指定面板控件上看到了 C++ 图片控件的轮廓。

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. 1) C++ 和 C# 应用程序闪烁得非常厉害,就像它们每秒都被重绘多次一样。

2) The picture control in the C++ app normally shows a video feed from my WebCam. 2) C++ 应用程序中的图片控件通常显示来自我的网络摄像头的视频源。 I BitBlt() the frames from the webcam into the C++ Picture control. I BitBlt() 将来自网络摄像头的帧转换为 C++ 图片控件。 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):这是 C++ 应用程序中的代码,它执行重新父级并将 C++ 主输入线程(拥有图片控件的线程)附加到属于 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)

我也遇到了这个问题,解决方法是父hwnd需要标志WS_CLIPCHILDREN。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM