2012-11-05 43 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。我非常沮喪,因爲我需要將圖像作爲壓縮+傳輸的流處理。