2017-06-19 1 views
0

私は今日遭遇した非常に奇妙な問題です。 MFCプロジェクトでVC6で以下のコードを実行すると黒い画面になりますが、これは完全に動作し、コメントを取るとデスクトップの画像が表示されます。しかし、これらのコードは無限ループで実行されるので、私はメモリコピーを減らそうとし、メモリはBitBltCreateCompatibleBitmapなどのように使います。私のプログラムはこれらのコメント付きコードとどう関係しているのか分かりません。問題の原因とその理由は誰でも知ることができます。GetDIBitsとデバイスコンテキストに関する奇妙なエラー

HDC hdcDesktop = ::CreateDC("DISPLAY", NULL, NULL, NULL); 
RECT desktopRect; 
::GetWindowRect(::GetDesktopWindow(), &desktopRect); 
int desktopWidth = desktopRect.right - desktopRect.left; 
int desktopHeight = desktopRect.bottom - desktopRect.top; 

HBITMAP hBitmap = CreateCompatibleBitmap(hdcDesktop, desktopWidth, desktopHeight); 
/* 
HDC hdcMemory = CreateCompatibleDC(hdcDesktop); 
SelectObject(hdcMemory, hBitmap); 
BitBlt(hdcMemory, 0, 0, desktopWidth, desktopHeight, hdcDesktop, 0, 0, SRCCOPY); 
*/ 

BITMAPINFO bitmapInfo = {0}; 
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 

GetDIBits(hdcDesktop, hBitmap, 0, 0, NULL, &bitmapInfo, DIB_RGB_COLORS); 
BYTE *pData = new BYTE[bitmapInfo.bmiHeader.biSizeImage]; 
memset(pData, 0, bitmapInfo.bmiHeader.biSizeImage); 
GetDIBits(hdcDesktop, hBitmap, 0, bitmapInfo.bmiHeader.biHeight, pData, &bitmapInfo, DIB_RGB_COLORS); 

CRect destRect; 
GetClientRect(&destRect); 
StretchDIBits(::GetDC(m_hWnd), 0, 0, destRect.Width(), destRect.Height(), 0, 0, bitmapInfo.bmiHeader.biWidth, bitmapInfo.bmiHeader.biHeight, 
    pData, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY); 
+0

スタックオーバーフローは、あなたの**コードについて説明するための助けを求める場所ではありません。あなたのコードが何をしているかを知っておく必要があります。真剣に、VC6?あなたがパフォーマンスを気にするなら、この千年紀に書かれたものにアップグレードしてください。 – IInspectable

+0

私は多くのプロジェクトがまだVC6で動作していますが、安定していて、良いです...私は全く同意していますが、これは古いコンパイラですが、信頼できます...からのコードはVC6でもうまくいくはずです。 – flaviu2

+0

@flaviu2:VC6は現在サポートされているバージョンのWindows **(つまり、Windows Vistaのアップ)をサポートしていません。あなたのターゲットをサポートしていないツールの使用について信頼できるものはありません。加えて、実際にVC6のC++バージョンをまだ理解している開発者のグループは、ごくわずかです。 – IInspectable

答えて

0

セクションをコメントアウトすると動作しない理由はここにあなたが、DIBSectionを作成することにより、アプリのグローバルスコープでその関連BITMAPINFOとpDataをバッファをあなたのコードを最適化することができます...

HBITMAP hBitmap = CreateCompatibleBitmap(hdcDesktop, desktopWidth, desktopHeight); 

HDC hdcMemory = CreateCompatibleDC(hdcDesktop); 
SelectObject(hdcMemory, hBitmap); 

// BitBlt makes a copy of the desktop here. 
BitBlt(hdcMemory, 0, 0, desktopWidth, desktopHeight, hdcDesktop, 0, 0, SRCCOPY); 

BITMAPINFO bitmapInfo = {0}; 
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 

// the following lines make use of the contents of bitmap in hBitmap 
// commenting out the BitBlt would mean the bitmap is uninitialized. 
// 
GetDIBits(hdcDesktop, hBitmap, 0, 0, NULL, &bitmapInfo, DIB_RGB_COLORS); 
BYTE *pData = new BYTE[bitmapInfo.bmiHeader.biSizeImage]; 
memset(pData, 0, bitmapInfo.bmiHeader.biSizeImage); // <-- this is unnecessary. 

GetDIBits(hdcDesktop, hBitmap, 0, bitmapInfo.bmiHeader.biHeight, pData, &bitmapInfo, DIB_RGB_COLORS); 

です。そのディメンションはかなり長い間有効です... WM_DISPLAYCHANGEメッセージ(https://msdn.microsoft.com/en-us/library/windows/desktop/dd145210(v=vs.85).aspx)を処理することで、画面解像度の変更を監視する必要があります。

これにより、CreateCompatibleBitmap()を繰り返し呼び出す手間が省けます。

BitBlt()とGetDIBits()を使用してデスクトップビットを取得するための回避策はありません。