I've got a program with a status bar at the bottom containing three elements. I'd like to redraw the second element in a different font color to signify that a user is valid. The first part of my question is:
a) How can I redraw the text in a different color to the default text?
and b) How can I draw the text in a different color after an event is triggered (For example a button push)?
My current code is below. I'm trying to check whether the condition for the panel to be repainted in a different color is correct (CurrentUser.Valid, which is a boolean), and then trying to recolor the text. This currently does not work.
procedure TChatFormMain.sbarMainDrawPanel(StatusBar: TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
var
RectForText: TRect;
begin
if (Panel = StatusBar.Panels[1]) and (CurrentUser.Valid) then
begin
sbarMain.Canvas.Font.Color := clGreen;
RectForText := Rect;
StatusBar.Canvas.FillRect(RectForText);
DrawText(sbarMain.Canvas.Handle, PChar(Panel.Text), -1, RectForText,
DT_SINGLELINE or DT_VCENTER or DT_LEFT);
end;
end;
In another part of the code I'm calling StatusBar.repaint;
to try and redraw the bar with the new text colour, is this correct?
Update MCVE:
unit colourStatusU;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;
type
TForm1 = class(TForm)
StatusBar1: TStatusBar;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure StatusBar1DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
const Rect: TRect);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
valid : boolean;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
valid := true;
StatusBar1.Repaint;
end;
procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
const Rect: TRect);
var
RectForText: TRect;
begin
if (Panel = StatusBar.Panels[1]) and (Valid) then
begin
Canvas.Font.Color := clGreen;
RectForText := Rect;
Canvas.FillRect(RectForText);
DrawText(Canvas.Handle, PChar(Panel.Text), -1, RectForText,
DT_SINGLELINE or DT_VCENTER or DT_LEFT);
end;
end;
end.
The OnDrawPanel
event is called only for a panel that has its Style
set to psOwnerDraw
, so make sure you have set the Style
properly, either in the Object Inspector or in code.
The Canvas
to paint on must be the TStatusBar.Canvas
, but you are using the TForm.Canvas
instead. Use the Canvas
of the StatusBar
that is provided by the OnDrawPanel
event:
procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
const Rect: TRect);
var
RectForText: TRect;
begin
if (Panel = StatusBar.Panels[1]) and (Valid) then
begin
StatusBar.Canvas.Font.Color := clGreen;
RectForText := Rect;
StatusBar.Canvas.FillRect(RectForText);
DrawText(StatusBar.Canvas.Handle, PChar(Panel.Text), -1, RectForText, DT_SINGLELINE or DT_VCENTER or DT_LEFT);
end;
end;
Calling Repaint()
or Invalidate()
to force the Statusbar to refesh its painting is the method to use.