2

レポート ビューで MFC リスト コントロールを使用し、グリッド線を使用して、漠然としたスプレッドシート形式でデータを表示します。

ユーザーがコントロールを垂直方向にスクロールすると、余分なグリッド線が描画され、見栄えが悪くなります。

これは、スライダーまたはマウスホイールをスクロールに使用した場合には発生せず、スクロール コントロールの下部にある小さな下矢印ボタンを使用した場合にのみ発生します。

これは、リスト コントロール ウィンドウのサイズが正確な偶数行ではなく、行の一部が下部に表示される場合に発生するようです。

部分的な行が表示されないようにリスト コントロールのサイズを調整すると、問題は解決します。ただし、プログラムが別のコンピューターで実行されると、おそらく行が占めるピクセル数が変化するため、表示されます。

画面解像度、フォントサイズ、「ダイアログユニット」の間の相互作用であると想定しています。

コントロールの作成時に、コントロールのサイズをプログラムで強制する必要があると思います。しかし、どのサイズですか?

ApproximateViewRect() メソッドを使用してみましたが、動作しません。おそらく、このメソッドはレポート ビューを認識していないのでしょうか?

もう 1 つの方法は、CListCtrl の独自の特殊化を作成し、スクロールを行っているメソッドをオーバーライドすることだと思います。これは大変な作業になりそうです。

このスクリーンショットは、グリッド線が失われる密接に関連する問題を示しています

代替テキスト

これは余分なグリッド線のあるものです

代替テキスト

これら 2 つと、完全にスクロールするものとの唯一の違いは、コントロールの垂直方向のサイズが数ピクセル異なることです。

4

4 に答える 4

6

これは実際には「スムーズ スクロール」に関連するバグです。回避策は次のとおりです。

void CMyListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    __super::OnVScroll(nSBCode, nPos, pScrollBar);
    Invalidate();
    UpdateWindow();
}
于 2008-10-08T17:34:55.340 に答える
1

これは、ListView (MFC だけでなく、一般的な共通コントロール) 自体のバグであることを思い出します。これについて簡単にグーグルで検索すると、多くの人が同じ結論に達しているようです。Windows エクスプローラーにはグリッド線がないため、これを修正する必要はないと思いますか? 90年代後半のことを思い出しました。

トリックは、スクロール後にウィンドウを無効にすることだと思います-おそらくVSCROLLメッセージに応答してですか?推測です。

于 2008-10-08T17:14:43.307 に答える
0

これはストック リスト ビューで発生していますか、それともカスタム ドローですか? 標準の Windows コントロールで再描画の問題を見たことはありません。

問題を説明するためにスクリーンショットを投稿できますか? コントロールのサイズを正確に変更するのではなく、再描画の問題を修正したいと思いますか?

于 2008-10-08T14:46:12.420 に答える
-1

MFC リスト コントロールでこのバグを修正するには、コントロールを特殊化し、スクロールに応答するメソッドをオーバーライドし、スクロール後にリストを完全に再描画するように強制する必要があります。

インターフェイス ヘッダー

class cSmoothListControl : public CListCtrl
{
public:
    DECLARE_MESSAGE_MAP()
    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
};

実装:

BEGIN_MESSAGE_MAP(cSmoothListControl, CListCtrl)
ON_WM_VSCROLL()
END_MESSAGE_MAP()

void cSmoothListControl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    // call base class method to do scroll
    CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);

    // force redraw to cover any mess that may be created
    Invalidate();
    UpdateWindow();
}
于 2008-10-08T18:58:08.497 に答える