即使我(想想我)关闭了背景擦除,我的凸轮视频显示也会闪烁。为什么呢?
即使视频演示文稿上方的文字显示也会闪烁。
完整代码at Bitbucket。
也许是最相关的代码,即显示视频的Gizmo:
class ImageDisplay:
public gizmo::SubGizmo
{
typedef gizmo::SubGizmo Base;
private:
winapi::graphics::ColorDib dib_;
protected:
void onPaint( raw::DcHandle const dc ) CPP_IS_OVERRIDE
{
dib_.renderOn( dc );
}
bool onWmEraseBkgnd( raw::DcHandle const dc )
{
CPP_DECLARE_UNUSED( dc );
return true; // Just say it's done, so it won't be done again.
}
void onWmPaint() CPP_IS_OVERRIDE
{
callOnPaint();
}
virtual raw::LResult dispatchWm(
raw::UInt const messageId,
raw::WParam const wParam,
raw::LParam const lParam
)
{
CPP_DUMMY_USE_OF( wParam ); CPP_DUMMY_USE_OF( lParam );
typedef ImageDisplay W;
switch( messageId )
{
case WM_ERASEBKGND:
return FORWARD_WM_TO( this, W::onWmEraseBkgnd, WM_ERASEBKGND, wParam, lParam );
}
return Base::dispatchWm( messageId, wParam, lParam );
}
public:
void setImage( cvapi::ImageRef const newImage )
{
dib_ = win_cv::dibFrom( newImage );
setExtent( newImage.extent() );
}
ImageDisplay(
Gizmo& parent,
int const x,
int const y,
cvapi::ImageRef const& pic
)
: Base( parent, x, y, pic.width(), pic.height() )
, dib_( win_cv::dibFrom( pic ) )
{}
};
视频制作人线程的主要代码:
void imageProducer(
wstring const& namePattern,
PutFunction const putResult,
Thread::Control const& threadControl
)
{
assert( !!putResult );
cv::VideoCapture cap( 0 ); // Open the default camera.
hopefully( cap.isOpened() )
|| throwX( "cam::imageProducer: VideoCapture::<init> failed" );
for(;;)
{
cv::Mat frame;
if( threadControl.exitIsRequested() ) { return; }
cap >> frame; // Get a new frame from camera.
if( threadControl.exitIsRequested() ) { return; }
putResult( frame );
}
}
putResult
函数只调用Windows的SendMessage
,它与显示线程同步。
我看不出闪烁是如何潜入的?
<小时/> 编辑:我找到了一个修复程序,即将
WS_CLIPCHILDREN
添加到主窗口,并使用RedrawWindow
强制立即重新绘制控件(子窗口)。很神秘,为什么它的工作原理。更大的谜团:没有应用RedrawWindow
,WS_CLIPCHILDREN
导致极度缓慢,例如每20秒1帧?
编辑2 :它没有持续。 : - (
编辑3 : * S O L V E D * 。并且 mea culpa 。所有这些闪烁都是由主窗口代码中对InvalidateRect
的不恰当调用引起的。我可能只是为了测试它而把它放在那里,并且忘了将它删除。哎呀!
答案 0 :(得分:2)
Mea culpa 。所有这些闪烁都是由主窗口代码中对Windows“InvalidateRect
的不恰当调用引起的。我可能把那个电话放在那里只是为了测试东西,而忘了把它删除。哎呀!
学习要点:
在完全检查自己代码中的所有内容之前,不要责怪“系统”(这里是Windows API,还有编译器等)。这就像你眼镜上的脏指纹。你永远不会把手指戴在眼镜上,然后出现这些指纹;与代码中神秘的不良陈述相同。