1

ウィンドウにビットマップ (バイト配列として格納) を描画しようとしています。

一般的な手順は次のとおりです。

OnPaint() ハンドラーでデバイス コンテキストを取得します。

CPaintDC dc(this);

そこから互換性のあるデバイス コンテキストを作成し、

CDC pMemDC->CreateCompatibleDC(&dc);

クライアント領域のサイズの互換ビットマップを作成します ( GetClientRect(&WinRect))。

CBitmap pNewBitmap->CreateCompatibleBitmap(&dc, WinRect.Width(), WinRect.Height());

ここで、ウィンドウ クライアントのサイズがビットマップとまったく同じサイズである場合はpNewBitmap->SetBitmapBits、配列をビットマップに "フィード" するために を呼び出すだけです。

これに aBitBltを続けると、ウィンドウにビットマップが表示されます。

dc->BitBlt(0, 0, WinRect.Width(), WinRect.Height(), pMemDC, 0, 0, SRCCOPY);

ウィンドウ サイズを画像サイズとは無関係に変化させたい場合は、最初pNewBitmapに適切なサイズ (クライアントの四角形) であることを確認する必要がありますが、配列をビットマップに単純に押し込むことはできません。

この状況では、上記の手順を繰り返して画像の正確なサイズのビットマップを作成することで解決策を見つけたので、ビットをその中に「押し込む」ことができBitBltます。BitBlt窓に向かった。

これを行う別の方法はありますか?実際のコードは次のとおりです。

void CAnimateWnd::OnPaint() 
{
    CPaintDC dc(this); // device context for painting

    DrawScene(&dc);

    // Do not call CWnd::OnPaint() for painting messages
}

void CAnimateWnd::DrawScene(CDC *pDrawDC)
{
    CRect WinRect;
    GetClientRect(&WinRect);

    if (pNewBitmap == NULL)
    {
        pMemDC = new CDC();
        pMemDC->CreateCompatibleDC(pDrawDC);
        pNewBitmap = new CBitmap();
        pNewBitmap->CreateCompatibleBitmap(pDrawDC, WinRect.Width(), WinRect.Height());
        pMemDC->SelectObject(pNewBitmap);
    }

    CRect BMPRect;
    GetBitmapDrawSize(&BMPRect);
    if (BMPRect != NULL)
    {
        if (!(BMPRect.Width() >= WinRect.Width() && BMPRect.Height() >= WinRect.Height()))
        {
            //The bitmap is smaller than the window, so fill the window with the background color.
            CBrush BackBrush(BackGndColor);
            CPen BackPen(PS_SOLID, 1, BackGndColor);
            pMemDC->SelectObject(&BackBrush);
            pMemDC->SelectObject(&BackPen);
            pMemDC->Rectangle(&WinRect);
            BackBrush.DeleteObject();
            BackPen.DeleteObject();
        }
    }

    OverrideAndDrawInHere(pMemDC, resize);
    pDrawDC->BitBlt(0,0,WinRect.right,WinRect.bottom,pMemDC,0,0,SRCCOPY);
}

template <class T>
void ImageWindow<T>::OverrideAndDrawInHere(CDC *pDC, int resize)
{
    if (this->sourceImage == NULL) return;

    CRect clientRect;
    GetClientRect(&clientRect);

    if (this->dispBMP == NULL)
    {
        this->dispDC = new CDC();
        this->dispDC->CreateCompatibleDC(pDC);
        this->dispBMP = new CBitmap();
        this->dispBMP->CreateCompatibleBitmap(pDC, this->sourceImage->GetWidth(), this->sourceImage->GetHeight());
        this->dispDC->SelectObject(this->dispBMP);
    }

    this->dispBMP->SetBitmapBits(this->sourceImage->GetArea() * 4, this->translatedImage);
    pDC->BitBlt(0, 0, this->sourceImage->GetWidth(), this->sourceImage->GetHeight(), this->dispDC, 0, 0, SRCCOPY);
}
4

1 に答える 1

0

ソース イメージと同じサイズではないウィンドウにビットマップをペイントする場合は、BitBlt を使用する代わりにStretchBltを試してください。

MSDN から:

ビットマップをコピー元の四角形からコピー先の四角形にコピーし、必要に応じてビットマップを拡大または圧縮してコピー先の四角形のサイズに合わせます。

示したのと同じ結果が必要な場合は、おそらく最善の方法で行っていることになります。FillRect のようなものを使用して Frame に直接描画 (または OnEraseBkgnd を処理) し、元のサイズの画像を BitBlt することもできますが、おそらくちらつきが発生する可能性があります。

于 2014-06-16T09:20:29.467 に答える