可視状態にあるコンポーネントを取得するには?

解決


ちらつき防止隊員  2006-02-28 16:25:53  No: 20257  IP: 192.*.*.*

いま、ちらつき防止をなくすために、DoubleBufferedを使っているのですが、
作成中のアプリケーションは使用するコンポーネントが非常に多く(200近い)、
いまいち全てのコンポーネントのDoubleBufferedをtrueに手作業でする気にはなりません。
Delphi6.0pro XP
ですが、はなからTwinControlから継承されるコントロールのDoubleBufferedをtrueにする方法ってないですか?

ただ、不安なのはそれだけのコントロール全てをダブルバッファすると動作が重くなるのではないかとも思うのです。
かといって、ちらつきもコントロールの数に比例(?)するし、ちらつきは防ぎたいものです。他にちらつきをなくす方法ってないですかね?

編集 削除
ママん  2006-02-28 18:28:07  No: 20258  IP: 192.*.*.*

200個のコントロールをベタ張りしてる時点で気になりますが、
目的の動作であれば、Controls.pasをコピーして、そのプロジェクトファイルのある場所に保存し、
procedure TWinControl.CreateWnd;
の最初の一行目に
FDoubleBuffered:=True;
を挿入して再コンパイルかければできます。
コピーは慎重に行ってください。

ちらつきを無くす他の方法としては、WM_ERASEBKGNDの返り値を0にして完全自前描画というのもありますが、面倒です。

編集 削除
Fusa  2006-02-28 18:46:52  No: 20259  IP: 192.*.*.*

コピーしてコンパイルっていうのは大変でしょう。

procedure TForm1.AllDoubleBufferd;
var
  i: Integer;
begin
  for i := 0 to Self.ComponentCount-1 do
    if (Self.Components[i] is TWinControl) then
      (Self.Components[i] as TWinControl).DoubleBuffered := true;
end;
これをFormCreateイベントあたりで呼べばいいと
思います。

編集 削除
ちらつき防止隊員  2006-03-01 00:44:38  No: 20260  IP: 192.*.*.*

ママんさんありがとうございます。早速試したところうまくいきました。
ただ、コピーしたControl.pasって用済みになれば削除してもいんですよね。
まだ、よく理解していないのですが、プロジェクトファイルと同じ場所にファイルアない場合はライブラリパスにあるファイルを検知してくれるのですよね??

それからFusaさんありがとうございます。HELP見てたらComponentCountつかえそうだよなぁ〜〜なんて持ったところで使い方わからず、逃げていました。
このコード大変参考になります。
ComponentsってComponentsListのことですよね?
ComponentsListって単語だけ出てヘルプにはその解説が見当たらないのです(TT)

ありがとうございました。

編集 削除
 2006-03-01 09:57:00  No: 20261  IP: 192.*.*.*

> ComponentsってComponentsListのことですよね?
> ComponentsListって単語だけ出てヘルプにはその解説が見当たらないのです(TT)

Delphiのバージョンはいくつでしょう?
当方D5、D7を確認しましたが「Components」です。
さらに上では変わってしまったのでしょうか?

ちなみに、判定が必要なのはWinControlのみなので、ComponentCount + Componentsより、
ControlCount + Controls のほうがいいと思います。
実行結果に変わりはありませんが、Componentsだと、非ビジュアルコンポーネントとかも
含まれているので、無駄な判定が増えるかな?と。

編集 削除
 2006-03-02 10:16:49  No: 20262  IP: 192.*.*.*

って言うよりTWinControl.CreateWndをoverloadしてFDoubleBuffered:=True;を追加した方が早いと思うんだが^^;

編集 削除
Fusa  2006-03-03 20:18:42  No: 20263  IP: 192.*.*.*

ControlCount + Controls だと
Panelの上にPanelやButtonやEditがのっている物を見つけるために、再帰的処理を書かなければいけなかったのではないでしょうか?

自分の手元のメモではそう書いてました。

編集 削除
ぁゃιぃ  2006-03-03 22:37:21  No: 20264  IP: 192.*.*.*

ControlCount + Controls も ComponentCount + Components も
再帰的処理は必要なんじゃないの?

編集 削除
ぁゃιぃ  2006-03-03 22:45:49  No: 20265  IP: 192.*.*.*

気になって調べてみたら・・・
うわ、Componentsって、所有物全部持ってるんだ。
なんかヤダ・・・。

編集 削除
ぁゃιぃ  2006-03-03 23:02:18  No: 20266  IP: 192.*.*.*

すいません、スレ荒らしてしまいました。

ControlCount + Controls は、再帰処理が必要ですが、
ComponentCount + Components は不要です。

また、ComponentCountは、フォーム(たぶんフレームも?)でのみ使用可能です。
例えば、フォーム上にパネルを一個置いて、パネルの上にボタンを置きます。
そうすると、こんな感じ。

              ComponentCount      ControlCount
親:フォーム        2                  1
子:パネル          0                  1
孫:ボタン          0                  0

うーむ、初めて知りました。

編集 削除
えーと  2006-03-03 23:32:19  No: 20267  IP: 192.*.*.*

> ComponentCountは、フォーム(たぶんフレームも?)でのみ使用可能です。

錯綜してるようですが、ヘルプを読むと

TComponent.ComponentCount
ComponentCount プロパティは,コンポーネントが所有するコンポーネントの数を示します。

TComponent.Components
Components プロパティは,コンポーネントが所有するすべてのコンポーネントを一覧表示します。

どちらも、TComponent 派生クラスのプロパティーで、オーナーになれればつかえ
ます。TForm に置かれたコンポーネントは、デフォルトですべてそのフォームに
所有されます。



TWinControl.ControlCount
ControlCount プロパティは,子コントロールの数を返します。

TWinControl.Controls
Controls プロパティは,すべての子コントロールを表示します。

ということで、TWinControl の派生クラスで親になれば使えます。コントロールの
親になれるのは、ウィンドウハンドルをもつ TWinContorl 派生クラスだけです。

所有関係と親子関係を混同すると面倒なことになります。

編集 削除
あれま  2006-03-04 13:02:10  No: 20268  IP: 192.*.*.*

> どちらも、TComponent 派生クラスのプロパティーで、オーナーになれればつかえ
> ます。TForm に置かれたコンポーネントは、デフォルトですべてそのフォームに
> 所有されます。

button := TButton.Create(Panel1);
このように記述すると、ここでクリエイトされたTButtonは、Panel1の所有物。

button.Parent := Form1;

このように親を指定して初めて親子関係ができあがる。


ぽとりぺたりで設計しただけのフォームなら、すべてのコンポーネントは、
フォームの所有物になるので、ComponentCount + Components で、
フォーム上の全てのコンポーネントが列挙される。

でも、上記例のように、ソースコードで記述しクリエイトされるコンポーネントは、
明示的にフォームを指定しないと、拾われない可能性がある。
だから「パネルの上にのっけるから、オーナーはパネルでいいや」ってやっちゃうと、
Componentsでは参照できないわけですね。

凝ったことやってるんだったら、ControlCount + Controls で再帰処理したほうがいい場合もあるでしょう。

編集 削除
仮死状態  2006-03-05 16:07:35  No: 20269  IP: 192.*.*.*

ごめん仮死状態って書きたかっただけです。

編集 削除
ちらつき防止隊員  2006-03-05 23:52:33  No: 20270  IP: 192.*.*.*

ごめんなさい。ただいま、DELPHIが入っているPCがトラブル中で、何もできません。もちろんみなさんの解答は大変参考になっています。ありがとうございます。

編集 削除
ちらつき防止隊員  2006-03-12 00:18:12  No: 20271  IP: 192.*.*.*

改めてみなさん貴重なアドバイスありがとうございます。これからもお世話になります。よろしくお願いいたします。

編集 削除