355 lines
11 KiB
ObjectPascal

{ TPoweredby Component
Copyright (C)2014 Gordon Bamber minesadorada@charcodelvalle.com
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version with the following modification:
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent modules,and
to copy and distribute the resulting executable under terms of your choice,
provided that you also meet, for each linked independent module, the terms
and conditions of the license of that module. An independent module is a
module which is not derived from or based on this library. If you modify
this library, you may extend this exception to your version of the library,
but you are not obligated to do so. If you do not wish to do so, delete this
exception statement from your version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
for more details.
You should have received a copy of the GNU Library General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
}
unit uPoweredby;
{$mode objfpc}{$H+}
interface
uses
{$IFDEF WINDOWS}Windows, JwaWindows,{$ENDIF}Classes, Controls, Dialogs,
Forms, Graphics, LResources, SysUtils,
ExtCtrls, InterfaceBase, LCLType, LCLVersion, AboutPoweredbyunit;
const
C_VERSIONSTRING = '1.0.4.0';
C_WIDGETSET_GTK = 'GTK widget set';
C_WIDGETSET_GTK2 = 'GTK 2 widget set';
C_WIDGETSET_GTK3 = 'GTK 3 widget set';
C_WIDGETSET_WIN = 'Win32/Win64 widget set';
C_WIDGETSET_WINCE = 'WinCE widget set';
C_WIDGETSET_CARBON = 'Carbon widget set';
C_WIDGETSET_QT = 'QT widget set';
C_WIDGETSET_fpGUI = 'fpGUI widget set';
C_WIDGETSET_COCOA = 'Cocoa widget set';
C_WIDGETSET_CUSTOM = 'Custom drawn widget set';
C_WIDGETSET_OTHER = 'Other gui';
type
TPoweredby = class(TAboutPoweredBy)
private
{ Private declarations }
fPoweredByForm: TForm;
fVersionString: string;
fDelayMilliseconds: integer;
fFadeInMilliseconds: integer;
fShowOnlyOnce, fAlreadyShown: boolean;
// Used by Timer to close the PoweredBy form
procedure ClosePoweredByForm(Sender: TObject);
// Windows only!
procedure FadeInPoweredBy(Sender: TObject);
procedure SetDelayMilliSeconds(AValue: integer);
function GetWidgetSetString: string;
function GetFPCTargetInfoString: string;
function GetInfoLCLVersion: string;
function GetInfoFPCVersion: string;
{$IFDEF WINDOWS}
procedure MakeTransparentWindow(var AForm: TForm; var AImage: TImage);
{$ENDIF}
protected
{ Protected declarations }
public
{ Public declarations }
// Call the method 'ShowPoweredByForm' to show the shaped window
procedure ShowPoweredByForm;
// Called when component is dropped onto a form
constructor Create(AOwner: TComponent); override;
published
{ Published declarations }
// Minimum delay=1000msec; Maximum delay=10000msec. Fade-in time is automatically adjusted
property DelayMilliSecs: integer read fDelayMilliSeconds
write SetDelayMilliSeconds default 1000;
// Call the method 'ShowPoweredByForm' to show the shaped window
property Version: string read fVersionString;
// Reports the current WidgetSet
property InfoWidgetSet: string read GetWidgetSetString;
// Reports your current Environment
property InfoFPCTarget: string read GetFPCTargetInfoString;
// Reports your current Environment
property InfoFPCVersion: string read GetInfoFPCVersion;
// Reports your current Environment
property InfoLCLVersion: string read GetInfoLCLVersion;
// Useful if you have ShowPoweredByForm in your TForm.Activate() method
property ShowOnlyOnce: boolean read fShowOnlyOnce write fShowOnlyOnce default False;
end;
procedure Register;
implementation
uses {$IF (lcl_major > 0) and (lcl_minor > 6)}LCLPlatformDef {$ENDIF};
procedure Register;
begin
{$I upoweredby_icon.lrs}
RegisterComponents('Additional', [TPoweredby]);
end;
constructor TPoweredby.Create(AOwner: TComponent);
// Initialise private vars
begin
inherited Create(AOwner);
fVersionString := C_VERSIONSTRING;
fDelayMilliseconds := 1000;
fFadeInMilliseconds := 20;
fAlreadyShown := False;
fShowOnlyOnce := False;
// About dialog
AboutBoxComponentName := 'PoweredBy component';
AboutBoxWidth := 400;
// AboutBoxHeight (integer)
AboutBoxDescription := 'Component that shows a Powered By graphic.' +
LineEnding + 'Use method ShowPoweredByForm in your form.create()' +
LineEnding + 'to use the component';
AboutBoxBackgroundColor := clWindow;
AboutBoxFontName := 'Arial';
AboutBoxFontSize := 10;
AboutBoxVersion := C_VERSIONSTRING;
AboutBoxAuthorname := 'Gordon Bamber';
AboutBoxOrganisation := 'Public Domain';
AboutBoxAuthorEmail := 'minesadorada@charcodelvalle.com';
AboutBoxLicenseType := 'MODIFIEDGPL';
end;
function TPoweredby.GetInfoLCLVersion: string;
begin
Result := lcl_version;
end;
function TPoweredby.GetInfoFPCVersion: string;
begin
Result:={$I %FPCVERSION%};
end;
function TPoweredby.GetFPCTargetInfoString: string;
begin
Result := {$I %FPCTARGETCPU%}+' - '+{$I %FPCTARGETOS%};
end;
function priv_GetWidgetSetString: string;
// This code cannot be a method of TPoweredBy
begin
case WidgetSet.LCLPlatform of
lpGtk: Result := C_WIDGETSET_GTK;
lpGtk2: Result := C_WIDGETSET_GTK2;
lpWin32: Result := C_WIDGETSET_WIN;
lpWinCE: Result := C_WIDGETSET_WINCE;
lpCarbon: Result := C_WIDGETSET_CARBON;
lpCocoa: Result := C_WIDGETSET_COCOA;
lpQT: Result := C_WIDGETSET_QT;
lpfpGUI: Result := C_WIDGETSET_fpGUI;
// When were these first included in InterfaceBase?
{$IFDEF FPC_FULLVERSION>24200}
lpGtk3: Result := C_WIDGETSET_GTK3;
lpCustomDrawn: Result := C_WIDGETSET_CUSTOM;
{$ENDIF}
else
Result := C_WIDGETSET_OTHER;
end;
end;
function TPoweredby.GetWidgetSetString: string;
begin
Result := priv_GetWidgetSetString;
end;
procedure TPoweredby.SetDelayMilliSeconds(AValue: integer);
begin
if ((fDelayMilliSeconds <> AValue) and (AValue > 0) and (AValue < 11000)) then
begin
fDelayMilliseconds := AValue;
fFadeInMilliseconds := (AValue div 1000) * 20;
end;
end;
procedure TPoweredby.ClosePoweredByForm(Sender: TObject);
// Called by Timer event in ShowPoweredByForm to close Modal window
// Also the image OnClick event
begin
fPoweredByForm.Close;
end;
procedure TPoweredby.FadeInPoweredBy(Sender: TObject);
// Use Alphablend property of TForm
begin
if (fPoweredByForm.AlphaBlendValue < 245) then
fPoweredByForm.AlphaBlendValue := fPoweredByForm.AlphaBlendValue + 10;
end;
function CanShowRoundedGraphic: boolean;
{
Check the current WidgetSet, and add to the list that can show the rounded graphic
Choices are:
lpGtk,
lpGtk2,
lpGtk3,
lpWin32,
lpWinCE,
lpCarbon,
lpQT,
lpfpGUI,
lpNoGUI,
lpCocoa,
lpCustomDrawn
}
begin
Result := False;
case WidgetSet.LCLPlatform of
lpWin32, lpQT: Result := True;
else
Result := False;
end;
end;
{$IFDEF WINDOWS}
procedure TPoweredby.MakeTransparentWindow(var AForm: TForm; var AImage: TImage);
var
BlendFunction: TBlendFunction;
Size: TSize;
P: TPoint;
ExStyle: DWORD;
begin
with AForm do
begin
ExStyle := GetWindowLongA(Handle, GWL_EXSTYLE);
if (ExStyle and WS_EX_LAYERED = 0) then
SetWindowLong(Handle, GWL_EXSTYLE, ExStyle or WS_EX_LAYERED);
ClientWidth := AImage.picture.Bitmap.Width;
ClientHeight := AImage.picture.Bitmap.Height;
P.x := 0;
P.y := 0;
Size.cx := AImage.picture.Bitmap.Width;
Size.cy := AImage.picture.Bitmap.Height;
BlendFunction.BlendOp := AC_SRC_OVER;
BlendFunction.BlendFlags := 0;
BlendFunction.SourceConstantAlpha := 255;
BlendFunction.AlphaFormat := AC_SRC_ALPHA;
UpdateLayeredWindow(Handle, 0, nil, @Size, AImage.picture.Bitmap.Canvas.Handle,
@P, 0, @BlendFunction, ULW_ALPHA);
end;
end;
{$ENDIF}
procedure TPoweredby.ShowPoweredByForm;
// Graphics are in graphics.lrs
// 1 ) Constructs a new TForm with an image control
// 2 ) Sets a timer to fade it in using the Alphablend property
// 3 ) Sets another timer to close the form
// Note: Windows can fade in a shaped transparent screen
// But some widgetsets (GTK,Carbon) cannot
var
img_Background: TImage;
DelayTimer: TTimer;
FadeInTimer: TTImer;
begin
// Respect the ShowOnlyOnce property setting
if ((fShowOnlyOnce = True) and (fAlreadyShown = True)) then
Exit;
// Try..Finally so we can be sure resources are Freed
try
try
// Create controls
fPoweredByForm := TForm.Create(nil);
fPoweredByForm.AlphaBlend := True;
fPoweredByForm.AlphaBlendValue := 0;
img_background := TImage.Create(fPoweredByForm);
// Delay Timer
Delaytimer := TTimer.Create(fPoweredByForm);
delaytimer.Interval := fDelayMilliseconds;
delaytimer.OnTimer := @ClosePoweredByForm;
FadeInTimer := TTimer.Create(fPoweredByForm);
FadeInTimer.Interval := fFadeInMilliseconds;
FadeInTimer.OnTimer := @FadeInPoweredBy;
// BackGround image - load from resource
with img_background do
begin
Align := alClient;
Stretch := True;
Parent := fPoweredByForm;
if CanShowRoundedGraphic then
Picture.LoadFromLazarusResource('powered_by_graphic')
else
Picture.LoadFromLazarusResource('linux_powered_by_graphic');
OnClick := @ClosePoweredByForm;
SendToBack;
end;
// Set form properties
with fPoweredByForm do
begin
position := poScreenCenter;
borderstyle := bsnone;
bordericons:=[];
formstyle := fsSystemStayOnTop;
OnClick := @ClosePoweredByForm;
color := clNone;
Scaled:=True;
if CanShowRoundedGraphic then
begin
MakeTransparentWindow(fPoweredByForm,img_background);
end
else
begin
// If square graphic, then adjust form size
Height := img_background.Picture.Height;
Width := img_background.picture.Width;
end;
// Now show the completed form
delaytimer.Enabled := True;
FadeInTimer.Enabled := True;
Application.ProcessMessages;
ShowModal; // Closed via the Timer event or a user click
fAlreadyShown := True;
end;
except
On E: Exception do
raise Exception.CreateFmt('%s Error: %s', [Name, Exception.ClassName]);
end;
finally
FreeAndNil(img_background);
FreeAndNil(delayTimer);
FreeAndNil(FadeInTimer);
FreeAndNil(fPoweredByForm);
end;
end;
initialization
// Load graphics as lazarus resources into the component
{$I graphics.lrs}
end.