我要在wince5.0上全屏显示视频,并在视频上显示按钮和文本。
通过网络得到了各种方法,总结一下:
基于的是对话框,视频显示在对话框的DC上:生成一个兼容的mem DC,然后,生成一个位图bmp,将mem DC和bmp关联,摄像头数据刷到bmp上,然后用Bitblt从Mem DC上传到DC上。貌似这就是传说中的双缓冲!~~~
文字的显示方法:
1.直接在对话框DC上输出文字,Textout或Drawtext(wince)之类的
经过验证,这种方法,会造成文字的闪烁,网上说是因为多次刷屏的原因,应该是,DC输出文字的时候会刷一次屏
(刷一次屏,指的是,将显示缓冲区擦出:换上背景色,然后将更新的缓冲区刷上),Bitblt也要刷一次屏,所以会导致字闪烁。我测试过,先显示字,再显示视频,字会比较淡;顺序颠倒一下,字会比较真;但是都会闪烁。因为文字上显示视频会将字刷掉,而视频上显示文字不会将除字之外的视频刷掉。所以,字会闪,而视频并不会闪。
2.在对话框前面生成一个新的窗口,然后,在那个对话框上显示视频。因为要将按钮和文字显示在视频上,所以这个涉及到Z轴的操作,设置窗口位置的函数SetWindowPos有个参数可以设置为TOP,BOTTOM之类的,似乎不怎么管用,后来,没深究了。
3.还有一种方法,在对话框上添加一个静态文本控件,然后,将静态文本控件背景设置为透明的。这种方法,如果在OnCtlColor中,返回一个NULL_BRUSH,会导致文本重叠,因为没有返回刷控件背景的刷子,所以控件背景没有更新,所以,上一次的内容还在,然后,输出文字,会造成文本和上一次的重叠(静态文本似乎是先刷背景,再刷文字的)。不过,http://blog.csdn.net/sunwill_chen/article/details/5615928提供了一种方法,可以得到控件背景的刷子,然后,在OnCtlColor中返回这把刷子就好了。但是,这种适用于静态的背景,我的是视频的,我试过,刷视频和刷控件不可能同时,在下一个视频帧刷上时候,控件的背景还没有更新,这时会看到上一个视频帧的背景还在,呵呵,挺有意思的。
4.还是1的方法,在对话框DC上输出文字,不过,在mem DC上将文字输出之后,在一下Bitblt刷到屏幕上。这是看到这个帖子后的:
http://topic.csdn.net/u/20070205/20/d9d39f9b-1b1e-4e82-99fc-101f293832b0.html?seed=1436112382&r=55823679#r_55823679
DC和MEM DC代码:
CDC *pDC = GetDC(); HDC hDc = pDC->m_hDC; if(hDc) { // m_nBitsPixel = ::GetDeviceCaps(hDc, BITSPIXEL); m_nBitsPixel = 24; m_hTmpDc = ::CreateCompatibleDC(hDc); if(m_hTmpDc) { m_hBmp = ::CreateBitmap(m_nWidth, m_nHeight, 1, m_nBitsPixel, NULL); if(m_hBmp) ::SelectObject(m_hTmpDc, m_hBmp); } ::ReleaseDC(GetSafeHwnd(), hDc); hDc = NULL; } ReleaseDC(pDC); pDC = NULL;
hdc = ::GetDC(hWnd); if(hdc) { ::SetBitmapBits(m_hBmp, m_nWidth * m_nHeight * (m_nBitsPixel >> 3), pBuffer); // CDC dc; dc.Attach(m_hTmpDc); dc.SetBkMode(TRANSPARENT); dc.SelectObject(m_Font); dc.SetTextColor(RGB(255, 0, 0)); dc.DrawText(strText,CRect(0,0,200,200),DT_LEFT); dc.Detach(); // ::BitBlt(hdc, 0, 0, m_nWidth, m_nHeight, m_hTmpDc, 0, 0, SRCCOPY); ::ReleaseDC(hWnd, hdc); hdc = NULL; return TRUE; }