使用线程进行gdi绘画 [英] gdi painting using Threading

查看:86
本文介绍了使用线程进行gdi绘画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我需要在视频上连续绘制一些形状.
我已使用直接播放进行视频播放和播放;用于绘制形状的gdi

现在假设要绘制形状,我已使用以下函数


in my application i need to draw some shapes over video continuously.
i have used direct show for video play back & gdi for drawing shapes

now suppose for drawing shapes i have used following function


void  threadPaint( void * )
{
	WINDOWPLACEMENT lpwndpl_v1;   
	GetWindowPlacement(hw,&lpwndpl_v1); // hw is handler to picture box control (used for video playback) 

	HDC hdc;
	hdc = BeginPaint(hw, &ps);                
	Graphics graphics(hw);      
	Pen  pen3(Color(255, 0,0,255),10);
	while(threadAna) /////////
	 {
      graphics.DrawLine(&pen3,lpwndpl_v1.rcNormalPosition.left+40,lpwndpl_v1.rcNormalPosition.top+90,lpwndpl_v1.rcNormalPosition.right,lpwndpl_v1.rcNormalPosition.top+90);
     }
EndPaint(hw, &ps);  
}




我使用
将此线程称为




i call this thread using

threadAna=1;
_beginthread( threadPaint, 0, (void*)12 );
Sleep(20);


在我的应用程序中,我使用了功能SetWindowPos()& ShowWindow()在各个地方.

例如在WM_MOUSEMOVE


in my application i used function SetWindowPos() & ShowWindow() at various places.

for example at WM_MOUSEMOVE

::SetWindowPos(GetDlgItem(g_hDialogWindow, IDC_MODE_TEXT), HWND_TOPMOST,  lpwndpl_home.rcNormalPosition.left+9,  lpwndpl_home.rcNormalPosition.bottom, 55,18,   SWP_NOZORDER );      

SetWindowText(GetDlgItem(g_hDialogWindow, IDC_MODE_TEXT), "HOME");
ShowWindow(GetDlgItem(g_hDialogWindow, IDC_MODE_TEXT), TRUE);



现在我的问题是,每当我移动或按下SetWindowPos()& ShowWindow()整个窗口都受到影响(我认为它以不寻常的方式进行了更新).

如果我不使用线程,则应用程序运行正常..



now my problem is that whenever i mouse move or press some button where i used SetWindowPos() & ShowWindow() whole window is affected(i think its updated in unusual way).

if i did not use the thread then application runs fine..

推荐答案

尝试使用以下原则:

仅在UI线程中进行所有渲染,但是渲染的结果将取决于某些数据,并且应该在线程之间共享数据,并使用关键部分将其互锁.更好的是,使用多个读取器/单个写入器锁,它可在Windows,boost等操作系统中使用:
http://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock [ ^ ],
另请参见此CodeProject文章: Ultra-simple C ++ Read/为Windows编写锁类 [ http://msdn.microsoft.com/en-us/library/ax04k970%28v = vs.71%29.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/dd145002%28v = vs.85%29.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/2f3csed3%28v = vs.80%29.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/dd145003%28v = vs.85%29.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/532h978c%28v = vs.80%29.aspx [ ^ ].

您可以通过仅重绘场景的一部分来使矩形或区域无效以获得一些性能.

另请参阅: http://msdn.microsoft.com/en-us /library/dd162759%28v=vs.85%29.aspx [
Try to use the following principles:

Do all your rendering only in the UI thread, but the result of rendering will depends on some data, and the data should be shared between threads, interlocked using Critical Section. Better yet, use multiple readers / single-writer lock, it is available in Windows, boost, etc.:
http://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock[^],
see also this CodeProject article: Ultra-simple C++ Read/Write Lock Class for Windows[^].

In the case of multi-reader lock, the writer is a non-UI thread which modifies data.

When data is modified, trigger sending WM_PAINT Windows message by calling one of Invalidate functions:
http://msdn.microsoft.com/en-us/library/ax04k970%28v=vs.71%29.aspx[^],
http://msdn.microsoft.com/en-us/library/dd145002%28v=vs.85%29.aspx[^],
http://msdn.microsoft.com/en-us/library/2f3csed3%28v=vs.80%29.aspx[^],
http://msdn.microsoft.com/en-us/library/dd145003%28v=vs.85%29.aspx[^],
http://msdn.microsoft.com/en-us/library/532h978c%28v=vs.80%29.aspx[^].

You can invalidate rectangle or region to gain some performance by repainting only a part of the scene.

See also: http://msdn.microsoft.com/en-us/library/dd162759%28v=vs.85%29.aspx[^].

—SA


这篇关于使用线程进行gdi绘画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆