はじめまして。早速質問させていただきます。
例えば、画面に正方形が複数個配置されており、
その中のひとつをドラッグで任意の場所に運ぶことができるとします。
(正方形の左上座標を配列に記憶しています)
この中で正方形を移動させているときの処理方法なのですが、
(1)FillRectを使って画面全体を白く塗りつぶす。
(2)WM_MOUSEMOVEを捕まえてRectangleで正方形を描画
以上の処理を長方形ドラッグ中繰り返し。
という手順で行っています。
ちなみに(2)の処理は長方形の数だけfor文で繰り返しています。
しかし、この方法で正方形の数が多くなったときに処理が遅くなってしまいました。
500個ほど表示したところでリアルタイムに正方形がマウスについて行かなくなります。
そこで、
・画面全体を塗りつぶすのではなく、必要な部分だけを更新する。
・もっと有用な方法を利用する。
など、手順を短くする方法をお教えください。
今まで我流でやってきたので画面の更新に対しての知識が、
基本的な部分で間違っているかもしれません。
ちなみに必要な部分だけを更新する方法に関しては、
そういったAPI関数がなく、自分で作成しなければならないのであれば諦めます。
自作するのであれば、ここで質問させて頂かなくとも自力でできます。
あまり時間がないので…。
その他にもこういったGUI部分を裏で処理してくれるツールキットなどがあれば、
その情報もお願いしたいと思います。
OSはWindowsXP、VisualStudio.NETで開発しています。
C言語で作成しており、MFCは使っていません。
::IntersectClipRect() 、
::ExcludeClipRect() あたりが使えるのでは。
全ての正方形の描画をWM_PAINTでやってないのですか?
WM_PAINTで処理しているなら、操作対象の正方形が移動する部分、
つまり、移動前と移動後を含む最小の長方形をInvalidateRectすればよいのでは?
またドラッグ中に描画しつづけることは本当に必要なのでしょうか?
エクセルやワードに貼り付けた図形をドラッグするときは、輪郭を点線で表し、
反転させています。これでも良いならこっちの方が大分楽ですが。
>・画面全体を塗りつぶすのではなく、必要な部分だけを更新する。
これに尽きます。移動対象の正方形のみを描画更新します。
こうすれば全体の正方形の数がいくつだろうが、移動中の描画速度を
O(1)に固定できます。
例えば、XORのラスターオペレーションを使い、WM_MOUSEMOVEの中で
o 前回分を消す
o 今回分を描く
という古典的な方法があります。これは描画負荷自体も小さく有用です。
又、合わせて描画面積の小さな方法を選ぶのもいいと思います。面画より線画という事です。
これは ピクセル打ち込み速度の遅いデバイスで より有効です。
この方法は、特に全クライアント領域更新を必要とする描画(DirectXやOpenGL等)と
同期させて描画する時などは、目に見えて速度面の利益が出ます。
案として、、、
正方形の重ね合わせの順番が変化しないとします。
移動する正方形の前まで描画したものと、移動する正方形の次から描画したものを用
意します。
「前までのも」のを背景として移動した正方形を描画し、「次からのもの」を重ね合
わせ表示します。
重ね合わせの表示処理を変化があったとこだけ行うようにすれば更に良いでしょう。
例)
250番目を移動中。
1~249番目を描画したものと、251~500番目を描画したものを用意しま
す。
1~249番目を描画したものを裏画面にコピーし、250番目を描画します。
251~500番目を描画したものを裏画面に重ね合わせします。
裏画面を表示します。
ありがとうございます。
「輪郭を点線で表し、反転させています」←今のところはこの方法にしました。
しかし、この正方形の問題は例題であり、
実際はここからさらに「正方形と正方形をラインで繋ぐ」など、
いろいろな処理を施していきます。
ラインも同時に確認したいため、リアルタイムで動作させたかったのです。
しかし、そうなると基本的に画面全体を更新しなくてはならなくなります。
(たとえば移動中の正方形が、画面の端の正方形とリンクしている場合、
そのラインも同時に更新しなくてはならないため)
ですのでさらに改良していきたいと思います。
IntersectClipRect、ExcludeClipRect
これは知りませんでした。調べてみます。
XORのラスターオペレーションについても知識がないため、これから勉強します。
NEG(ねぐ)さんの案は思いつきませんでした。
利用できないか考えてみます。