3

C ++で記述されたリストビューコントロール(レポートモード)を備えたプレーンなWin32ダイアログについて考えてみます。特定のイベントが発生すると、すべてのアイテムとすべての列が削除され、新しい列とアイテムが作成されます。基本的に、コンテンツが変更されると、コンテンツに基づいて列が自動的に生成されます。

古いアイテム/列が削除され、新しいアイテム/列が追加されると、リストビューが地獄のようにちらつきます。私は試してみましたが、視覚的な体験に変更はありませんWM_SETREDRAWLockWindowUpdate()

私は拡張リストビュースタイルLVS_EX_DOUBLEBUFFERを設定しましたが、それはまったく役に立ちませんでした。

親ダイアログがWS_CLIPCHILDREN設定されました。

ちらつきをできるだけ少なくしてこれを機能させる方法について何か提案はありますか?私は2つのリストビューを使用することを考えています。可視性を交互に使用し、非表示のリストビューをバックバッファーとして使用しますが、これはやり過ぎのように聞こえます。簡単な方法があるはずです。

4

2 に答える 2

7

デフォルトのリストコントロールの描画にはかなり欠陥があります。ただし、独自のダブルバッファリング手法を実装するための簡単なトリックがあります。

CMyListCtrl::OnPaint()
{
    CRect rcClient;
    GetClientRect(rcClient);

    CPaintDC dc(this);
    CDC dcMem;
    dcMem.CreateCompatibleDC(&dc);

    CBitmap bmMem;
    bmMem.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
    CBitmap* pbmOld = dcMem.SelectObject(&bmMem);

    dcMem.FillSolidRect(rcClient, ::GetSysColor(COLOR_WINDOW));

    this->DefWindowProc(WM_PAINT, (WPARAM)dcMem.m_hDC, (LPARAM)0);

    dc.BitBlt(0,0,rcClient.Width(), rcClient.Height(), &dcMem, 0, 0, SRCCOPY);
    dcMem.SelectObject(pbmOld);

    CHeaderCtrl*    pCtrl = this->GetHeaderCtrl();
    if (::IsWindow(pCtrl->GetSafeHWnd())
    {
        CRect   aHeaderRect;
        pCtrl->GetClientRect(&aHeaderRect);
        pCtrl->RedrawWindow(&aHeaderRect);
    }
}

これにより、ビットマップが作成され、デフォルトのウィンドウプロシージャが呼び出されて、リストコントロールがビットマップにペイントされ、ビットマップのコンテンツがペイントDCにブリットされます。

WM_ERASEBKGNDのハンドラーも追加する必要があります。

BOOL CMyListCtrl::OnEraseBkgnd(CDC* pDC)
{
    return TRUE;
}

これにより、コントロールが再描画の前に常に背景を消去するのを停止します。ビットマップのメンバー変数を追加し、ウィンドウのサイズが変更された場合にのみ(再)作成すると、OnPaintをさらに最適化できます(ウィンドウのサイズによっては、常にビットマップの作成にコストがかかる可能性があるため)。

これはかなりうまくいくはずです。

于 2010-06-30T14:33:48.287 に答える
1

多くのこと、そして何よりもhumbagumba提案を試した後、私は非常に単純な結論に達しました。LockWindowUpdateこのような状況でみんなの友達です。どうして初めてうまくいかなかったのかわかりませんが、カスタムペイントがすべての状況でうまくいかなかった後、LockWindowUpdateもう一度試してみましたが、うまくいきました!

基本的に、リストビューのすべての作業をaでラップするだけでLockWindowUpdate(hWnd)LockWindowUpdate(NULL)物事は美しく機能します。スクロールバーのちらつきすらありません。

LockWindowUpdate一度にロックできるウィンドウは1つだけなので、ネストしないように注意してください。

于 2010-06-30T16:10:07.197 に答える