2017-08-03 9 views
0

の作品DelphiでTStatusBarにTProgressBarを配置するhereを説明した:(?最近Windowsアップデート後)方法私はこの方法を使用し過去に

procedure TForm1.FormCreate(Sender: TObject); 
var 
    ProgressBarStyle: integer; 
begin 
    //enable status bar 2nd Panel custom drawing 
    StatusBar1.Panels[1].Style := psOwnerDraw; 
    //place the progress bar into the status bar 
    ProgressBar1.Parent := StatusBar1; 
    //remove progress bar border 
    ProgressBarStyle := GetWindowLong(ProgressBar1.Handle, GWL_EXSTYLE); 
    ProgressBarStyle := ProgressBarStyle - WS_EX_STATICEDGE; 
    SetWindowLong(ProgressBar1.Handle, GWL_EXSTYLE, ProgressBarStyle); 
end; 

procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel; 
    const Rect: TRect); 
begin 
    if Panel = StatusBar.Panels[1] then 
    with ProgressBar1 do 
    begin 
    Top := Rect.Top; 
    Left := Rect.Left; 
    Width := Rect.Right - Rect.Left; 
    Height := Rect.Bottom - Rect.Top; 
    end; 
end; 

しかし、このもはや動作しません。つまり、古いプログラムは期待どおりに動作しますが、新しくコンパイルされたプログラムは動作しません。私はWindows 10で同じDelphiバージョン、XE8を使用しています。

これはこのメソッドが不適切だったということですか?これを行う正しい方法は何ですか?

+0

それは、このような進行状況を表示するウィンドウコントロールを作成するには、上部の上です。私はいつも進行状況をパネルに直接ペイントすることでそれをやってきました。単純なFillRect呼び出し、またはスタイル/テーマの場合はスタイル/テーマAPIを使用します。 –

+0

意味がある、私はそれを試みる。 (一般的にプログレスバーについても同じことは言えませんが)私のコードが突然動かないのはどういうことなのでしょうか?ありがとう。 – stevenvh

答えて

3

他の人が説明したように、TProgressBarのウィンドウスタイルを誤って管理すると、問題が発生します。

TProgressBarを配置するためにTStatusBar.OnDrawPanelイベントを使用する必要はありません(使用しないでください)ということを付け加えたいと思います。描画イベントであり、オブジェクト管理イベントではありません。 TStatusBar.Canvasにプログレスバーを手動で描画しない場合は、OnDrawPanelハンドラを完全に削除する必要があります。

代わりに、パネルの座標と寸法を取得し、それに応じてTProgressBarを配置するSB_GETRECTメッセージを使用することにより、起動時にTProgressBar 1時間を置くことができます。例:

uses 
    CommCtrl; 

procedure TForm1.FormCreate(Sender: TObject); 
var 
    ... 
    R: TRect; 
begin 
    // no need to set the panel's Style to psOwnerDraw! 
    ... 
    //place the progress bar into the status bar 
    SendMessage(StatusBar1.Handle, SB_GETRECT, 1, LPARAM(@R)); 
    ProgressBar1.Parent := StatusBar1; 
    ProgressBar1.SetBounds(R.Left, R.Top, R.Width, R.Height); 
    ... 
end; 

フォームがサイズ変更可能である場合

、あなたパネルのサイズが変更場合 TProgressBarを再配置する TStatusBar.OnResizeイベントを使用することができます。

uses 
    CommCtrl; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    // no need to set the panel's Style to psOwnerDraw! 
    ... 
    //place the progress bar into the status bar 
    ProgressBar1.Parent := StatusBar1; 
    StatusBar1Resize(nil); 
    ... 
end; 

procedure TForm1.StatusBar1Resize(Sender: TObject); 
var 
    R: TRect; 
begin 
    //place the progress bar over the 2nd panel 
    SendMessage(StatusBar1.Handle, SB_GETRECT, 1, LPARAM(@R)); 
    ProgressBar1.SetBounds(R.Left, R.Top, R.Width, R.Height); 
end; 
+0

ThoughtCoのコードは悪い考えであり、私はそれを正しく見ずに使ったことに恥ずかしく思います。ありがとう – stevenvh

1

あなたが国境の世話を行削除する場合それは動作します:

// remove these lines 
ProgressBarStyle := GetWindowLong(ProgressBar1.Handle, GWL_EXSTYLE); 
ProgressBarStyle := ProgressBarStyle - WS_EX_STATICEDGE; 
SetWindowLong(ProgressBar1.Handle, GWL_EXSTYLE, ProgressBarStyle); 

を結果として二重枠がとして見栄えしないので、OnDrawPanelでFillRectを呼び出すのデビッドのソリューションは、よりよい解決策かもしれ。これは、あなたが最終的にその醜い緑を取り除くことができるという特別な利点があります:-)。

procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel; 
    const Rect: TRect); 
var 
    R: TRect; 
begin 
    if Panel = StatusBar.Panels[1] then 
    begin 
    StatusBar.Canvas.Brush.Color := clBtnFace; 
    StatusBar.Canvas.FillRect(Rect); 
    R := Rect; 
    R.Right := Round(R.Left + (R.Right - R.Left) * FProgress {0..1}); 
    StatusBar.Canvas.Brush.Color := clGrayText; 
    StatusBar.Canvas.FillRect(R); 
    end; 
end; 

注:ONDrawPanelイベントハンドラが実行されますように、ステータスバーのInvalidateメソッドを呼び出す必要があります。

+0

@downvoter - 最初に間違っていることを教えてくれないと、この回答を改善する方法はありますか? – stevenvh

+1

それは本当に質問された質問に答えるものではありません。答えの1つだけが実際にそれを行います。 –

3

私は行動の変更のために持っている唯一の明白な説明は、このコードが間違っているということです。

ProgressBarStyle := ProgressBarStyle - WS_EX_STATICEDGE; 

このコードはWS_EX_STATICEDGEのスタイルで、すでにあることを前提としています。しかし、そうでなければ、あなたは窓のスタイルを破壊しています。ウィンドウが再作成されている場合、このウィンドウスタイルは、VCLの下で起こるん、何かを失われることも

ProgressBarStyle := ProgressBarStyle and not WS_EX_STATICEDGE; 

注:このコードは、ビット演算を使用する必要があります。より良いオプションは、プログレスバークラスをサブクラス化し、スタイルを直接オーバーライドされたCreateParamsに設定することです。

+0

私はそれを逃した奇妙な、それは答えと思われる。つまり、あなたが緑が好きなら、...-) – stevenvh

関連する問題