2011. február 6., vasárnap

A Trackbar like on the desktop volume control


Problem/Question/Abstract:

Has it ever bothered you that the TTrackbar in Delphi doesn't look the way you expect?

Answer:

Solve 1:

The TTrackBar in Delphi is very wide. This is unlike the trackbar you see used throughout the Windows 9X and 2000 desktops. For some reason I found this annoying.

After doing some research and a bit of experimenting I discovered the reason. When Delphi creates the trackbar from the windows common controls store it specifies a style of TBS_ENABLESELRANGE (see TTrackBar.CreateParams in ComCtrls.pas). The TBS_ENABLESELRANGE style is what allows the Trackbar to display a selection range and support the three properties SelEnd, SelRange and SelStart..

This range feature is nice but under normal usage isn’t used much. In most cases all we want is a slider that we can set a min an max value and then set and track the current position (like the desktop volume control).

Anyway, it turns out that if the trackbar is created without this TBS_ENABLESELRANGE style set, then it’s thickness reverts back to the skinny slider seen on the desktop. See the complete code below for ToaTrackbar.

The new ToaTrackBar is very simple. It just adds a boolean SelRange property which specifies if you want to use the range features of the component. This property defaults to true so it is exactly like the current TTrackBar component. If you can live without the range feature then you can set SelRange to false which has a visible slimming effect. In the code, setting SelRange to false simply recreates the control without the TBS_ENABLESELRANGE style.

To Use - Once you’ve installed the component code below into your IDE then go to the Samples tab on the component palette find the oaTrackBar and drop it on a form. Now set the new SelRange property to false, TickMarks to tmBoth and TickStyle to tsNone and presto, you have a trackbar just like the desktops volume control.

unit oaTrackBar;
{ Freeware by Alec Bergamini O&A Productions www.o2a.com
  Setting the SelRange to false, TickMarks to tmBoth and TickStyle
  tsNone gives you the same look as the desktop volume slider.}
interface

uses
  Windows, Messages, SysUtils, Classes, Controls, ComCtrls, CommCtrl;

type
  ToaTrackBar = class(TTrackBar)
  private
    fSelRange: Boolean;
    procedure SetSelRange(const Value: Boolean);
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property SelRange: Boolean read fSelRange write SetSelRange default True;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [ToaTrackBar]);
end;

{ ToaTrackBar }

constructor ToaTrackBar.Create(AOwner: TComponent);
begin
  inherited;
  fSelRange := True;
end;

procedure ToaTrackBar.CreateParams(var Params: TCreateParams);
begin
  inherited;
  with Params do
  begin
    if not fSelRange then
      Style := Style and not TBS_ENABLESELRANGE;
  end;
end;

procedure ToaTrackBar.SetSelRange(const Value: Boolean);
begin
  if Value <> fSelRange then
  begin
    fSelRange := Value;
    RecreateWnd;
  end;
end;

end.


Solve 2:

procedure TForm1.Button1Click(Sender: TObject);
var
  h1: integer;
begin
  h1 := getwindowlong(trackbar1.handle, GWL_STYLE);
  h1 := h1 xor $20 {numeric value of TBS_ENABLESELRANGE};
  setwindowlong(trackbar1.handle, GWL_STYLE, h1);
end;

Nincsenek megjegyzések:

Megjegyzés küldése