スクロール時の描画方法

[戻る]
さおり 2002/07/22(月) 20:11:16
こんばんは。さおりと申します。
いつもお世話になっております。

CScrollViewを使って画像をスクロールする際のことで質問です。
環境は、WinMe

さおり 2002/07/22(月) 20:16:53
すみません、途中で送信してしまいました。

CScrollViewを使って画像をスクロールする際のことで質問です。
環境は、WinMe VC++ MFCです。

ScrollViewのOnDrawで画像をScrollViewに貼り付けているのですが
スクロールさせた際に、なめらかなスクロールになりません。

ペイントなどでスクロールさせるとぜんぜんなめらかに
スクロールするようです。

不必要な部分まで描画させているために処理が遅くなっているのが
原因と思っていますが、ただしいでしょうか?

もし正しいとしたら、どのような処理をしたらよいのでしょうか?
ご教授願います。

dairygoods 2002/07/23(火) 11:49:50
> 不必要な部分まで描画させているために処理が遅くなっているのが
> 原因と思っていますが、ただしいでしょうか?

CDC::GetClipBox()で書き換えるべき領域が取得できます。
その部分だけ描画するようにしてみると良いかもしれません。

匿名希望 2002/07/23(火) 12:41:35
こんにちは、さおりです。
DairyGoodsさんレスありがとうございます。
GetClipBox()使ってみました。下のようなコードになったのですが、
結論としては、前と変わらなかったです。
//でコメント合うとしている部分はGetClipBox()を使う前のところです。
GetClipBox()の使い方が悪いのでしょうか?
それとも、OnDrawではなく、スクロールボタンが押されたところで
何らかの処理をするべきなのでしょうか?

void CGraphView::OnDraw(CDC* pDC)
{
    CDocument* pDoc = GetDocument();
    RECT rect;
    pDC->GetClipBox(&rect);
    CBitmap myBMP;
    myBMP.LoadBitmap(IDB_BITMAP1);
    CDC myDC;
    myDC.CreateCompatibleDC(pDC);
    CBitmap *oldBMP = myDC.SelectObject(&myBMP);
    pDC->BitBlt(rect.left,rect.top,rect.right, rect.bottom,&myDC, 
rect.left, rect.top, SRCCOPY);
//    pDC->BitBlt(0, 0, 1024, 768, &myDC, 0, 0, SRCCOPY);
    myDC.SelectObject(oldBMP);
    
    // TODO: この位置に描画用のコードを追加してください
}

dairygoods 2002/07/23(火) 13:22:08
BitBltの第3,4引数は幅と高さですよ。

あと、ビットマップは毎回ロードせず
何処かの初期化処理で読み込んでおきましょう。

メモリDCを作る処理はそんなに重くないと思いますが、
これも初期化時にあらかじめ作っておくと良いでしょう。

さおり 2002/07/24(水) 12:42:00
こんにちは。さおりです。
dairygoodsさんのおっしゃる通りビットマップのロードと
メモリDCの作製を1回しか行わない様にしました。
InitialUpDateの所でビットマップを読み込んで、
メモリDCの作製は下の通りに行ないました。
(InitialUpdateのなかで、pDCを持ってくる方法がわからなかった)

結果、スクロールは前に比べるとスムーズに動くようになりました。
しかし、同じ画像をペイントなどでスクロールさせた場合と比べると
まだ、白いちらちらがでます。(特に左右に動かした場合)
依然として余計な作業が入っているのでしょうか?

何回も申し訳ないですが教えて下さい。

void CGraphView::OnDraw(CDC* pDC)
{
    static int i = 0;
    if (i == 0){
        myDC.CreateCompatibleDC(pDC);    
        i = 1;}

    RECT rect;
    pDC->GetClipBox(&rect);

    CBitmap *oldBMP = myDC.SelectObject(&myBMP);

    pDC->BitBlt(rect.left, rect.top, 
        rect.right - rect.left, rect.bottom - rect.top,
        &myDC, rect.left, rect.top, SRCCOPY);

    myDC.SelectObject(oldBMP);
}

dairygoods 2002/07/24(水) 13:56:53
OnEraseBkgnd()は記述していますか?

もし、画像をビュー全体に描画しているのでしたら、
OnEraseBkgnd()では、何もする必要はありません。
(return TRUE)

一部分でも背景が見えるのでしたら、
背景が見える部分だけを塗りつぶすようにしてください。


>(InitialUpdateのなかで、pDCを持ってくる方法がわからなかった)

CClientDC dc(this);
mDC.CreateCompatibleDC(&dc);

古いスレッドには追加発言できません。