ファイルを開く度に、背景を一旦リセット(消去)するには

[戻る]
湿布薬 2008/10/22(水) 20:38:52
環境:VC8  MFC(SDI) Win XP

お世話になります。
MFCドキュメント、ビューアーキテクチャーについて、教えて頂きたく思います
BOOL CxxxDoc::OnOpenDocument(LPCTSTR lpszPathName)から、ファイルを開き
データを読込み、加工して
CDocument::UpdateAllViews(NULL)で
ビュー画面へ表示へ表示はできるのですが、その後
異なるファイルを開いたとき、そのタイミングで、一旦それまでの、ビュー画像は
消去して(画面を単色で塗りつぶし)、新たに読込んだファイルを
表示したいのですが、どうも、うまくいきません

背景画面を消去するのに
afx_msg BOOL OnEraseBkgnd(CDC* pDC);

BOOL CxxxView::OnEraseBkgnd(CDC* pDC)
{
    CRect rc;
    GetClientRect(&rc);
    pDC->FillSolidRect(&rc, RGB(0,0,0));
    return TRUE;
}
と、追加し、これ自体は問題は無いのですが、呼び出すタイミングが、よくわかりません
void CxxxView::OnInitialUpdate()
{
    // CScrollView::OnInitialUpdate();
    CDC* pDC = this->GetDC();
    OnEraseBkgnd(pDC);

    CSize sizeTotal;
    // TODO: このビューのサイズの合計を計算します。
    sizeTotal.cx = sizeTotal.cy = 2000;
    SetScrollSizes(MM_TEXT, sizeTotal);
}
このように、OnInitialUpdate()メッソッド内で呼ぶと、新規作成ボタンを、
押下した場合は、機能するのですが、ファイルを開く場面では、機能しません。
また、OnUpdateFileOpenイベントハンドラーを追加して、そのメッソッド内に、
CDC* pDC = this->GetDC();
OnEraseBkgnd(pDC);
を記述すると、ファイルを読込み、ビュー画面へ表示させるよう、実装しても
何も表示できません。

CxxxView::OnDraw()で呼んでも、スクロールビューなので、表示がおかしくなってしまい
ます。

どのタイミングで、呼び出したらいいか、ご教示願います。

wclrp ( 'o') 2008/10/23(木) 07:27:39
MSDNによると
CDocument::UpdateAllViewsでCView::OnUpdateが呼ばれると書いてあるけど。
俺はドキュメントビューを使わないので知らない。

念のため
直接OnDraw();などはコールしてはいけないよ。
CWnd::InvalidateRectなどを使えば、後でOnDraw();が呼ばれる。

KJ 2008/10/23(木) 22:50:24
MFCは最近触ってませんが・・・

wclrp ( 'o')さんの指摘にあるように、OnDraw()やOnEraseBkgnd()は直接コールしてはダ
メです。
これ -> OnEraseBkgnd(pDC);

一般的な方法として、
1. OnOpenDocumentでファイルを読み込んだ後、InvalidateRect()を実行
2. OnEraseBkgnd, OnDrawが順番に実行されます。

#スクロールビューってpDCの原点が自動的に調整されてるはずでは?

湿布薬 2008/10/24(金) 20:55:07
wclrp ( 'o')さん、KJさんお世話になります。
OnDrawやOnEraseBkgndを、直接実行するのは、セオリー違反ということですね。
ご教授ありがとうございます。さて、
OnOpenDocument()メッソッド内でファイルを読んだ後、下記の通りInvalidateRectを
実行するのですが
OnEraseBkgndを、呼んでくれないようです、間違いがあれば、ご指摘お願いします。

BOOL CxxxDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
    if (!CDocument::OnOpenDocument(lpszPathName))
        return FALSE;

    // TODO:  ここに特定な作成コードを追加してください。

    if( m_curFcdata.ReadStream(lpszPathName) ) {    // ファイル読込み
        InvalidateRect(NULL, NULL, TRUE);
        //UpdateWindow(FALSE);
        CDocument::UpdateAllViews(NULL);
        return TRUE;
    }
    return FALSE;
}

wclrp ( 'o') 2008/10/25(土) 01:43:33
CxxxDocからInvalidateRect呼ぶと
CxxxDoc::InvalidateRectは無いので
::InvalidateRectを呼ぶわけだ。

そして::InvalidateRect(NULL,だから
どのウィンドウに対してInvalidateRectを行うか指定がないから失敗。

描画させたいウィンドウに対してInvalidateRectを行わないと意味ない。

CxxxDoc::UpdateAllViewsで
CxxxView::OnUpdateって呼ばれない?

当然CxxxView::OnUpdateが存在しないと呼ばれるわけないけど
その辺はよく知らない。

湿布薬 2008/10/26(日) 16:38:15
[[解決]]
wclrp ( 'o')さん、いつもお世話になります。
Visual C++ 2005 シニア編という本に、ドキュメントとビューの詳しい、解説が掲載さ
れていました。
今回の場合ですと
void CFCView::OnInitialUpdate()
{
    CSize sizeTotal;
    // TODO: このビューのサイズの合計を計算します。
    sizeTotal.cx = sizeTotal.cy = 2000;
    SetScrollSizes(MM_TEXT, sizeTotal);
    OnUpdate(NULL, 0, NULL);    // これを追加
}
OnUpdate(NULL, 0, NULL);このように追加することで、
ファイルを開く度に、画像を消去し、新規画像を描画できました、ありがとうございました。

a 2008/10/26(日) 23:45:39
OnUpdate(NULL, 0, NULL);を追加するのではなく...

その箇所に基本クラスの
CScrollView::OnInitialUpdate();
を復活させるだけの話でわ?

CScrollView::OnInitialUpdate()はその中でOnUpdate()も
呼び出してくれるはず。
↑
MSDNのCView::OnUpdate()の解説に、
「OnInitialUpdate の既定の実装でも呼び出されます。」
とあります。
http://msdn.microsoft.com/ja-jp/library/w1z3te7e(VS.80).aspx

当初は ScrollView::OnInitialUpdate() があったはずだけど、
なぜか削除してしまっていますね。
特に明確な理由があって削除したのでなければ、
それを復活させるほうが妥当かと。

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