ランタイムテーマ有効時のプログレスバー処理が遅い

解決


smatsu  2013-11-15 23:21:40  No: 45570

こんにちは。
WindowsVista + Delphi2007で開発を行っています。

ランタイムテーマを有効にした状態でプログレスバーのポジションを
変化させると、無効にした場合と比べてあまりに遅く困っています。

次のソースで検証しています。

procedure TForm1.Button1Click(Sender: TObject);
var
  I : Integer;
  st: cardinal;
begin
  ProgressBar1.Position := 0;
  st := GetTickCount;

  for I := 1 to 100000 do
    begin
      ProgressBar1.Position := Trunc(I / 100000 * 100);
    end;

  Caption := IntToStr(GetTickCount - st);
end;

ランタイムテーマ無効時  約0.78秒
ランタイムテーマ有効時  約9.5秒

プログレスバーのsmoothプロパティはFalseに設定しています。
事情によりランタイムテーマを無効にすることはできません。

この現象について何か情報があれば教えていただけないでしょうか。

ランタイムテーマの仕様なら仕方がないのですが、
何か回避方法がないかと質問させていただきました。

よろしくお願いいたします。


Quest  2013-11-15 23:59:43  No: 45571

同じVista+Delphi2007で試してみました。
どうやらランタイムテーマが有効だと描画に時間がかかるようです。
しかも非同期で描画されているようです。

procedure TForm1.Button1Click(Sender: TObject);
var
  I : Integer;
  st: cardinal;
  cnt: integer;
begin
  ProgressBar1.Position := 0;
  st := GetTickCount;
  cnt := 0;
  for I := 1 to 100000 do
    begin
      if cnt < Trunc(I / 100000 * 100) then
      begin 
        cnt := Trunc(I / 100000 * 100);
        ProgressBar1.Position := cnt;
      end;
    end;

  Caption := IntToStr(GetTickCount - st);
end;

このようにすると、私のPCではキャプションに18とか0とか表示されますが
キャプションに数値が表示された後にもプログレスバーが動き続けます。
最初の例だとプログレスバーの更新が10万回実行されますが
これを必要最小限にすれば回避できると思います。


DEKO  2013-11-16 00:11:45  No: 45572

> これを必要最小限にすれば回避できると思います。
こんな感じですかね。

var
  I : Integer;
  st: cardinal;
  CurrentPosition, OldPosition: Integer;
begin
  ProgressBar1.Position := 0;
  CurrentPosition       := ProgressBar1.Position;
  OldPosition           := ProgressBar1.Position;
  st := GetTickCount;

  for I := 1 to 100000 do
    begin
      CurrentPosition := Trunc(I / 100000 * 100);
      if OldPosition <> CurrentPosition then
        ProgressBar1.Position := CurrentPosition;
      OldPosition := ProgressBar1.Position;
    end;

  Caption := IntToStr(GetTickCount - st);
end;

ComCtrls.TProgressBar.SetPosition を書き換えたほうが手っ取り早いかもしれませんね。


smatsu  2013-11-16 00:52:23  No: 45573

Questさん、DEKOさん、ありがとうございます。

確かに10万回セットは無駄でしかないですね。。。
いただいたサンプルで確認すると、ほぼ同じような処理時間になりました。

普段からこういう丁寧な作り方をするよう心がけます。

今回初めてランタイムテーマを有効にするアプリケーションを
作成するのですが、何かと問題が発生して苦戦しています。

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


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

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






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