> ただ、なにぶん初心者で、点線の残像の消し方がわかりません。
> 塗りつぶしたり、いろいろ試したのです。
Invalidateでwindowの再描画ができます。
Invalidateは、windowの領域が再描画の必要があることを
OSに教えてあげる関数ですので、そのうちOnPaint等が呼ばれて再描画されます。
『そのうち』で問題なら、UpdateWindowです。
InvalidateRectも似ていますが、window全体でなく指定した領域のみが
再描画の対象になります。領域が限られている場合は、再描画の処理が
軽いですが、領域をプログラムが指定してやる必要があります。
※ 表示がちらつく場合は、『ダブルバッファリング』について調べてください。
たいちうさん、ありがとうございます。
座標を記憶しておき、InvalidateRectで処理を行うことにしました。
助かりました。ありがとうございます。
『ダブルバッファリング』ちょっと調べてみますね。(^_^
度々申し訳ありません。
少し問題がありまして、ご教授いただけないでしょうか。
コントロール選択時に隅に■を表示しているのですが、ダイアログの背景色が
黒色なので、周りを白で囲んだ■にて表示しておりました。
そこで、消去するときに背景色が黒なのを良いことに周りの白の部分を黒に塗りつぶし
てきえているようように描画してみせかけてました。
コントロールが単体の場合は、問題ないのですが、複数重なりあった場合に、
その黒い部分がコントロール上に描画されてしまいました。
このような場合、どう対応すべきなのでしょうか?
もともとの■部分を塗りつぶすのではなくて、消去したいのです。
申し訳ありませんが、ご教授ください。
ChildWindowFromPoint で、■の下の、コントローラのポインタを持ってきて、Invalidate
で、試してみてください。
いまさらかもしれないけど、コントローラを動的サブクラス化して、
移動の時は、
lParam = MAKELPARAM(point.x, point.y);
PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, lParam);
で、リサイズは
lParam = MAKELPARAM(point.x, point.y);
PostMessage(WM_NCLBUTTONDOWN, HTLEFT/*など*/, lParam);
で、いけるような気がします。
この方法なら、デフォルトで点線を書いてくれるので、描いたり消したりもいらないし、
マウス押下をオーバーライドしてやれば、コマンドメッセージも飛んでこないので、やりやすい
かな、とふと思ったりもします。
通りすがり改め、SundayProgramer
何度も質問になってしまいまして、申しわけありません。
『コントローラを動的サブクラス化』という方法がわかりません。
どのようにすればよいのでしょうか
下記内容でコールしているのですがアサーションが出てしまいます。
bRet = pdata->pWnd->SubclassDlgItem(pdata->nID,this);
pdata->nIDはCreateしたときのコントロールIDです。
> 『コントローラを動的サブクラス化』という方法がわかりません。
http://www.athomejp.com/goldfish/mfc/button/clrbutton.asp
この方法で、ボタンの見た目を自由に変えることができますので、
おそらくこれを指しているのではないかと。
あと、PATIOさんの『2007/02/15(木) 12:29:00』の投稿を
読み返してほしいのですが、とりあえず、デザインモードの
ことだけを考えてみてはどうでしょうか?
デザインモードのボタンは、クリックに応答する必要もなく、
ただ大きさや配置があるだけの絵で十分ではないですか?
デザインモードで作成した座標データを元に、
実行モードでコントロールを作成・配置するほうが良さそう。
この方針に従うならば、最終目標までの道筋は次のようなものかと。
1.ダイアログに複数の四角を書く。
2.そのうちの1つにフォーカスを持たせる。
(フォーカスを持った場合の表示と、フォーカスの移動方法が必要)
3.フォーカスを持つ四角をドラッグで移動
4.フォーカスを持つ四角の辺付近で、マウスカーソルを変更
5.マウスカーソルが変わっているときに、ドラッグで大きさ変更
6.四角の追加・削除等を実装
7.座標データを何らかの形で保存
これで機能的にはデザインモードが完成。
もっと作りこむ余地はいくらでもありますが。
8.座標データを元に、コントロールの作成・配置
実行モードが正常に実行できることの確認も大変そうだ。
# 以前も書きましたが、本当にやる必要がありますか?
# 私の力量だと2週間ほどの作業をイメージしてますが。
# 仕事でするならば、別の方法も検討すべきですが、
# 勉強のためならば全然OKです。
# 途中で挫折したとしても勉強になるでしょうが、
# できれば、デザインモードから実行モードまで、
# ちゃんと動くものを完成させてください。
# まずは、ボタン1つの大きさを変えるだけでも良いので。
たいちろうさん、お返事ありがとうございます。
各コントロールに構造体で座標や選択済みとかの情報を持たせて、
現状では下記までは完成しており
1.ダイアログに複数の四角を書く。
2.そのうちの1つにフォーカスを持たせる。
(フォーカスを持った場合の表示と、フォーカスの移動方法が必要)
3.フォーカスを持つ四角をドラッグで移動
4.フォーカスを持つ四角の辺付近で、マウスカーソルを変更
5.マウスカーソルが変わっているときに、ドラッグで大きさ変更
6.四角の追加・削除等を実装
7.座標データを何らかの形で保存
+
・複数選択された場合の移動、
・複数選択された場合にリサイズを許可しない
等はできるようになりました。簡単なデザインモードの動作はできているのですが、
後は、細かい描画で、コントロールが重なった場合に■が残ってしまったりする場合の
処理にてこずってます。
今後の予定としましては、てこずっている内容の修正。
また、複数選択時にコントロールに優先付けをして、■の外枠と□の外枠の
区別を行い、優先コントロールを元にした位置あわせ、リサイズを考えております。
つきまして、教えていただきたいのですが、VCというかwindowというか、説明しずらい
のですが、機能として、コントロールを押下した場合に■を描画でなくて、出す方法が
あるのでしょうか?
SundayProgramerさんの話では、サブクラス化することにより・・・・とあります。
実装上、■を描画せずに機能的に出す方法はあるのでしょうか。
申し訳ありません。ご教授ください。
> 各コントロールに構造体で座標や選択済みとかの情報を持たせて、
> 現状では下記までは完成しており
一応書きますが、私の書いた道筋はデザインモードでコントロールを
使わない場合です。
> SundayProgramerさんの話では、サブクラス化することにより・・・・とあります。
> 実装上、■を描画せずに機能的に出す方法はあるのでしょうか。
私は無いと思いますが、知らないだけかもしれません。
SundayProgramerさんの真意については私では判りません。
ご本人か、上級者のレスをお待ち下さい。
(投稿されたソースコード等から自明なのかもしれませんので)
おそらく、そのようなことができるという趣旨ではないと思います。
> 後は、細かい描画で、コントロールが重なった場合に■が残ってしまったりする場合の
> 処理にてこずってます。
消す処理が必要ないのではないのでしょうか?
フォーカスの移動などで、■が不要になったときは、そのコントロールの
フォーカスフラグをfalseにして、Dialogに対してInvalidate。
OnPaintでは以前の状態など気にせず、フラグが立っていれば■を描き、
立ってなければ何もしない。
もしInvalidateRectを使うならば、コントロールよりも一回り大きい領域を
指定してください。
回答ありがとうございます。
OnPaint内での処理で問題なくなりました。
今までOnPaintを作成してませんでした。
これで、複数の問題が解決しました。
本当に何度も申し訳ありません(>_<)
今回、エディット中のコントロールをツーリングバーより、右寄せや左寄せを
行いたいと思い、ツールバーを作成したのですが、コントロールが選択されるまで
ツールバーのボタンを押下できないようにしたいのですが、いつもアクティブな
状態のままで対応に困っています。ツールバーのボタンの制御は、どのように
行えばよいのでしょうか。
宜しく、ご教授ください。
ON_UPDATE_COMMAND_UI について調べてください。
たいちうさん、ありがとうございます。
なんとかツールバーの制御はできました。
ありがとうございます。
>bRet = pdata->pWnd->SubclassDlgItem(pdata->nID,this);
コントロールの動的サブクラス化はそんな感じですが、微妙に使い方が違います。やり方は、ま
ずダイアログクラスに、CButtonなどのメンバ変数を作って、(仮にm_Buttonとします。
m_Button は Create せず、宣言するだけです。)後は、必要な時に、
m_Button.SubclassDlgItem(pdata->nID,this);
とすると、m_Button を通して、ボタンとのやり取りができるようになります。
ClassWizerd の コントロールへのメンバ変数の割付を、手動でやるみたいな感じです。
前の書き込みで誤解を与えてしまったみたいなんですが、これを少し工夫すると、点線の描画等
は出来るんですが、■までは出来ません。
一応コードはこんな感じです。
// 編集用の自作クラス CWnd 継承にしておくと、ボタン以外でもサブクラス化できる。
class CEditedCtrl : public CWnd
{
…
};
// WM_NCHITTESTのハンドラ
UINT CEditedCtrl::OnNcHitTest(CPoint point)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォル
トの処理を呼び出してください
return HTCAPTION; // ウィンドウ領域全体をタイトルバー化
//return CWnd::OnNcHitTest(point);
}
class CXXDlg : public CDialog
{
…
CEditedCtrl m_EditedCtrl;
}
後は例の OnSetCursor の WM_MOUSEMOVE のタイミングでで、
if(m_EditedCtrl.GetSafeHwnd() != pWnd->GetSafeHwnd() && pWnd != this){
if(m_EditedCtrl.GetSafeHwnd() != NULL){
m_EditedCtrl.UnsubclassWindow();
}
if(pWnd->GetSafeHwnd() != NULL){
m_EditedCtrl.SubclassWindow(pWnd->GetSafeHwnd());
}
}
とするだけで、移動とコマンドメッセージのブロックをやってくれます。一度に一つしかサブク
ラス化できないことと、this はサブクラス化できないので気をつけてください。
編集系は、CEditedCtrl に任せてしまうとコードもすっきりするのかな、と思います。
ただ、随分書き換えも必要だろうし、あちらを立てればこちらが立たずって事もありうるので参
考までに。
SundayProgramerさん、ありがとうございます。
早速、参考にさせていていただきます。(^_^)