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

解決


ちらつき防止隊員  2006-03-01 01:25:53  No: 20257

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

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


ママん  2006-03-01 03:28:07  No: 20258

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

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


Fusa  2006-03-01 03:46:52  No: 20259

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

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 09:44:38  No: 20260

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

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

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


  2006-03-01 18:57:00  No: 20261

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

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

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


  2006-03-02 19:16:49  No: 20262

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


Fusa  2006-03-04 05:18:42  No: 20263

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

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


ぁゃιぃ  2006-03-04 07:37:21  No: 20264

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


ぁゃιぃ  2006-03-04 07:45:49  No: 20265

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


ぁゃιぃ  2006-03-04 08:02:18  No: 20266

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

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

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

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

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


えーと  2006-03-04 08:32:19  No: 20267

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

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

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

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

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

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

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

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

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


あれま  2006-03-04 22:02:10  No: 20268

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

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

button.Parent := Form1;

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

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

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

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


仮死状態  2006-03-06 01:07:35  No: 20269

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


ちらつき防止隊員  2006-03-06 08:52:33  No: 20270

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


ちらつき防止隊員  2006-03-12 09:18:12  No: 20271

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


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加