下面是将窗口内的图像采集生成一个BITMAP文件的过程,只要在去掉存储的过程,在修改一下采集的范围就可以使用,在类似于ONTIME之类的过程中调用,就可以实时处理了
m_hMciWnd 是播放窗口的句柄
HDC hdcDC = ::GetDC(m_hMciWnd);
RECT rcRect;
::GetClientRect(m_hMciWnd ,&rcRect);
HDC memDC;
memDC = ::CreateCompatibleDC(hdcDC);
HBITMAP hbitmap = ::CreateCompatibleBitmap(hdcDC, rcRect.right,rcRect.bottom);
HBITMAP holdbitmap = (HBITMAP)::SelectObject(memDC, hbitmap); ::ShowWindow(m_hMciWnd, SW_HIDE);
Sleep(500);
::ShowWindow(m_hMciWnd, SW_SHOWNA);
::SetWindowPos(m_hMciWnd, NULL, rcRect.left, rcRect.right, (rcRect.right - rcRect.left)/2,
(rcRect.bottom - rcRect.top)/2, SWP_NOMOVE);
::SetWindowPos(m_hMciWnd, NULL, rcRect.left, rcRect.right, rcRect.right - rcRect.left,
rcRect.bottom - rcRect.top, SWP_NOMOVE); int b = ::BitBlt(memDC, rcRect.left,rcRect.top,rcRect.right,rcRect.bottom,
hdcDC,0,0, SRCCOPY);
if(strFileName.IsEmpty())
{
CFileDialog BmpFile(FALSE,"BMP",strFileName,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
"BMP图像文件 (*.bmp)|*.bmp||");
if(BmpFile.DoModal() != IDOK)
{
::SelectObject(memDC,holdbitmap);
::DeleteDC(hdcDC);
::DeleteDC(memDC);
if(result == MCI_MODE_PLAY)
MCIWndPlay(m_hMciWnd);
return FALSE;
}
strFileName = BmpFile.GetFileName();
}
CBitmap *bitmap = CBitmap::FromHandle(hbitmap);
BITMAP bitmapinfo;
bitmap->GetBitmap(&bitmapinfo);
WORD cClrBits;
cClrBits = (WORD)(bitmapinfo.bmPlanes * bitmapinfo.bmBitsPixel);
if (cClrBits == 1)
cClrBits = 1;
else if (cClrBits <= 4)
cClrBits = 4;
else if (cClrBits <= 8)
cClrBits = 8;
else if (cClrBits <= 16)
cClrBits = 16;
else if (cClrBits <= 24)
cClrBits = 24;
else cClrBits = 32;
PBITMAPINFO pbmi;
if (cClrBits != 24)
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * (1<< cClrBits));
else
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER)); pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = bitmapinfo.bmWidth;
pbmi->bmiHeader.biHeight = bitmapinfo.bmHeight;
pbmi->bmiHeader.biPlanes = bitmapinfo.bmPlanes;
pbmi->bmiHeader.biBitCount = bitmapinfo.bmBitsPixel;
if (cClrBits < 24)
pbmi->bmiHeader.biClrUsed = (1<<cClrBits); pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
* pbmi->bmiHeader.biHeight;
pbmi->bmiHeader.biClrImportant = 0;
PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER) pbmi;
LPBYTE lpBits;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
::GetDIBits(memDC, hbitmap, 0, (WORD) pbih->biHeight, lpBits, pbmi,
DIB_RGB_COLORS);
BITMAPFILEHEADER fiHead;
fiHead.bfType = 0x4d42;
fiHead.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
pbih->biSize +
pbih->biClrUsed* sizeof(RGBQUAD) +
pbih->biSizeImage);
fiHead.bfReserved1 = 0;
fiHead.bfReserved2 = 0;
fiHead.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
pbih->biSize +
pbih->biClrUsed* sizeof (RGBQUAD);
CFile file(strFileName,CFile::modeCreate | CFile::modeWrite);
file.WriteHuge(&fiHead, sizeof(BITMAPFILEHEADER));
file.WriteHuge((LPVOID) pbih, sizeof(BITMAPINFOHEADER)
+ pbih->biClrUsed * sizeof (RGBQUAD)) ;
DWORD dwTotal;
DWORD cb;
BYTE *hp;
dwTotal = cb = pbih->biSizeImage;
hp = lpBits;
file.WriteHuge((LPSTR) hp, (int) cb);
file.Close();
GlobalFree((HGLOBAL)lpBits);
::SelectObject(memDC,holdbitmap);
::DeleteDC(hdcDC);
::DeleteDC(memDC);
if(result == MCI_MODE_PLAY)
MCIWndPlay(m_hMciWnd);
Invalidate();
m_hMciWnd 是播放窗口的句柄
HDC hdcDC = ::GetDC(m_hMciWnd);
RECT rcRect;
::GetClientRect(m_hMciWnd ,&rcRect);
HDC memDC;
memDC = ::CreateCompatibleDC(hdcDC);
HBITMAP hbitmap = ::CreateCompatibleBitmap(hdcDC, rcRect.right,rcRect.bottom);
HBITMAP holdbitmap = (HBITMAP)::SelectObject(memDC, hbitmap); ::ShowWindow(m_hMciWnd, SW_HIDE);
Sleep(500);
::ShowWindow(m_hMciWnd, SW_SHOWNA);
::SetWindowPos(m_hMciWnd, NULL, rcRect.left, rcRect.right, (rcRect.right - rcRect.left)/2,
(rcRect.bottom - rcRect.top)/2, SWP_NOMOVE);
::SetWindowPos(m_hMciWnd, NULL, rcRect.left, rcRect.right, rcRect.right - rcRect.left,
rcRect.bottom - rcRect.top, SWP_NOMOVE); int b = ::BitBlt(memDC, rcRect.left,rcRect.top,rcRect.right,rcRect.bottom,
hdcDC,0,0, SRCCOPY);
if(strFileName.IsEmpty())
{
CFileDialog BmpFile(FALSE,"BMP",strFileName,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
"BMP图像文件 (*.bmp)|*.bmp||");
if(BmpFile.DoModal() != IDOK)
{
::SelectObject(memDC,holdbitmap);
::DeleteDC(hdcDC);
::DeleteDC(memDC);
if(result == MCI_MODE_PLAY)
MCIWndPlay(m_hMciWnd);
return FALSE;
}
strFileName = BmpFile.GetFileName();
}
CBitmap *bitmap = CBitmap::FromHandle(hbitmap);
BITMAP bitmapinfo;
bitmap->GetBitmap(&bitmapinfo);
WORD cClrBits;
cClrBits = (WORD)(bitmapinfo.bmPlanes * bitmapinfo.bmBitsPixel);
if (cClrBits == 1)
cClrBits = 1;
else if (cClrBits <= 4)
cClrBits = 4;
else if (cClrBits <= 8)
cClrBits = 8;
else if (cClrBits <= 16)
cClrBits = 16;
else if (cClrBits <= 24)
cClrBits = 24;
else cClrBits = 32;
PBITMAPINFO pbmi;
if (cClrBits != 24)
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * (1<< cClrBits));
else
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER)); pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = bitmapinfo.bmWidth;
pbmi->bmiHeader.biHeight = bitmapinfo.bmHeight;
pbmi->bmiHeader.biPlanes = bitmapinfo.bmPlanes;
pbmi->bmiHeader.biBitCount = bitmapinfo.bmBitsPixel;
if (cClrBits < 24)
pbmi->bmiHeader.biClrUsed = (1<<cClrBits); pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
* pbmi->bmiHeader.biHeight;
pbmi->bmiHeader.biClrImportant = 0;
PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER) pbmi;
LPBYTE lpBits;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
::GetDIBits(memDC, hbitmap, 0, (WORD) pbih->biHeight, lpBits, pbmi,
DIB_RGB_COLORS);
BITMAPFILEHEADER fiHead;
fiHead.bfType = 0x4d42;
fiHead.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
pbih->biSize +
pbih->biClrUsed* sizeof(RGBQUAD) +
pbih->biSizeImage);
fiHead.bfReserved1 = 0;
fiHead.bfReserved2 = 0;
fiHead.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
pbih->biSize +
pbih->biClrUsed* sizeof (RGBQUAD);
CFile file(strFileName,CFile::modeCreate | CFile::modeWrite);
file.WriteHuge(&fiHead, sizeof(BITMAPFILEHEADER));
file.WriteHuge((LPVOID) pbih, sizeof(BITMAPINFOHEADER)
+ pbih->biClrUsed * sizeof (RGBQUAD)) ;
DWORD dwTotal;
DWORD cb;
BYTE *hp;
dwTotal = cb = pbih->biSizeImage;
hp = lpBits;
file.WriteHuge((LPSTR) hp, (int) cb);
file.Close();
GlobalFree((HGLOBAL)lpBits);
::SelectObject(memDC,holdbitmap);
::DeleteDC(hdcDC);
::DeleteDC(memDC);
if(result == MCI_MODE_PLAY)
MCIWndPlay(m_hMciWnd);
Invalidate();
我想是否可以用内嵌汇编语言直接读取显卡内容?《Windows图形编程》有这个例程,我还没试的。
,已经搞定了。
后来我发现其实只要不是使用directDraw来播放的AVI窗口,通常的屏幕捕捉代码都可以实现的。
如果没什么其他问题,这个帖子近日内可以结掉了,谢谢。