ファイルを開く度に、背景を一旦リセット(消去)するには – プログラミング – Home

ファイルを開く度に、背景を一旦リセット...
 
通知
すべてクリア

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


湿布薬
 湿布薬
(@湿布薬)
ゲスト
結合: 16年前
投稿: 9
Topic starter  

環境: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')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

MSDNによると
CDocument::UpdateAllViewsでCView::OnUpdateが呼ばれると書いてあるけど。
俺はドキュメントビューを使わないので知らない。

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


返信引用
KJ
 KJ
(@KJ)
ゲスト
結合: 21年前
投稿: 52
 

MFCは最近触ってませんが・・・

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

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

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


返信引用
湿布薬
 湿布薬
(@湿布薬)
ゲスト
結合: 16年前
投稿: 9
Topic starter  

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')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

CxxxDocからInvalidateRect呼ぶと
CxxxDoc::InvalidateRectは無いので
::InvalidateRectを呼ぶわけだ。

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

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

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

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


返信引用
湿布薬
 湿布薬
(@湿布薬)
ゲスト
結合: 16年前
投稿: 9
Topic starter  

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
 a
(@a)
ゲスト
結合: 23年前
投稿: 59
 

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() があったはずだけど、
なぜか削除してしまっていますね。
特に明確な理由があって削除したのでなければ、
それを復活させるほうが妥当かと。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました