MFCドキュメント/ビューアーキテクチャ、GDI描画/印刷。私は表示して印刷する必要があるDIBバックバッファを持っています。GDI(MFC)でDIB印刷を実装できません
私は、CreateDIBSection(CreateCompatibleBitmapで作成されたDDBではなく)で作成されたDIBを使用する必要があると判断し、StretchBltではなくStretchDIBitsでプリンタdcにblitする必要があります。
しかし、私はこのことを動作させることができません。ここで
は、私が何をすべきかです:私の初期化ルーチンで
、Iセットアップバックバッファ、次のように:アンダースコアで
// Prepare device context:
CClientDC aDC(this);
OnPrepareDC(&aDC);
// Setup proper backbuffer:
_pMemDc = new CDC;
_pMemDc->CreateCompatibleDC(&aDC);
memset(&_bitmapInfo, 0, sizeof(BITMAPINFO));
_bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
_bitmapInfo.bmiHeader.biWidth = _sizeBackBuffer.cx;
_bitmapInfo.bmiHeader.biHeight = -_sizeBackBuffer.cy; // top-down
_bitmapInfo.bmiHeader.biPlanes = 1;
_bitmapInfo.bmiHeader.biBitCount = 24; // Maybe 32?
_bitmapInfo.bmiHeader.biCompression = BI_RGB;
HANDLE hMemBitmap = CreateDIBSection(aDC.GetSafeHdc(), &_bitmapInfo, DIB_RGB_COLORS, (void**)&_pBitmapRawBits, 0, 0);
_hOldSelBitmap = (HBITMAP)_pMemDc->SelectObject(hMemBitmap);
変数(プライベート)のメンバー変数であり、このように宣言:
ファー:今すぐ下記
CDC *_pMemDc; // Backbuffer memory dc
HBITMAP _hOldSelBitmap;
BITMAPINFO _bitmapInfo; // Backbuffer DIB (header-only)
unsigned char *_pBitmapRawBits; // Pointer to pixel data of DIB
SIZE _sizeBackBuffer; // Size of backbuffer, i.e. size of that DIB
は、私は私のOnDrawオーバーライドで何をすべきかですstly私はエリアが、この(簡体字コード)のように描かれることを得る:
CRect rectClipBoxPlayground;
if (pDC->IsPrinting())
{
rectClipBoxPlayground = _printingParams.pPrintInfo->m_rectDraw;
}
else
{
pDC->GetClipBox(&rectClipBoxPlayground);
}
その後、私は通常、DCよりも(かなり)大きい私のバックバッファ内の対応するRECT座標を計算します。この計算の詳細は、私はちょうど
CRect rectClipBoxBackBuffer;
は(バックバッファのピクセル座標における)バックバッファの対応する四角形を表すと言う、ここでは無関係です。
次に、_pMemDcメモリdcを使用してバックバッファに描画します。
最後に、私は問題を抱えている部分があります。ターゲットDc(スクリーンまたはプリンタ)にDIBをブリッティングします。ここでは、私が何をすべきかです:
// Copy back buffer to screen/printer dc:
pDC->SetStretchBltMode(HALFTONE);
SetBrushOrgEx(pDC->GetSafeHdc(), 0, 0, 0);
// BELOW COMMENTED CODE OF StretchBlt WORKS(!) INSTEAD OF StretchDIBits.
//
//BOOL bSuccess = pDC->StretchBlt(rectClipBoxPlayground.left, rectClipBoxPlayground.top,
// rectClipBoxPlayground.Width(), rectClipBoxPlayground.Height(),
// _pMemDc, rectClipBoxBackBuffer.left, rectClipBoxBackBuffer.top,
// rectClipBoxBackBuffer.Width(), rectClipBoxBackBuffer.Height(), SRCCOPY);
HBITMAP hMemBitmap = (HBITMAP)_pMemDc->SelectObject(_hOldSelBitmap);
DWORD dwLines = StretchDIBits(pDC->GetSafeHdc(),
rectClipBoxPlayground.left, rectClipBoxPlayground.top, rectClipBoxPlayground.Width(), rectClipBoxPlayground.Height(),
rectClipBoxBackBuffer.left, rectClipBoxBackBuffer.top, rectClipBoxBackBuffer.Width(), rectClipBoxBackBuffer.Height(),
_pBitmapRawBits, &_bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
_pMemDc->SelectObject(hMemBitmap);
問題があり、StretchBltのコメントアウトされたコードは(一部のプリンタでの印刷を除く)完璧に動作しますが、一部のプリンタがそれとのトラブルを持っているので、私はそれを使用することはできません。だから私はStretchDIBitsを使用する必要があります。私はまず、DIBをそのメモリdcから一時的に選択解除して、それがdcに関連付けられていないことに注意してください。それから私はStretchDIBitsを使用しますが、物事はうまくいきません!私は間違った座標を与えるように、出力がうまくいきません。描画されるべき領域から領域が外れて描画されます。だから私は何かを逃しているに違いない(おそらく非常に些細なこと)。助けて!私はrectClipBoxBackBuffer.topとbitmapInfo.bmiHeader.biHeightの兆候を変更しようとしましたが、結果は変わりましたが、何もうまくいかないように動作します。
私は何が間違っていますか?
追加情報: 'StretchDIBits'呼び出しが成功しました。 DIB。私はその数がドキュメントごとに 'rectClipBoxBackBuffer.Height()'と等しくなることを期待しています。これは 'StretchDIBits'が"スキャンライン数**コピー** "を返すと言います。私はこれがどんなヒントかもしれないかどうかわかりません。 –
痛いほど痛いです。 '#include' –
残念ながらHans、GDI +は自分のやることには遅すぎます。 –