Invalidate
Invalidate
MFCのVC++6.0で開発しています。
ダイアログ内をリサイズしてコントロールなど再配置するというプログラムを作っています。
コントロールを移動させInvalidateで再描画する。
普段ならこれでいいのですがダイアログ内の一部コントロールにおいて再描画したくないものもあるので
全体を再描画するのはまずいです。部分的に排除した画面全体を再描画する方法か
1つのコントロールだけにおいて再描画する方法を教えて下さい。
ダイアログ内をリサイズしてコントロールなど再配置するというプログラムを作っています。
コントロールを移動させInvalidateで再描画する。
普段ならこれでいいのですがダイアログ内の一部コントロールにおいて再描画したくないものもあるので
全体を再描画するのはまずいです。部分的に排除した画面全体を再描画する方法か
1つのコントロールだけにおいて再描画する方法を教えて下さい。
Re:Invalidate
逆に質問で申し訳ないのですが、やりたい事は『再描画したくない』のですか?『表示したくない』のですか?
質問を読んでも、いまいち、やりたい事が伝わってこないものでして…ピンとこないんですよね。
質問を読んでも、いまいち、やりたい事が伝わってこないものでして…ピンとこないんですよね。
Re:Invalidate
ダイアログ上にリストビュー1個とボタン2個があってサイズに合わせてコントロール配置するのですが
画面全体を再描画してしまうとリストビューのところがちかちかするんですよね。
必要なのはボタン2個の再描画なんです。ダイアログ内のリストビュー以外の箇所の再描画か
もしくはボタンの移動した箇所の再描画がしたいです。
質問の答えとしてはリストビューの所の再描画をしたくない でしょうか
画面全体を再描画してしまうとリストビューのところがちかちかするんですよね。
必要なのはボタン2個の再描画なんです。ダイアログ内のリストビュー以外の箇所の再描画か
もしくはボタンの移動した箇所の再描画がしたいです。
質問の答えとしてはリストビューの所の再描画をしたくない でしょうか
Re:Invalidate
それもやったんですが私の考え方がおかしいのかもしれません。例えばOKボタンのメンバ変数をm_OKとします。
OnSize関数内で
SetWindowPosで移動させ
CRect rect;
m_OK.GetClientRect(&rect);//領域確保
InvalidateRect(&rect, TRUE);
としても全く変化がなくリサイズするとコマ送りようにOKボタンの残像が・・
どこがおかしいのでしょうか
OnSize関数内で
SetWindowPosで移動させ
CRect rect;
m_OK.GetClientRect(&rect);//領域確保
InvalidateRect(&rect, TRUE);
としても全く変化がなくリサイズするとコマ送りようにOKボタンの残像が・・
どこがおかしいのでしょうか
Re:Invalidate
それでは…
CRect rect;
m_OK.GetClientRect(&rect);
/* この位置でrectの中身を書き換えて座標を移動させる*/
m_OK.MoveWindow(&rect, TRUE);
これではどうでしょうか?
CButtonクラスのMoveWindow関数を使用して移動させ、第2引数をTRUEにする事で、m_OKを再描画させています。
CRect rect;
m_OK.GetClientRect(&rect);
/* この位置でrectの中身を書き換えて座標を移動させる*/
m_OK.MoveWindow(&rect, TRUE);
これではどうでしょうか?
CButtonクラスのMoveWindow関数を使用して移動させ、第2引数をTRUEにする事で、m_OKを再描画させています。
Re:Invalidate
書き忘れてしまいました・・
MoveWindowは使わないように言われています。
MoveWindowでのやり方はできているんですが用意している関数の方を使うよういわれています
MoveWindowは使わないように言われています。
MoveWindowでのやり方はできているんですが用意している関数の方を使うよういわれています
Re:Invalidate
あ、それから追記ですが…
残像が残るのは移動させた後の領域を再描画しているからでしょう。
「移動させる前」と「移動させた後」の領域で重なっていない部分が再描画されずに残っているのが原因です。
ですから、研修生さんの方法でやりたいのならば、「移動させる前」と「移動させた後」の両方の領域を再描画させる必要があります。
>>m_OK.GetClientRect(&rect);//領域確保
>>InvalidateRect(&rect, TRUE);
それから、この書き方では、m_OKのクライアント領域を取得しているのに、そのまま親オブジェクト(今回の場合はダイアログクラスでしょうか?)のInvalidateRect関数の引数へ使用しています。これはマズイのではないでしょうか?
この方法でやりたいのならば…
CRect rect;
m_OK.GetClientRect(&rect); // OKボタンのクライアント座標を取得
m_OK.ClientToScreen(&rect); // クライアント座標をスクリーン座標に変換
this->ScreenToClient(&rect); // OKボタンのスクリーン座標をダイアログのクライアント座標へ変換
this->InvalidateRect(&rect); // 指定領域を再描画
こんな感じでしょうか?
残像が残るのは移動させた後の領域を再描画しているからでしょう。
「移動させる前」と「移動させた後」の領域で重なっていない部分が再描画されずに残っているのが原因です。
ですから、研修生さんの方法でやりたいのならば、「移動させる前」と「移動させた後」の両方の領域を再描画させる必要があります。
>>m_OK.GetClientRect(&rect);//領域確保
>>InvalidateRect(&rect, TRUE);
それから、この書き方では、m_OKのクライアント領域を取得しているのに、そのまま親オブジェクト(今回の場合はダイアログクラスでしょうか?)のInvalidateRect関数の引数へ使用しています。これはマズイのではないでしょうか?
この方法でやりたいのならば…
CRect rect;
m_OK.GetClientRect(&rect); // OKボタンのクライアント座標を取得
m_OK.ClientToScreen(&rect); // クライアント座標をスクリーン座標に変換
this->ScreenToClient(&rect); // OKボタンのスクリーン座標をダイアログのクライアント座標へ変換
this->InvalidateRect(&rect); // 指定領域を再描画
こんな感じでしょうか?
Re:Invalidate
MoveWindowが使えれば楽なんですが、事情があるなら仕方ないですね。
ちょっと、汚いソースになってしまいましたが…こんな感じかな?
同じ様な処理をいている個所を関数化すればスッキリするかもしれませんね。
// 移動前の座標を保持する
CRect rect1;
m_OK.GetWindowRect(&rect1); // OKボタンのスクリーン座標を取得
this->ScreenToClient(&rect1); // OKボタンのスクリーン座標をダイアログのクライアント座標へ変換
// 移動後の座標を保持する
CRect rect2;
/* ここで移動処理を行う */
m_OK.GetWindowRect(&rect2); // OKボタンのスクリーン座標を取得
this->ScreenToClient(&rect2); // OKボタンのスクリーン座標をダイアログのクライアント座標へ変換
// 再描画を行う
this->InvalidateRect(&rect1); // 移動前の領域を再描画する
this->InvalidateRect(&rect2); // 移動後の領域を再描画する
ちょっと、汚いソースになってしまいましたが…こんな感じかな?
同じ様な処理をいている個所を関数化すればスッキリするかもしれませんね。
// 移動前の座標を保持する
CRect rect1;
m_OK.GetWindowRect(&rect1); // OKボタンのスクリーン座標を取得
this->ScreenToClient(&rect1); // OKボタンのスクリーン座標をダイアログのクライアント座標へ変換
// 移動後の座標を保持する
CRect rect2;
/* ここで移動処理を行う */
m_OK.GetWindowRect(&rect2); // OKボタンのスクリーン座標を取得
this->ScreenToClient(&rect2); // OKボタンのスクリーン座標をダイアログのクライアント座標へ変換
// 再描画を行う
this->InvalidateRect(&rect1); // 移動前の領域を再描画する
this->InvalidateRect(&rect2); // 移動後の領域を再描画する