mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 10:57:55 +02:00
538 lines
16 KiB
ObjectPascal
538 lines
16 KiB
ObjectPascal
unit customdrawn_windows7;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Types, Math,
|
|
{ Graphics }
|
|
LResources, Graphics, FPCanvas, FPImage, IntfGraphics, lazcanvas,
|
|
{ Custom Drawn }
|
|
customdrawn_common, customdrawndrawers;
|
|
|
|
type
|
|
TBitmapArray = array of TBitmap;
|
|
TBitmapArrays = array of TBitmapArray;
|
|
|
|
{ TSliceScaling }
|
|
|
|
TSliceScaling = class
|
|
private
|
|
BorWidth: integer;
|
|
BorHeight: integer;
|
|
FUseNativeStretch: boolean;
|
|
procedure SetFUseNativeStretch(AValue: boolean);
|
|
function InternalGetBitmapElements(bmpArrayStates: TBitmapArray;
|
|
Number, BorderWidth, BorderHeight: integer): TBitmapArrays;
|
|
protected
|
|
function GetBitmap(Filename: string; Number: integer; ALoadFromResource: Boolean = False): TBitmapArray;
|
|
function GetBitmapPart(Source: TBitmap;
|
|
BorderWidth, BorderHeight: integer): TBitmapArray;
|
|
function GetBitmapElements(Filename: string;
|
|
Number, BorderWidth, BorderHeight: integer): TBitmapArrays;
|
|
function GetBitmapElementsWithResource(AResourceName: string;
|
|
Number, BorderWidth, BorderHeight: integer): TBitmapArrays;
|
|
function DrawBitmapNonNativeStretch(Source: TBitmapArray;
|
|
DestWidth, DestHeight, BorderWidth, BorderHeight: integer): TBitmap;
|
|
function DrawBitmapNativeStretch(Source: TBitmapArray;
|
|
DestWidth, DestHeight, BorderWidth, BorderHeight: integer): TBitmap;
|
|
public
|
|
bmpArrays: TBitmapArrays;
|
|
constructor Create(Filename: string;
|
|
BorderWidth, BorderHeight, NumberOfItems: integer);
|
|
constructor CreateWithResource(AResourceName: string;
|
|
BorderWidth, BorderHeight, NumberOfItems: integer);
|
|
destructor Destroy; override;
|
|
function Draw(Width, Height, ItemIndex: integer): TBitmap;
|
|
procedure Draw(Dest: TCanvas; Left, Top, Width, Height, ItemIndex: integer);
|
|
public
|
|
property UseNativeStretch: boolean read FUseNativeStretch
|
|
write SetFUseNativeStretch default False;
|
|
property BorderWidth: integer read BorWidth;
|
|
property BorderHeight: integer read BorHeight;
|
|
end;
|
|
|
|
{ TCDWin7 }
|
|
|
|
TCDWin7 = class(TCDDrawerCommon)
|
|
// ===================================
|
|
// Standard Tab
|
|
// ===================================
|
|
// TCDButton
|
|
procedure DrawButton(ADest: TFPCustomCanvas; ADestPos: TPoint; ASize: TSize;
|
|
AState: TCDControlState; AStateEx: TCDButtonStateEx); override;
|
|
end;
|
|
|
|
var
|
|
win7button: TSliceScaling;
|
|
|
|
implementation
|
|
|
|
{$R customdrawnimages/windows7.res}
|
|
|
|
{ TSliceScaling }
|
|
|
|
procedure TSliceScaling.SetFUseNativeStretch(AValue: boolean);
|
|
begin
|
|
if FUseNativeStretch = AValue then
|
|
Exit;
|
|
FUseNativeStretch := AValue;
|
|
end;
|
|
|
|
function TSliceScaling.InternalGetBitmapElements(bmpArrayStates: TBitmapArray;
|
|
Number, BorderWidth, BorderHeight: integer): TBitmapArrays;
|
|
var
|
|
bmpArrayParts: TBitmapArrays = nil;
|
|
i, tempWidth, tempHeight: integer;
|
|
begin
|
|
if (BorderWidth * 2 > bmpArrayStates[0].Width) or (BorderWidth < 0) then
|
|
tempWidth := Trunc(bmpArrayStates[0].Width div 2)
|
|
else
|
|
tempWidth := BorderWidth;
|
|
|
|
if (BorderHeight * 2 > bmpArrayStates[0].Height) or (BorderHeight < 0) then
|
|
tempHeight := Trunc(bmpArrayStates[0].Height div 2)
|
|
else
|
|
tempHeight := BorderHeight;
|
|
|
|
SetLength(bmpArrayParts, Number, 9);
|
|
for i := Low(bmpArrayStates) to High(bmpArrayStates) do
|
|
begin
|
|
bmpArrayParts[i] := GetBitmapPart(bmpArrayStates[i], tempWidth, tempHeight);
|
|
bmpArrayStates[i].Free;
|
|
bmpArrayStates[i] := nil;
|
|
end;
|
|
|
|
bmpArrayStates := nil;
|
|
|
|
Result := bmpArrayParts;
|
|
end;
|
|
|
|
function TSliceScaling.GetBitmap(Filename: string; Number: integer; ALoadFromResource: Boolean = False): TBitmapArray;
|
|
var
|
|
bmpArray: TBitmapArray = nil;
|
|
temp: TBitmap;
|
|
i: integer;
|
|
s: TSize;
|
|
begin
|
|
temp := TBitmap.Create;
|
|
if ALoadFromResource then temp.LoadFromResourceName(HInstance, Filename)
|
|
else temp.LoadFromFile(Filename);
|
|
s.cx := temp.Width;
|
|
s.cy := temp.Height div Number;
|
|
|
|
SetLength(bmpArray, Number);
|
|
Result := bmpArray;
|
|
|
|
for i := Low(bmpArray) to High(bmpArray) do
|
|
begin
|
|
bmpArray[i] := TBitmap.Create;
|
|
bmpArray[i].Width := s.cx;
|
|
bmpArray[i].Height := s.cy;
|
|
bmpArray[i].Canvas.Draw(0, -s.cy * i, temp);
|
|
end;
|
|
|
|
temp.Free;
|
|
end;
|
|
|
|
function TSliceScaling.GetBitmapPart(Source: TBitmap;
|
|
BorderWidth, BorderHeight: integer): TBitmapArray;
|
|
var
|
|
bmpArray: TBitmapArray = nil;
|
|
begin
|
|
SetLength(bmpArray, 9);
|
|
Result := bmpArray;
|
|
|
|
{ Top Left }
|
|
bmpArray[0] := TBitmap.Create;
|
|
bmpArray[0].Width := BorderWidth;
|
|
bmpArray[0].Height := BorderHeight;
|
|
bmpArray[0].Canvas.Draw(0, 0, Source);
|
|
|
|
{ Top Right }
|
|
bmpArray[1] := TBitmap.Create;
|
|
bmpArray[1].Width := BorderWidth;
|
|
bmpArray[1].Height := BorderHeight;
|
|
bmpArray[1].Canvas.Draw(BorderWidth - Source.Width, 0, Source);
|
|
|
|
{ Bottom Left }
|
|
bmpArray[2] := TBitmap.Create;
|
|
bmpArray[2].Width := BorderWidth;
|
|
bmpArray[2].Height := BorderHeight;
|
|
bmpArray[2].Canvas.Draw(0, BorderHeight - Source.Height, Source);
|
|
|
|
{ Bottom Right }
|
|
bmpArray[3] := TBitmap.Create;
|
|
bmpArray[3].Width := BorderWidth;
|
|
bmpArray[3].Height := BorderHeight;
|
|
bmpArray[3].Canvas.Draw(BorderWidth - Source.Width, BorderHeight -
|
|
Source.Height, Source);
|
|
|
|
{ Center }
|
|
bmpArray[4] := TBitmap.Create;
|
|
bmpArray[4].Width := Source.Width - BorderWidth * 2;
|
|
bmpArray[4].Height := Source.Height - BorderHeight * 2;
|
|
bmpArray[4].Canvas.Draw(-BorderWidth, -BorderHeight, Source);
|
|
|
|
{ Top }
|
|
bmpArray[5] := TBitmap.Create;
|
|
bmpArray[5].Width := Source.Width - BorderWidth * 2;
|
|
bmpArray[5].Height := BorderHeight;
|
|
bmpArray[5].Canvas.Draw(-BorderWidth, 0, Source);
|
|
|
|
{ Left }
|
|
bmpArray[6] := TBitmap.Create;
|
|
bmpArray[6].Width := BorderWidth;
|
|
bmpArray[6].Height := Source.Height - BorderHeight * 2;
|
|
bmpArray[6].Canvas.Draw(0, -BorderHeight, Source);
|
|
|
|
{ Right }
|
|
bmpArray[7] := TBitmap.Create;
|
|
bmpArray[7].Width := BorderWidth;
|
|
bmpArray[7].Height := Source.Height - BorderHeight * 2;
|
|
bmpArray[7].Canvas.Draw(BorderWidth - Source.Width, -BorderHeight, Source);
|
|
|
|
{ Bottom }
|
|
bmpArray[8] := TBitmap.Create;
|
|
bmpArray[8].Width := Source.Width - BorderWidth * 2;
|
|
bmpArray[8].Height := BorderHeight;
|
|
bmpArray[8].Canvas.Draw(-BorderWidth, BorderHeight - Source.Height, Source);
|
|
end;
|
|
|
|
function TSliceScaling.GetBitmapElements(Filename: string;
|
|
Number, BorderWidth, BorderHeight: integer): TBitmapArrays;
|
|
var
|
|
bmpArrayStates: TBitmapArray;
|
|
begin
|
|
bmpArrayStates := GetBitmap(Filename, Number);
|
|
Result := InternalGetBitmapElements(bmpArrayStates, Number, BorderWidth, BorderHeight);
|
|
end;
|
|
|
|
function TSliceScaling.GetBitmapElementsWithResource(AResourceName: string;
|
|
Number, BorderWidth, BorderHeight: integer): TBitmapArrays;
|
|
var
|
|
bmpArrayStates: TBitmapArray;
|
|
begin
|
|
bmpArrayStates := GetBitmap(AResourceName, Number, True);
|
|
Result := InternalGetBitmapElements(bmpArrayStates, Number, BorderWidth, BorderHeight);
|
|
end;
|
|
|
|
function TSliceScaling.DrawBitmapNonNativeStretch(Source: TBitmapArray;
|
|
DestWidth, DestHeight, BorderWidth, BorderHeight: integer): TBitmap;
|
|
|
|
procedure StretchDrawBitmapToBitmap(SourceBitmap, DestBitmap: TBitmap;
|
|
DestWidth, DestHeight: integer);
|
|
var
|
|
DestIntfImage, SourceIntfImage: TLazIntfImage;
|
|
DestCanvas: TLazCanvas;
|
|
begin
|
|
// Prepare the destination
|
|
DestIntfImage := TLazIntfImage.Create(0, 0);
|
|
DestIntfImage.LoadFromBitmap(DestBitmap.Handle, 0);
|
|
|
|
DestCanvas := TLazCanvas.Create(DestIntfImage);
|
|
|
|
//Prepare the source
|
|
SourceIntfImage := TLazIntfImage.Create(0, 0);
|
|
SourceIntfImage.LoadFromBitmap(SourceBitmap.Handle, 0);
|
|
|
|
// Execute the stretch draw via TFPSharpInterpolation
|
|
DestCanvas.Interpolation := TFPSharpInterpolation.Create;
|
|
DestCanvas.StretchDraw(0, 0, DestWidth, DestHeight, SourceIntfImage);
|
|
|
|
// Reload the image into the TBitmap
|
|
DestBitmap.LoadFromIntfImage(DestIntfImage);
|
|
|
|
SourceIntfImage.Free;
|
|
DestCanvas.Interpolation.Free;
|
|
DestCanvas.Free;
|
|
DestIntfImage.Free;
|
|
end;
|
|
|
|
procedure DrawStretch(Source, Dest: TBitmap; x, y, w, h: integer);
|
|
var
|
|
temp: TBitmap;
|
|
begin
|
|
if (Source.Width <> w) or (Source.Height <> h) then
|
|
begin
|
|
temp := TBitmap.Create;
|
|
temp.Width := w;
|
|
temp.Height := h;
|
|
StretchDrawBitmapToBitmap(Source, temp, w, h);
|
|
dest.Canvas.Draw(x, y, temp);
|
|
temp.Free;
|
|
end
|
|
else
|
|
dest.Canvas.Draw(x, y, Source);
|
|
end;
|
|
|
|
procedure DrawEachPart(Source: TBitmapArray; dest: TBitmap;
|
|
DestWidth, DestHeight, BorderWidth, BorderHeight: integer);
|
|
begin
|
|
// center
|
|
if (DestWidth > BorderWidth * 2) and (DestHeight > BorderHeight * 2) then
|
|
DrawStretch(Source[4], dest, BorderWidth, BorderHeight, DestWidth -
|
|
2 * BorderWidth, DestHeight - 2 * BorderHeight);
|
|
//top
|
|
DrawStretch(Source[5], dest, BorderWidth, 0, DestWidth - 2 * BorderWidth,
|
|
BorderHeight);
|
|
//left
|
|
DrawStretch(Source[6], dest, 0, BorderHeight, BorderWidth, DestHeight -
|
|
2 * BorderHeight);
|
|
//right
|
|
DrawStretch(Source[7], dest, DestWidth - BorderWidth, BorderHeight,
|
|
BorderWidth, DestHeight - 2 * BorderHeight);
|
|
//bottom
|
|
DrawStretch(Source[8], dest, BorderWidth, DestHeight - BorderHeight,
|
|
DestWidth - 2 * BorderWidth, BorderHeight);
|
|
//top left
|
|
DrawStretch(Source[0], dest, 0, 0, BorderWidth, BorderHeight);
|
|
//top right
|
|
DrawStretch(Source[1], dest, DestWidth - BorderWidth, 0, BorderWidth, BorderHeight);
|
|
//bottom left
|
|
DrawStretch(Source[2], dest, 0, DestHeight - BorderHeight, BorderWidth,
|
|
BorderHeight);
|
|
//bottom right
|
|
DrawStretch(Source[3], dest, DestWidth - BorderWidth, DestHeight -
|
|
BorderHeight, BorderWidth, BorderHeight);
|
|
end;
|
|
|
|
var
|
|
temp: TBitmap;
|
|
tempWidth, tempHeight: integer;
|
|
begin
|
|
if (BorderWidth < 1) or (BorderHeight < 1) then
|
|
begin
|
|
Result := TBitmap.Create;
|
|
Result.Width := DestWidth;
|
|
Result.Height := DestHeight;
|
|
StretchDrawBitmapToBitmap(Source[4], Result, DestWidth, DestHeight);
|
|
Result.Transparent := True;
|
|
Result.TransparentColor := clFuchsia;
|
|
exit;
|
|
end;
|
|
|
|
if DestWidth < BorderWidth * 2 then
|
|
tempWidth := BorderWidth * 2
|
|
else
|
|
tempWidth := DestWidth;
|
|
|
|
if DestHeight < BorderHeight * 2 then
|
|
tempHeight := DestHeight * 2
|
|
else
|
|
tempHeight := DestHeight;
|
|
|
|
temp := TBitmap.Create;
|
|
temp.Width := tempWidth;
|
|
temp.Height := tempHeight;
|
|
temp.Transparent := True;
|
|
temp.TransparentColor := clFuchsia;
|
|
DrawEachPart(Source, temp, tempWidth, tempHeight, BorderWidth, BorderHeight);
|
|
|
|
if (tempWidth <> DestWidth) or (tempHeight <> DestHeight) then
|
|
begin
|
|
Result := TBitmap.Create;
|
|
Result.Width := DestWidth;
|
|
Result.Height := DestHeight;
|
|
StretchDrawBitmapToBitmap(temp, Result, DestWidth, DestHeight);
|
|
Result.Transparent := True;
|
|
Result.TransparentColor := clFuchsia;
|
|
temp.Free;
|
|
end
|
|
else
|
|
Result := temp;
|
|
end;
|
|
|
|
function TSliceScaling.DrawBitmapNativeStretch(Source: TBitmapArray;
|
|
DestWidth, DestHeight, BorderWidth, BorderHeight: integer): TBitmap;
|
|
|
|
procedure DrawEachPart(Source: TBitmapArray; dest: TBitmap;
|
|
DestWidth, DestHeight, BorderWidth, BorderHeight: integer);
|
|
begin
|
|
//center
|
|
dest.Canvas.StretchDraw(Rect(BorderWidth, BorderHeight, DestWidth -
|
|
BorderWidth, DestHeight - BorderHeight), Source[4]);
|
|
//top
|
|
dest.Canvas.StretchDraw(Rect(BorderWidth, 0, DestWidth - BorderWidth, BorderHeight),
|
|
Source[5]);
|
|
//left
|
|
dest.Canvas.StretchDraw(Rect(0, BorderHeight, BorderWidth, DestHeight -
|
|
BorderHeight),
|
|
Source[6]);
|
|
//right
|
|
dest.Canvas.StretchDraw(Rect(DestWidth - BorderWidth, BorderHeight,
|
|
DestWidth, DestHeight - BorderHeight), Source[7]);
|
|
//bottom
|
|
dest.Canvas.StretchDraw(Rect(BorderWidth, DestHeight - BorderHeight,
|
|
DestWidth - BorderWidth, DestHeight), Source[8]);
|
|
//top left
|
|
dest.Canvas.StretchDraw(Rect(0, 0, BorderWidth, BorderHeight), Source[0]);
|
|
//top right
|
|
dest.Canvas.StretchDraw(Rect(DestWidth - BorderWidth, 0, DestWidth, BorderHeight),
|
|
Source[1]);
|
|
//bottom left
|
|
dest.Canvas.StretchDraw(Rect(0, DestHeight - BorderHeight, BorderWidth, DestHeight),
|
|
Source[2]);
|
|
//bottom right
|
|
dest.Canvas.StretchDraw(Rect(DestWidth - BorderWidth, DestHeight -
|
|
BorderHeight, DestWidth, DestHeight), Source[3]);
|
|
end;
|
|
|
|
var
|
|
dest: TBitmap;
|
|
begin
|
|
dest := TBitmap.Create;
|
|
dest.Transparent := True;
|
|
dest.TransparentColor := clFuchsia;
|
|
dest.Width := DestWidth;
|
|
dest.Height := DestHeight;
|
|
Result := dest;
|
|
|
|
DrawEachPart(Source, dest, DestWidth, DestHeight, BorderWidth, BorderHeight);
|
|
end;
|
|
|
|
constructor TSliceScaling.Create(Filename: string;
|
|
BorderWidth, BorderHeight, NumberOfItems: integer);
|
|
begin
|
|
FUseNativeStretch := False;
|
|
BorWidth := BorderWidth;
|
|
BorHeight := BorderHeight;
|
|
BmpArrays := GetBitmapElements(Filename, NumberOfItems, BorderWidth, BorderHeight);
|
|
inherited Create;
|
|
end;
|
|
|
|
constructor TSliceScaling.CreateWithResource(AResourceName: string;
|
|
BorderWidth, BorderHeight, NumberOfItems: integer);
|
|
begin
|
|
FUseNativeStretch := False;
|
|
BorWidth := BorderWidth;
|
|
BorHeight := BorderHeight;
|
|
BmpArrays := GetBitmapElementsWithResource(AResourceName, NumberOfItems, BorderWidth, BorderHeight);
|
|
inherited Create;
|
|
end;
|
|
|
|
destructor TSliceScaling.Destroy;
|
|
var
|
|
i, j: integer;
|
|
begin
|
|
for i := Low(bmpArrays) to High(BMPArrays) do
|
|
begin
|
|
for j := Low(BMPArrays[i]) to High(BMPArrays[i]) do
|
|
begin
|
|
BMPArrays[i, j].Free;
|
|
BMPArrays[i, j] := nil;
|
|
end;
|
|
BMPArrays[i] := nil;
|
|
end;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TSliceScaling.Draw(Width, Height, ItemIndex: integer): TBitmap;
|
|
begin
|
|
if UseNativeStretch then
|
|
Result := DrawBitmapNativeStretch(bmpArrays[ItemIndex], Width,
|
|
Height, BorWidth, BorHeight)
|
|
else
|
|
Result := DrawBitmapNonNativeStretch(bmpArrays[ItemIndex], Width,
|
|
Height, BorWidth, BorHeight);
|
|
end;
|
|
|
|
procedure TSliceScaling.Draw(Dest: TCanvas;
|
|
Left, Top, Width, Height, ItemIndex: integer);
|
|
var
|
|
temp: TBitmap;
|
|
begin
|
|
if UseNativeStretch then
|
|
temp := DrawBitmapNativeStretch(bmpArrays[ItemIndex], Width,
|
|
Height, BorWidth, BorHeight)
|
|
else
|
|
temp := DrawBitmapNonNativeStretch(bmpArrays[ItemIndex], Width,
|
|
Height, BorWidth, BorHeight);
|
|
|
|
Dest.Draw(Left, Top, temp);
|
|
temp.Free;
|
|
end;
|
|
|
|
{ TCDWin7 }
|
|
|
|
procedure TCDWin7.DrawButton(ADest: TFPCustomCanvas; ADestPos: TPoint; ASize: TSize;
|
|
AState: TCDControlState; AStateEx: TCDButtonStateEx);
|
|
var
|
|
Str: string;
|
|
lGlyphLeftSpacing: integer = 0;
|
|
lTextOutPos: TPoint;
|
|
lGlyphCaptionHeight: integer;
|
|
ItemIndex: integer;
|
|
begin
|
|
// ItemIndex
|
|
if csfEnabled in AState then
|
|
begin
|
|
ItemIndex := 0;
|
|
if csfHasFocus in AState then
|
|
ItemIndex := 4;
|
|
if csfMouseOver in AState then
|
|
ItemIndex := 1;
|
|
if csfSunken in AState then
|
|
ItemIndex := 2;
|
|
end
|
|
else
|
|
ItemIndex := 3;
|
|
|
|
// Draw ItemIndex
|
|
win7button.Draw(ADest as TCanvas, 0, 0, ASize.cx, ASize.cy, ItemIndex);
|
|
|
|
// Position calculations
|
|
if ADest is TCanvas then
|
|
begin
|
|
ADest.Font.Assign(AStateEx.Font);
|
|
Str := AStateEx.Caption;
|
|
lGlyphCaptionHeight := Max(TCanvas(ADest).TextHeight(Str), AStateEx.Glyph.Height);
|
|
lTextOutPos.X := (ASize.cx - TCanvas(ADest).TextWidth(Str) -
|
|
AStateEx.Glyph.Width) div 2;
|
|
lTextOutPos.Y := (ASize.cy - lGlyphCaptionHeight) div 2;
|
|
lTextOutPos.X := Max(lTextOutPos.X, 5);
|
|
lTextOutPos.Y := Max(lTextOutPos.Y, 5);
|
|
|
|
// Button glyph
|
|
if not AStateEx.Glyph.Empty then
|
|
begin
|
|
TCanvas(ADest).Draw(lTextOutPos.X, lTextOutPos.Y, AStateEx.Glyph);
|
|
lGlyphLeftSpacing := AStateEx.Glyph.Width + 5;
|
|
end;
|
|
|
|
// Button text
|
|
lTextOutPos.X := lTextOutPos.X + lGlyphLeftSpacing;
|
|
lTextOutPos.Y := (ASize.cy - TCanvas(ADest).TextHeight(Str)) div 2;
|
|
ADest.Brush.Style := bsClear;
|
|
ADest.Pen.Style := psSolid;
|
|
if csfEnabled in AState then
|
|
begin
|
|
ADest.TextOut(lTextOutPos.X, lTextOutPos.Y, Str);
|
|
end
|
|
else
|
|
begin
|
|
// The disabled text is composed by a white shadow under it and a grey text
|
|
TCanvas(ADest).Font.Color := clWhite;
|
|
Inc(lTextOutPos.X);
|
|
Inc(lTextOutPos.Y);
|
|
TCanvas(ADest).TextOut(lTextOutPos.X, lTextOutPos.Y, Str);
|
|
|
|
TCanvas(ADest).Font.Color := clSilver;
|
|
Dec(lTextOutPos.X);
|
|
Dec(lTextOutPos.Y);
|
|
ADest.TextOut(lTextOutPos.X, lTextOutPos.Y, Str);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
initialization
|
|
RegisterDrawer(TCDWin7.Create, dsWindows7);
|
|
win7button := TSliceScaling.CreateWithResource('windows7_button', 6, 6, 6);
|
|
win7button.UseNativeStretch := False;
|
|
|
|
finalization
|
|
win7button.Free;
|
|
|
|
end.
|