2012-11-05 48 views
0

我们正在尝试开发一种解决方案,即需要远程监视Windows XP计算机的桌面屏幕。屏幕捕获后无法访问缓冲区数据

根据我们的经验,我们发现基于GDI的方法比DirectX前端缓冲区捕获更快。

在GDI中,我们正在获取屏幕的句柄,如下所示。

// Get the Desktop windows handle and device context 


    hDesktopWnd=GetDesktopWindow(); 
    hDesktopDC=GetDC(hDesktopWnd); 


// Get the handle to the existing DC and create a bitmap file object  

    HDC   hBmpFileDC=CreateCompatibleDC(hDesktopDC); 
    HBITMAP  hBmpFileBitmap=CreateCompatibleBitmap(hDesktopDC,nWidth,nHeight); 



// Assign the object in Memory DC to the bitmap and perform a bitblt 

    SelectObject(hBmpFileDC,hBmpFileBitmap); 
    BitBlt(hBmpFileDC,0,0,nWidth,nHeight,hDesktopDC,0,0,SRCCOPY|CAPTUREBLT); 


// Assign the bitmap handle to a CImage Object 


    CImage m_temp; 
    m_temp.Attach(hBmpFileBitmap); 
    m_temp.Save("d:\\Images\\Image10.bmp"); 

该操作保存在给定的路径,这意味着该对象实际上保持从屏幕上的数据的硬盘驱动器上的m_temp的CImage对象。但在我的应用程序中,我想处理桌面缓冲区中的图像,我需要图像数据缓冲区指针。但是当我调用可以返回数据指针的函数m_temp.GetBits()时,我在那里得到NULL指针。 (I可以看到m_temp保持正确的高度,宽度,位/像素数据valiues但图像数据缓冲器指针为NULL)

即使是功能类似于

BITMAP bitmap; 
GetObject(hBmpFileBitmap, sizeof(BITMAP), &bitmap); 
BYTE *pucInputImage = (BYTE*) bitmap.bmBits; -> Returns NULL 

或者

BYTE* pucImage = NULL; 
GetBitmapBits(hBmpFileBitmap,nWidth*nHeight*4,(LPVOID)pucImage); 

也在变量pucImage中返回NULL。这是工作的唯一的事情是

pBuf=malloc(bmpInfo.bmiHeader.biSizeImage) 
GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf,&bmpInfo,DIB_RGB_COLORS); 

在这里,我们需要通过PBUF变量(与图像的大小预分配)和复制的GetDIBits从数据bitmpa处理到这个PBUF缓冲区。这需要额外15毫秒。

据我所知,在bitblt操作过程中发生数据传输,我觉得我应该能够避免这种额外的数据传输,避免每帧15ms的延迟。

我想到的另一件事是因为桌面窗口需要被用户写保护,并且HDC hBmpFileDC是从DesktopDC派生的,它可能会继承原始DC的写保护属性。如果是这样的话,是有一些方法来这里纪念这个写保护关闭新创建的变量(如下图所示)

HDC   hBmpFileDC=CreateCompatibleDC(hDesktopDC); 

    HBITMAP  hBmpFileBitmap=CreateCompatibleBitmap(hDesktopDC,nWidth,nHeight); 

回答

0

同样的问题,但在VB语言。我认为问题在于我们在内存对象中创建了一个独立于设备的设备,但源代码是DDB(依赖于设备的位图),由于桌面位图托管在VRAM中,因此它必须具有VRAM指针而非RAM,所以这种方式的功能像GetObject和其他人返回null pointer。所有其他的东西,如.bmwidth,.bmheight,.bmtype,是OK。我非常沮丧,因为我需要将图像作为压缩+传输的流处理。