(************************************************************************
*    This File is Part of the AHM Triton Tools                          *
*    for Borland Delphi and C++ Builder.                                *
*************************************************************************
* Copyright © 1995-1999 Alexander H. Mehlhorn (AHM) and Tritontools.com *
* All Rights reserved.                                                  *
*                                                                       *
*    For more Information contact us at                                 *
*    E-Mail : support@tritontools.com                                   *
*    URL : http://www.tritontools.com                                   *
*                                                                       *
*    AHM is copyright by Alexander H. Mehlhorn                          *
*    All Parts of this Collection were developed,                       *
*    designed and implemented by AHM                                    *
*                                                                       *
*    Under no Circumstances may you distribute this file                *
*    in this or any other format. This File is supplied                 *
*    as Evaluation of Source only. No Delphi Components may be developed*
*    using extracts or subsets of this code without expressed permission*
*    by AHM.                                                            *
*                                                                       *
*************************************************************************)
unit AHMTFormManager;
interface
{$I AHM.INC}
uses Dialogs,SysUtils,Messages,Classes,Controls,Windows,Graphics,AHMSystemClass,ShellApi,Menus,AHMTStoreData,Forms,Extctrls,AHMSystemConst,AHMTHookClass;

type
  TAHMFormManager = class;
  TAHMFormFillStyle = (Circle, Horizontal, Vertical, LeftBottom, RoundMiddle, SquareMiddle, Spectral,
                   DoppelFlash, Singleflash, MiddleHBar, MiddleVBar, VerticalDoppelBar, HorizontalDoppelBar);
  TAHMFormImageStyle = (isTile,isCenter,isStretched);
  TAHMFormGradient = class(TGraphicsObject)
  private
     FFillstyle : TAHMFormFillStyle;
     FBeginColor,FEndcolor : TColor;
     FColorCount : Integer;
     FColorStrings : TStrings;
     Procedure SetColorStrings(value : TStrings);
     Procedure SetStyle(value : TAHMFormFillStyle);
     Procedure SetBeginColor(value : TColor);
     Procedure SetEndColor(value : TColor);
     Procedure SetColorCount(Value : Integer);
  protected
  public
    constructor Create; virtual;
    Destructor Destroy; override;
    Procedure MultiDraw(const Cdc:HDC;iWidth,iHeight : Integer;CStrings : TStrings;NoGrad:TColor;Norm : Boolean);
  published
    Property BeginColor : TColor read FBeginColor write SetBeginColor default clbtnShadow;
    Property EndColor : TColor read FEndColor write SetEndColor default clBtnHighlight;
    Property FillStyle : TAHMFormFillstyle read FFillstyle write SetStyle default Horizontal;
    Property ColorCount : Integer read FColorCount write SetColorCount default 32;
    Property ColorsInBetween : TStrings read fColorStrings write SetColorStrings;
  end;
  TAHMFormTexture = class(TGraphicsObject)
  private
     FImage : TBitmap;
     FImageStyle : TAHMFormImageStyle;
     FTransparentColor : TColor;
     FTransparentBackground : TColor;
     Procedure SetTransparentColor(Value : TColor);
     Procedure SetTransparentBackground(Value : TColor);
     Procedure SetImage(Value : TBitmap);
     Procedure SetImageStyle(value : TAHMFormImageStyle);
  protected
  public
    Constructor Create; virtual;
    Destructor Destroy; override;
    Procedure Draw(const Cdc : HDC;Width,Height : Integer;Noimg : TColor);
  published
    Property Image : TBitmap read FImage write SetImage;
    Property ImageStyle : TAHMFormImageStyle read FImageStyle write SetImageStyle default isTile;
    Property TransparentColor : TColor read FTransparentColor write SetTransparentColor default clNone;
    Property TransparentBackground : TColor read FTransparentBackground write SetTransparentBackground default clbtnface;
  end;
  TAHMFormBrushFill = class(TGraphicsObject)
  private
     FBrushStyle:TBrushStyle;
     FBrushColor:TColor;
     Procedure SetBrushStyle(value : TBrushStyle);
     Procedure SetBrushColor(value : TColor);
  protected
  public
    Constructor Create; virtual;
  published
    Property BrushStyle : TBrushStyle read FBrushStyle write SetBrushStyle default bsSolid;
    Property BrushColor : TColor read FBrushColor write SetBrushColor default clbtnFace;
  end;
  TAHMFormBackStyle  = (bNormal,bGradient,bTexture,bBrushFillUseCurrent,bBrushFillFormColor);
  TAHMFormBackground = class(TPersistent)
  private
     FTexture    : TAHMFormTexture;
     FBrushFill  : TAHMFormBrushFill;
     FBackStyle  : TAHMFormBackStyle;
     FOnchanged  : TNotifyevent;
     FGradient   : TAHMFormGradient;
     FFormManager : TAHMFormManager;
     procedure SetTexture(value : TAHMFormTexture);
     procedure SetGradient(value : TAHMFormGradient);
     procedure SetBrushFill(value : TAHMFormBrushFill);
     procedure SetBackStyle(value : TAHMFormBackStyle);
     procedure BackChange(Sender : TObject);
  protected
  public
    constructor Create(AOwner : TAHMFormManager); virtual;
    destructor Destroy; override;
    Function Draw(DC : HDC;fWidth,fHeight : Integer;Norm:Boolean) : Boolean;
    procedure DrawTrans(Canvas : TCanvas;Width,Height : Integer;Norm:Boolean;TRC:TColor);
  published
    Property Texture         : TAHMFormTexture read FTexture write SetTexture;
    Property Gradient        : TAHMFormGradient read FGradient write SetGradient;
    Property BrushFill       : TAHMFormBrushFill read FBrushfill write SetBrushFill;
    Property OnChanged       : TNotifyevent read FOnChanged write FOnChanged;
    Property BackgroundStyle : TAHMFormBackStyle read FBackstyle write SetBackStyle default bNormal;
  end;
  TAHMFormProperties = (dsgnPreview,wsDlgFrame,wsThickframe,wsBorder,wsCaption,wsMinimizeBox,wsMaximizeBox,wsSysMenu,wsexAppWindow,
                        wsexClientEdge,wsexDlgModalFrame,wsexStaticEdge,wsexToolwindow,wsexContextHelp,wsexTransparent,wsexAcceptFiles);
  TAHMFormPropertySet = Set of TAHMFormProperties;
  TAHMFormGetConstraints = procedure(Sender:TObject;var MinWidth,MaxWidth,MinHeight,MaxHeight : LongInt) of object;
  TAHMOnFormDropFile=procedure(Sender:TObject;X,Y : Integer;Files : TStringlist;FileCount : Longint) of object;
  TAHMFormGetFile=procedure(Sender:TObject;FileAndPath : String) of object;
  TAHMFormOnSysMemLow = procedure(Sender : TObject;CompactRatio : LongInt) of Object;
  TAHMFormConstraints = class(TGraphicsObject)
  private
    FMaxWidth: LongInt;
    FMinWidth: LongInt;
    FMaxHeight: LongInt;
    FMinHeight: LongInt;
    procedure SetMaxHeight(const Value: LongInt);
    procedure SetMaxWidth(const Value: LongInt);
    procedure SetMinHeight(const Value: LongInt);
    procedure SetMinWidth(const Value: LongInt);
  protected
  public
  published
    property MinWidth : LongInt read FMinWidth write SetMinWidth default 0;
    property MinHeight : LongInt read FMinHeight write SetMinHeight default 0;
    property MaxWidth : LongInt read FMaxWidth write SetMaxWidth default 0;
    property MaxHeight : LongInt read FMaxHeight write SetMaxHeight default 0;
  end;
  TAHMFormStore  = class(TPersistent)
  private
    FState: Boolean;
    FVisible: Boolean;
    FSize: Boolean;
    FLocation: Boolean;
    FStoreKey: String;
    FStore: TAHMStoreData;
    FormManager : TAHMFormManager;
    procedure SetLocation(const Value: Boolean);
    procedure SetSize(const Value: Boolean);
    procedure SetState(const Value: Boolean);
    procedure SetStoreKey(const Value: String);
    procedure SetVisible(const Value: Boolean);
    procedure SetStore(const Value: TAHMStoreData);
  protected
    Procedure SaveToStore;
    Procedure LoadFromStore;
  public
    constructor Create(AOwner : TAHMFormManager);
    Destructor Destroy; override;
  published
    property Store : TAHMStoreData read FStore write SetStore;
    property StoreKey : String read FStoreKey write SetStoreKey;
    property Size : Boolean read FSize write SetSize default False;
    property Location : Boolean read FLocation write SetLocation default False;
    property State : Boolean read FState write SetState default false;
    property Visible : Boolean read FVisible write SetVisible default false;
  end;
  TAHMCButtons = class;
  TAHMCButton = class(TCollectionItem)
  private
    FAHMFormManager : TAHMFormManager;
    FDestroy : Boolean;
    FButtonRect : TRect;
    FPressed : Boolean;
    FDrawPressed : Boolean;
    FVisible: Boolean;
    FEnabled: Boolean;
    FWidth: Integer;
    FCaption: String;
    FFont: TFont;
    FOnClick: TNotifyEvent;
    FColor: TColor;
    FPopupMenu: TPopupMenu;
    WMViS : Boolean;
    procedure SetCaption(const Value: String);
    procedure SetEnabled(const Value: Boolean);
    procedure SetVisible(const Value: Boolean);
    procedure SetWidth(const Value: Integer);
    function GetBorder: DWord;
    function GetBorderEx: DWord;
    procedure Paint;
    procedure CalcArea;
    procedure OnFontChange(Sender: TObject);
    procedure SetColor(const Value: TColor);
    procedure SetPopupMenu(const Value: TPopupMenu);
  protected
    OFVisible : Boolean;
    function GetDisplayName: string; override;
    procedure Click; virtual;
  public
    constructor Create(Collection: TCollection); override;
    procedure Assign(Source: TPersistent); override;
    property Owner : TAHMFormManager read FAHMFormManager;
    property DisplayName : String read GetDisplayName;

    destructor Destroy; override;
  published
    property Color : TColor read FColor write SetColor default clbtnFace;
    property DropDownmenu : TPopupMenu read FPopupMenu write SetPopupMenu;
    property Width : Integer read FWidth write SetWidth default 0;
    property Enabled : Boolean read FEnabled write SetEnabled default True;
    property Visible : Boolean read FVisible write SetVisible default True;
    property Caption : String read FCaption write SetCaption stored True;
    property Font : TFont read FFont write FFont;
    property OnClick : TNotifyEvent read FOnClick write FOnClick;
  end;
  TAHMCButtons = class(TCollection)
  private
    FAHMFormManager : TAHMFormManager;
    function GetAHMCButtons(Index: Integer): TAHMCButton;
    procedure SetAHMCButtons(Index: Integer; Value: TAHMCButton);
  protected
    function GetOwner : TPersistent; override;
  public
    constructor Create(AOwner: TAHMFormManager);
    function Add : TAHMCButtons;
   Function Delete(Index :Integer) :Boolean;
    property Owner : TAHMFormManager read FAHMFormManager;
    property Items[Index: Integer]: TAHMCButton
             read GetAHMCButtons write SetAHMCButtons; default;
  end;
  TAHMFormMessage = procedure(Sender : TObject; var WndMessage : TMessage) of object;
  TAHMFormManager = class(TAHMSystemsComponent)
  private
    FMdiHandle : THandle;
    FMessage : TAHMFormMessage;
    FTopMost: Boolean;
    FFormProperties : TAHMFormPropertySet;
    FConstraints: TAHMFormConstraints;
    FOnGetConstraints: TAHMFormGetConstraints;
    FOnSysMemLow: TAHMFormOnSysMemLow;
    FOnDropFiles: TAHMOnFormDropFile;
    FOnEachDroppedFile: TAHMFormGetFile;
    FOnMove: TNotifyevent;
    FFormStore: TAHMFormStore;
    FParent: TCustomPanel;
    FOnSysNextWindow: TNotifyevent;
    FOnSysMaximize: TNotifyEvent;
    FOnSysPrevWindow: Tnotifyevent;
    FOnSysDefault: TNotifyEvent;
    FOnSysContextHelp: TNotifyevent;
    FOnSysMove: TNotifyEvent;
    FOnSysTaskList: TNotifyevent;
    FOnSysClose: TNotifyEvent;
    FOnSysSize: TNotifyevent;
    FOnSysScreenSave: TNotifyevent;
    FOnSysREstore: TNotifyevent;
    FOnSysHotkey: TNotifyevent;
    FOnSysOther: TNotifyevent;
    FOnSysMinimize: TNotifyevent;
    FOnSysMonitorPower: TNotifyevent;
    FAHMFormBackGround: TAHMFormBackground;
    isWMSize : Boolean;
    FAHMCButtons : TAHMCButtons;
    FOwnerForm : TWinControl;
    FAlign : TAlign;
    FOwnerHookClass : TAHMHookClass;
    FMDIHookClass : TAHMHookClass;
    Procedure Setalign(Const Value : TAlign);
    Procedure SetConstraints(Sender : TObject);
    procedure SetAHMCButtons(Value: TAHMCButtons);
    procedure SetTopMost(const Value: Boolean);
    function GetFormProperties: TAHMFormPropertySet;
    procedure SetFormProperties(const Value: TAHMFormPropertySet);
    procedure SetParent(const Value: TCustomPanel);
    Procedure OnBackChange(Sender : TObject);
    function GetOwnerHandle: Hwnd;
    function GetMDIHandle: Hwnd;
    procedure MDIHooked(var AHMMsg : TMessage;Var Handled : Boolean);
    procedure OwnerHooked(var AHMMsg : TMessage;Var Handled : Boolean);
    procedure ReloadMDIHook(Sender : TObject);
    procedure ReloadOwnerHook(Sender : TObject);
    procedure ResetProperties;
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    property OwnerHandle : Hwnd read GetOwnerHandle;
  public
    Constructor Create(AOwner : TComponent); override;
    Procedure Loaded; override;
    Destructor Destroy; override;
    Procedure Update;
    Procedure LoadStore;
    Procedure SaveStore;

  published
    property About;
    property Buttons: TAHMCButtons read FAHMCButtons write SetAHMCButtons;
    property Background : TAHMFormBackground read FAHMFormBackGround write FAHMFormBackGround;
    property FormStore : TAHMFormStore read FFormStore write FFormStore;
    property TopMost : Boolean read FTopMost write SetTopMost default False;
    property Constraints : TAHMFormConstraints read FConstraints write FConstraints;
    property Parent : TCustompanel read FParent write SetParent;
    property ParentAlign : TAlign read FAlign write SetAlign default alNone;
    property OnDropFiles : TAHMOnFormDropFile read FOnDropFiles write FOnDropFiles;
    property OnEachDroppedFile : TAHMFormGetFile read FOnEachDroppedFile write FOnEachDroppedFile;
    property OnSysMemLow : TAHMFormOnSysMemLow read FOnSysMemLow write FOnSysMemLow;
    property OnMessage : TAHMFormMessage read FMessage write FMessage;
    property OnGetConstraints : TAHMFormGetConstraints read FOnGetConstraints write FOnGetConstraints;
    property OnMove : TNotifyevent read FOnMove write FOnMove;
    property OnSysClose : TNotifyEvent read FOnSysClose write FOnSysClose;
    property OnSysMove : TNotifyEvent read FOnSysMove write FOnSysMove;
    property OnSysMaximize : TNotifyEvent read FOnSysMaximize write FOnSysMaximize;
    property OnSysMinimize : TNotifyevent read FOnSysMinimize write FOnSysMinimize;
    property OnSysHotkey : TNotifyevent read FOnSysHotkey write FOnSysHotKey;
    property OnSysContextHelp : TNotifyevent read FOnSysContextHelp write FOnSysContextHelp;
    property OnSysDefault : TNotifyEvent read FOnSysDefault write FOnSysDefault;
    property OnSysMonitorPower : TNotifyevent read FOnSysMonitorPower write FOnSysMonitorPower;
    property OnSysNextWindow : TNotifyevent read FOnSysNextWindow write FOnSysNextWindow;
    property OnSysPrevWindow : Tnotifyevent read FOnSysPrevWindow write FOnSysPrevWindow;
    property OnSysRestore : TNotifyevent read FOnSysREstore write FOnSysRestore;
    property OnSysScreenSave : TNotifyevent read FOnSysScreenSave write FOnSysScreenSave;
    property OnSysSize : TNotifyevent read FOnSysSize write FOnSysSize;
    property OnSysTasklist : TNotifyevent read FOnSysTaskList write FOnSysTasklist;
    property OnSysOther : TNotifyevent read FOnSysOther write FOnSysOther;
    property Properties : TAHMFormPropertySet read FFormProperties write SetFormProperties default [wsDlgFrame, wsThickframe, wsBorder, wsCaption, wsMinimizeBox, wsMaximizeBox, wsSysMenu];
  end;

implementation

constructor TAHMCButton.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  FAHMFormManager :=(((Collection as TAHMCButtons).GetOwner) as TAHMFormManager);
  FVisible:=True;
  FWidth:=0;
  FEnabled:=True;
  FDestroy:=False;
  FColor:=clbtnface;
  FFOnt:=TFont.Create;
  FFont.OnChange:=OnFontChange;
  if not(csLoading in FAHMFormManager.Componentstate) then
  SetWindowPos(FAHMFormManager.OwnerHandle, 0, 0,0,0,0, SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
end;

Destructor TAHMCButton.Destroy;
Var MFormMan : TAHMFormManager;
begin
  FDestroy:=true;
  FFont.OnChange:=nil;
  FFont.Free;
  MFormMan:=FAHMFormManager;
  inherited Destroy;
  if not(csDestroying in MFormMan.Componentstate) then
  SetWindowPos(MFormMan.OwnerHandle, 0, 0,0,0,0, SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
end;

function TAHMCButton.GetDisplayName: string;
begin
  Result := inherited GetDisplayName;
end;

procedure TAHMCButton.CalcArea;
var x1,y1,x2,y2,x3: Integer;
begin
  if ((GetBorderEx and WS_EX_TOOLWINDOW)=WS_EX_TOOLWINDOW) then
  begin
    if ((GetBorder and WS_THICKFRAME)=WS_THICKFRAME) then
      x2 := GetSystemMetrics(SM_CXSIZEFRAME) + 2 else
      x2 := GetSystemMetrics(SM_CXFIXEDFRAME) + 2;
    if ((GetBorder and WS_SYSMENU)=WS_SYSMENU) then
      Inc(x2, GetSystemMetrics(SM_CXSMSIZE) + 2);
    if ((GetBorder and WS_THICKFRAME)=WS_THICKFRAME) then
      y1 := GetSystemMetrics(SM_CYSIZEFRAME) + 2 else
      y1 := GetSystemMetrics(SM_CYFIXEDFRAME) + 2;
    if ((GetBorderEx and WS_EX_STATICEDGE)=WS_EX_STATICEDGE) and not((GetBorderEx and WS_EX_DLGMODALFRAME)=WS_EX_DLGMODALFRAME) then
    begin
      Dec(X2,1); Dec(Y1,1);
    end;
    y2 := y1 + GetSystemMetrics(SM_CYSMSIZE) - 4;
    x2 :=FAHMFormManager.FOwnerForm.Width - x2;
    x1 := x2 - GetSystemMetrics(SM_CXSMSIZE)+2;
  end else
  begin
    if ((GetBorder and WS_THICKFRAME)=WS_THICKFRAME) then
       x2 := GetSystemMetrics(SM_CXSIZEFRAME)  else
       x2 := GetSystemMetrics(SM_CXFIXEDFRAME) ;
    if ((GetBorder and WS_SYSMENU)=WS_SYSMENU) then
    begin
      Inc(x2, GetSystemMetrics(SM_CXSIZE));
       if (((GetBorder and WS_MAXIMIZEBOX)=WS_MAXIMIZEBOX) or ((GetBorder and WS_MINIMIZEBOX)=WS_MINIMIZEBOX)) then
         Inc(x2, GetSystemMetrics(SM_CXSIZE)*2-2) else
       if ((GetBorderEx and WS_EX_CONTEXTHELP)=WS_EX_CONTEXTHELP) then Inc(x2, GetSystemMetrics(SM_CXSIZE)-2);
    end;
    if ((GetBorder and WS_THICKFRAME)=WS_THICKFRAME) then
        y1 := GetSystemMetrics(SM_CYSIZEFRAME) + 2 else
        y1 := GetSystemMetrics(SM_CYFIXEDFRAME) + 2;
    if ((GetBorderEx and WS_EX_STATICEDGE)=WS_EX_STATICEDGE) and not((GetBorderEx and WS_EX_DLGMODALFRAME)=WS_EX_DLGMODALFRAME) then
    begin
      Dec(X2,1); Dec(Y1,1);
    end;
    y2 := y1 + GetSystemMetrics(SM_CYSIZE) - 4;
    x2 := FAHMFormManager.FOwnerForm.Width - x2;
    x1 := x2 - GetSystemMetrics(SM_CXSIZE)+2;
  end;
  x3:=(x2-x1)*((1)-1);
  if Index>0 then
  begin
    x3:=x3-2;
    SetRect(FButtonRect, FAHMFormManager.Buttons[Index-1].FButtonRect.Left- GetSystemMetrics(SM_CXSIZE)-x3-3-FWidth,
                         y1, FAHMFormManager.Buttons[Index-1].FButtonRect.Left-x3-3, y2);
  end else
  begin
    SetRect(FButtonRect, x1-x3-3-FWidth, y1, x2-x3-3, y2);
  end;
end;


procedure TAHMCButton.Paint;
var FButtonHandle: HDC;
    UButtonRect : TRect;
    st: UINT;
    FCanvas : TCanvas;
begin
  if not(csLoading in FAHMFormManager.componentstate) then
  if (((GetBorder and WS_DLGFRAME)=WS_DLGFRAME) and ((GetBorder and WS_BORDER)=WS_BORDER))
    and not(WMVIS) then
  begin
    UButtonRect:=FButtonRect;
    FButtonHandle := GetWindowDC(FAHMFormManager.OwnerHandle);
    if (FVisible) and (UButtonRect.Left>4) then
    begin
      if FDrawPressed then st := DFCS_PUSHED else st := 0;
      DrawFrameControl(FButtonHandle,UButtonRect, DFC_BUTTON, DFCS_BUTTONPUSH or st );
      InflateRect(UButtonRect,-2,-2);
      FCanvas:=TCanvas.Create;
      with FCanvas do
      try
        Handle:=FButtonHandle;
        FFont.Size:=Round(GetSystemMetrics(SM_CXSIZE)/2);
        Font:=FFont;
        FCanvas.Brush.Style:=bsSolid;
        FCanvas.Brush.Color:=FColor;
        FCanvas.FillRect(UButtonRect);
        InflateRect(UButtonRect,1,1);
        SetBkMode(Handle,TRANSPARENT);
        OffsetRect(UButtonRect,2,0);
        if not(FDrawPressed) then offsetRect(UButtonRect,-1,-1);
        if FEnabled then
          DrawText(FCanvas.Handle,PChar(FCaption),Length(FCaption),UButtonRect,DT_VCENTER or DT_CENTER or DT_SINGLELINE)
        else begin
          offsetRect(UButtonRect,1,1);
          InflateRect(UButtonRect,0,-1);
          Font.Color:=clWhite;
          DrawText(FCanvas.Handle,PChar(FCaption),Length(FCaption),UButtonRect,DT_VCENTER or DT_CENTER or DT_SINGLELINE);
          offsetRect(UButtonRect,-1,-1);
          InflateRect(UButtonRect,0,1);
          Font.Color:=clgray;
          DrawText(FCanvas.Handle,PChar(FCaption),Length(FCaption),UButtonRect,DT_VCENTER or DT_CENTER or DT_SINGLELINE);
        end;
      finally
        free;
      end;
    end
  end;
end;

procedure TAHMCButton.OnFontChange(Sender: TObject);
begin
  FFont.Size:=Round(GetSystemMetrics(SM_CXSIZE)/2);
  if not(csLoading in FAHMFormManager.Componentstate) then  
  SetWindowPos(FAHMFormManager.OwnerHandle, 0, 0,0,0,0, SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
end;

function TAHMCButton.GetBorder: DWord;
begin
  result:=GetWindowLong(FAHMFormManager.OwnerHandle, GWL_STYLE);
end;

function TAHMCButton.GetBorderEx: DWord;
begin
  result:=GetWindowLong(FAHMFormManager.OwnerHandle, GWL_EXSTYLE);
end;

function TAHMCButtons.GetOwner: TPersistent;
begin
  Result := FAHMFormManager;
end;

procedure TAHMCButton.Assign(Source: TPersistent);
begin
  if Source is TAHMCButton then
  begin
    FColor := TAHMCButton(Source).FColor;
    if TAHMCButton(Source).FPopupMenu<>nil then
    FPopupMenu := TAHMCButton(Source).FPopupMenu;
    FWidth:= TAHMCButton(Source).Width;
    FEnabled:= TAHMCButton(Source).FEnabled;
    FVisible:= TAHMCButton(Source).FVisible;
    FCaption:= TAHMCButton(Source).FCaption;
    FFont.Name:=TAHMCButton(Source).FFont.Name;
    FFont.Style:=TAHMCButton(Source).FFont.Style;
    FFont.Color:=TAHMCButton(Source).FFont.Color;
    FOnClick:= TAHMCButton(Source).FOnClick;
    CalcArea;
    Exit;
  end;
  inherited Assign(Source);
end;

constructor TAHMCButtons.Create(AOwner: TAHMFormManager);
begin
  inherited Create(TAHMCButton);
  FAHMFormManager := AOwner;
end;

function TAHMCButtons.Add: TAHMCButtons;
begin
  Result := TAHMCButtons(inherited Add);
end;

function TAHMCButtons.GetAHMCButtons(Index: Integer): TAHMCButton;
begin
  Result := TAHMCButton(inherited GetItem(Index));
end;

procedure TAHMCButtons.SetAHMCButtons(Index: Integer; Value: TAHMCButton);
begin
  inherited SetItem(Index, Value);
end;

function TAHMCButtons.Delete(Index: Integer): Boolean;
begin
  result := true;
  try
    Items[Index].free;
  except
    result := false;
    Application.HandleException(self);
  end;
end;

procedure TAHMCButton.SetCaption(const Value: String);
begin
  FCaption := Value;
  if not(csLoading in FAHMFormManager.Componentstate) then
  FWidth:=TCustomForm(FAHMFormManager.FOwnerForm).Canvas.TextWidth(FCaption)+2;
  if not(csLoading in FAHMFormManager.Componentstate) then
  SetWindowPos(FAHMFormManager.OwnerHandle, 0, 0,0,0,0, SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
end;

procedure TAHMCButton.SetEnabled(const Value: Boolean);
begin
  FEnabled := Value;
  if not(csLoading in FAHMFormManager.Componentstate) then
  SetWindowPos(FAHMFormManager.OwnerHandle, 0, 0,0,0,0, SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
end;

procedure TAHMCButton.SetVisible(const Value: Boolean);
begin
  FVisible := Value;
  if not(csLoading in FAHMFormManager.Componentstate) then
  SetWindowPos(FAHMFormManager.OwnerHandle, 0, 0,0,0,0, SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
end;

procedure TAHMCButton.SetWidth(const Value: Integer);
begin
  if Value>-1 then
  FWidth := Value;
  if not(csLoading in FAHMFormManager.Componentstate) then
  SetWindowPos(FAHMFormManager.OwnerHandle, 0, 0,0,0,0, SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
end;

procedure TAHMCButton.SetColor(const Value: TColor);
begin
  FColor := Value;
  if not(csLoading in FAHMFormManager.Componentstate) then
  SetWindowPos(FAHMFormManager.OwnerHandle, 0, 0,0,0,0, SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
end;

procedure TAHMCButton.Click;
begin
  if not(csdesigning in FAHMFormManager.Componentstate) then
    if assigned(FPopupMenu) and (FPopupMenu<>nil) then FPopupMenu.Popup(FAHMFormManager.FOwnerForm.Left+FButtonrect.Left,
                                                  FAHMFormManager.FOwnerForm.Top+FButtonRect.Bottom);
  if FEnabled and assigned(FOnClick) then FOnClick(self);
end;


procedure TAHMCButton.SetPopupMenu(const Value: TPopupMenu);
begin
  FPopupMenu := Value;
  if Value <> nil then Value.FreeNotification(FAHMFormManager);
end;

constructor TAHMFormManager.Create(AOwner: TComponent);
Var I : Integer;
begin
  inherited Create(AOwner);
  if (AOwner is TWinControl) then
  begin
    FOwnerForm := (AOwner) as TWinControl;
    FMdiHandle:=GetMDIHandle;
  end else FOwnerForm:=nil;
  FAHMCButtons:=TAHMCButtons.Create(self);
  isWMSize:=False;
  FFormStore:=TAHMFormStore.Create(Self);
  FConstraints := TAHMFormConstraints.Create;
  FConstraints.OnChange:=SetConstraints;
  FFormProperties:=GetFormProperties;
  FAHMFormBackground:=TAHMFormBackground.Create(self);
  FAHMFormBackground.OnChanged:=OnBackchange;
  FOwnerHookClass:=TAHMHookClass(HookList.Add(Self,AOwner,False));
  FMDIHookClass:=TAHMHookClass(HookList.Add(Self,AOwner,True));
  FMDIHookClass.Beforemessage:=MDIHooked;
  FOwnerHookClass.Beforemessage:=OwnerHooked;
  FOwnerHookClass.OnReloadHook:=ReloadOwnerHook;
  FMDIHookClass.OnReloadHook:=ReloadMDIHook;
  if (AOwner is TWinControl) then
  begin
    for I:=0 to FOwnerForm.ComponentCount-1 do
    if ((FOwnerForm.Components[I] is TAHMFormManager) and (FOwnerForm.Components[I] <>self) ) then
      raise EAHMDuplicateError.Create(ahmscsystemduplicate1+#13#10+self.classname+ahmscsystemduplicate2+#13#10+ahmscsystemduplicate4);
  end else raise EAHMOwnerFormNeeded.Create(self.ClassName+ahmscownerform);
end;

procedure TAHMFormManager.Loaded;
begin
  inherited Loaded;
  if assigned(FFormStore.FStore) then
  if FFormStore.FStore.ReadStr(FFormStore.FStoreKey,'')=FFormStore.FStoreKey then FFormStore.LoadFromStore;
  SetFormProperties(FFormProperties);
end;

procedure TAHMFormManager.SetAHMCButtons(Value: TAHMCButtons);
begin
  FAHMCButtons.Assign(Value);
end;

destructor TAHMFormManager.Destroy;
Var RHandle : Integer;
begin
  RHandle:=0;
  if (csDesigning in Componentstate) then ResetProperties;
  HookList.Remove(Self);
  if (FOwnerForm<>nil) and not(csDestroying in FOwnerForm.Componentstate) then
  begin
    FOwnerForm.Invalidate;
    RHandle:=FOwnerForm.Handle;
  end;
  if not(csdesigning in Componentstate) then SetTopMost(False);
  FAHMCButtons.Free;
  FFormStore.Free;
  FAHMFormBackground.OnChanged:=nil;
  FAHMFormBackground.Free;
  FConstraints.OnChange:=nil;
  FConstraints.Free;

  inherited Destroy;
  if (RHandle<>0) then SendMessage(RHandle,WM_ERASEBKGND,GETDC(RHandle),0);
end;

procedure TAHMFormManager.MDIHooked(var AHMMsg:TMessage;Var Handled : Boolean);
Var FFileCount,I : Integer;
    FFileList : TStringList;
    FDropPoint : TPoint;
    FBuffer : array[0..255] of Char;
    FStructSize : LongInt;
begin
  try
  if assigned(FMessage) then FMessage(self,AHMMsg);
  with AHMMsg do
  case Msg of
    WM_COMPACTING : if assigned(FOnSysMemLow) then FOnSysMemLow(self,Longint(wParam));
    WM_DROPFILES  :
    if not(csDesigning in Componentstate) and (wparam<>0) then
    begin
      FFileCount:=DragQueryFile(THandle(wparam), $FFFFFFFF, nil, 0);
      if FFileCount>0 then
      begin
        DragQueryPoint(THandle(wparam),FDropPoint);
        FFileList:=TStringList.Create;
        try
          for I:=0 to (FFileCount-1) do
          begin
            FStructSize:=DragQueryFile(THandle(wparam), i, nil, 0);
            if FStructSize<255 then
            begin
              DragQueryFile(THandle(wparam), I,FBuffer,FStructSize + 1);
              FFileList.Add(UPPERCASE(StrPas(FBuffer)));
            end;
          end;
          if assigned(FOnDropFiles) then
          FOnDropFiles(self,FDropPoint.X, FDropPoint.Y, FFileList,FFileCount);
          for I:=0 to FFileCount-1 do
            if assigned(FOnEachDroppedFile) then FOnEachDroppedFile(self,FFilelist[I]);
        finally
          FFileList.Free;
        end;
      end;
      Handled:=True;
    end;
    WM_MOVE :  if Assigned(FonMove) then FOnMove(self);
    WM_CLOSE :
    FFormStore.SaveToStore;
    WM_WINDOWPOSCHANGED,
    WM_SIZE :
    begin
      if (DsgnPreview in FFormProperties) or Not(csDesigning in Componentstate)
      and (Msg=WM_SIZE) and (FMDIHandle<>0) then InvalidateRect(FMDIHandle, nil, True);
    end;
    WM_HSCROLL,
    WM_VSCROLL :
       if FMDIHandle<>0 then InvalidateRect(FMDIHandle, nil, False);
    WM_PALETTECHANGED:
       if FMDIHandle<>0 then InvalidateRect(FMDIHandle, nil, True);
    WM_PAINT : Result:=1;
    WM_ERASEBKGND :
    begin
      if FAHMFormBackground.Draw(wparam,FOwnerForm.Width,FOwnerForm.Height,True) then
      begin
        Handled:=True;
        Result:=1;
      end;
    end;
  end;
  except
    Application.HandleException(self);
  end;
end;

procedure TAHMFormManager.OwnerHooked(var AHMMsg:TMessage;Var Handled : Boolean);
Var FFileCount,I : Integer;
    FFileList : TStringList;
    FDropPoint : TPoint;
    FBuffer : array[0..255] of Char;
    FStructSize : LongInt;
    DoDefault : Boolean;
function InButton(InClient: Boolean;Button : Integer): Boolean;
var p: TPoint;
begin
  p.x := Loword(AHMMsg.lParam);
  p.y := Smallint(Hiword(AHMMsg.lParam));
  if InClient then ClientToScreen(OwnerHandle, p );
  Dec( p.x, FOwnerForm.Left );
  Dec( p.y, FOwnerForm.Top );
  if Buttons[Button].FVisible then
  Result := PtInRect( Buttons[Button].FButtonRect, p )
  else Result:=False;
end;
begin
  try
  if assigned(FMessage) then FMessage(self,AHMMsg);
  with AHMMsg do
  case Msg of
    WM_COMPACTING : if assigned(FOnSysMemLow) then FOnSysMemLow(self,Longint(wParam));
    WM_DROPFILES  :
    if not(csDesigning in Componentstate) and (wparam<>0) then
    begin
      FFileCount:=DragQueryFile(THandle(wparam), $FFFFFFFF, nil, 0);
      if FFileCount>0 then
      begin
        DragQueryPoint(THandle(wparam),FDropPoint);
        FFileList:=TStringList.Create;
        try
          for I:=0 to (FFileCount-1) do
          begin
            FStructSize:=DragQueryFile(THandle(wparam), i, nil, 0);
            if FStructSize<255 then
            begin
              DragQueryFile(THandle(wparam), I,FBuffer,FStructSize + 1);
              FFileList.Add(UPPERCASE(StrPas(FBuffer)));
            end;
          end;
          if assigned(FOnDropFiles) then
          FOnDropFiles(self,FDropPoint.X, FDropPoint.Y, FFileList,FFileCount);
          for I:=0 to FFileCount-1 do
            if assigned(FOnEachDroppedFile) then FOnEachDroppedFile(self,FFilelist[I]);
        finally
          FFileList.Free;
        end;
      end;
      Handled:=True;
    end;
    WM_MOVE :  if Assigned(FonMove) then FOnMove(self);
    WM_CLOSE :
    FFormStore.SaveToStore;
    WM_WINDOWPOSCHANGED,
    WM_SIZE :
    begin
      if not(csDestroying in componentstate) then
      begin
        FOwnerHookClass.DefaultMessage(AHMMsg);
        for I:=0 to Buttons.Count-1 do with Buttons[I] do CalcArea;
        SendMessage(OwnerHandle,WM_NCPAINT,1,1);
        Handled:=True;
      end;
    end;
    WM_LBUTTONUP, WM_LBUTTONDBLCLK:
    begin
      for I:=0 to Buttons.Count-1 do
      with Buttons[I] do
      begin
        FDrawPressed := False;
        if FPressed then
        begin
          if InButton(True,I) then
          begin
            Click;
            Paint;
          end else if FEnabled then Paint;
          Result := 1;
        end;
      end;
      for I:=0 to Buttons.Count-1 do
      with Buttons[I] do FPressed := False;
      FOwnerHookClass.DefaultMessage(AHMMsg);
      ReleaseCapture;
      Handled:=True;
    end;
    WM_NCACTIVATE,WM_NCPAINT,WM_SETTINGCHANGE :
    begin
      FOwnerHookClass.DefaultMessage(AHMMsg);
      for I:=0 to Buttons.Count-1 do
      with Buttons[I] do
      begin
        CalcArea;
        Paint;
      end;
      Handled:=True;
    end;
    WM_NCMOUSEMOVE:
    begin
      begin
        DoDefault:=True;
        for I:=0 to Buttons.Count-1 do
        with Buttons[I] do
        begin
          if FPressed then
          begin
            DoDefault:=False;
            if not InButton( True,I ) then
            begin
              if FDrawPressed then
              begin
                FDrawPressed := False;
                if FEnabled then Paint;
              end;
            end else
            begin
              if not FDrawPressed then
              begin
                FDrawPressed := True;
                if FEnabled then Paint;
              end;
            end;
          end;
          Result:=1;
        end;
        if not(DoDefault) then FOwnerHookClass.DefaultMessage(AHMMsg)
        else Handled:=True;
      end;
    end;
    WM_NCLBUTTONDOWN, WM_NCLBUTTONDBLCLK:
    begin
      for I:=0 to Buttons.Count-1 do
      with Buttons[I] do
      if InButton( False,I ) then
      begin
        SetCapture(OwnerHandle);
        if FEnabled then
        begin
          FDrawPressed := True;
          FPressed := True;
          Paint;
        end;
        //Result:=1;
        Handled:=True;
      end;
    end;
    WM_SYSCOMMAND:
    if (FOwnerForm as TCustomForm).Active then
    begin
      case WParam and $FFF0 of
        SC_CLOSE : if assigned(FOnSysClose) then FOnSysClose(self);
        SC_CONTEXTHELP : if assigned(FOnSysContextHelp) then FOnSysContextHelp(self);
        SC_DEFAULT : if assigned(FOnSysDefault) then FOnSysDefault(self);
        SC_HOTKEY : if assigned(FOnSysHotKey) then FOnSysHotkey(self);
        SC_MAXIMIZE : if assigned(FOnSysMaximize) then FOnSysMaximize(self);
        SC_MINIMIZE : if assigned(FOnSysMinimize) then FOnSysMinimize(self);
        SC_MONITORPOWER : if assigned(FOnSysMonitorPower) then FOnSysMonitorPower(self);
        SC_MOVE : if assigned(FOnSysMove) then FOnSysMove(self);
        SC_NEXTWINDOW : if assigned(FOnSysNextWindow) then FOnSysNextWindow(self);
        SC_PREVWINDOW : if assigned(FOnSysPrevWindow) then FOnSysPrevWindow(self);
        SC_RESTORE : if assigned(FOnSysRestore) then FOnSysRestore(self);
        SC_SCREENSAVE : if assigned(FOnSysScreenSave) then FOnSysScreenSave(self);
        SC_SIZE : if assigned(FOnSysSize) then FOnSysSize(self);
        SC_TASKLIST : if assigned(FOnSystaskList) then FOnSysTaskList(self);
      else
        if assigned(FOnSysOther) then FOnSysOther(self);
      end;
    end;
    WM_GETMINMAXINFO :
    Begin
      With PMinMaxInfo(lParam)^ do
      Begin
        if assigned(FOnGetConstraints) then
           FOnGetConstraints(Self,FConstraints.FMinWidth,FConstraints.FMaxWidth,FConstraints.FMinHeight,FConstraints.FMaxHeight);
        if (FConstraints.FMinWidth>0) Then ptMinTrackSize.X := FConstraints.FMinWidth;
        if (FConstraints.FMaxWidth>0) Then ptMaxTrackSize.X := FConstraints.FMaxWidth;
        if (FConstraints.FMinHeight>0) Then ptMinTrackSize.Y := FConstraints.FMinHeight;
        if (FConstraints.FMaxHeight>0) Then ptMaxTrackSize.Y := FConstraints.FMaxHeight;
      end;
    end;
  end;
  except
    Application.HandleException(self);
  end;
end;

procedure TAHMFormManager.SetTopMost(const Value: Boolean);
begin
  FTopMost := Value;
  if not(csdesigning in ComponentState) then
  if (Owner is TForm) then
  begin
    if Value then
      SetWindowPos(OwnerHandle, HWND_TopMost, 0,0,0,0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE)
    else
      SetWindowPos(OwnerHandle, HWND_NOTopMost,0,0,0,0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
  end;
end;

{ TAHMFormConstraints }

procedure TAHMFormConstraints.SetMaxHeight(const Value: LongInt);
begin
  FMaxHeight := Value;
  Changed;
end;

procedure TAHMFormConstraints.SetMaxWidth(const Value: LongInt);
begin
  FMaxWidth := Value;
  Changed;
end;

procedure TAHMFormConstraints.SetMinHeight(const Value: LongInt);
begin
  FMinHeight := Value;
  Changed;
end;

procedure TAHMFormConstraints.SetMinWidth(const Value: LongInt);
begin
  FMinWidth := Value;
  Changed;
end;

procedure TAHMFormManager.SetConstraints(Sender: TObject);
begin
  Postmessage(OwnerHandle,WM_SIZE,0,0);
end;

{ TAHMFormStore }

constructor TAHMFormStore.Create(AOwner: TAHMFormmanager);
begin
  inherited Create;
  FormManager:=AOwner;
end;

destructor TAHMFormStore.Destroy;
begin
  inherited Destroy;
end;

procedure TAHMFormStore.LoadFromStore;
begin
  if not(csDesigning in FormManager.Componentstate) then
  if Assigned(FStore) then
  with FStore do
  begin
    if FSize then
    begin
      FormManager.FOwnerForm.Width:=ReadInt(FStoreKey+FormManager.FOwnerForm.Name+'_Width',FormManager.FOwnerForm.Width);
      FormManager.FOwnerForm.Height:=ReadInt(FStoreKey+FormManager.FOwnerForm.Name+'_Height',FormManager.FOwnerForm.Height);
    end;
    if FLocation then
    begin
      FormManager.FOwnerForm.Top:=ReadInt(FStoreKey+FormManager.FOwnerForm.Name+'_Top',FormManager.FOwnerForm.Top);
      FormManager.FOwnerForm.Left:=ReadInt(FStoreKey+FormManager.FOwnerForm.Name+'_Left',FormManager.FOwnerForm.Top);
    end;
    if FVisible then
     FormManager.FOwnerForm.Visible:=ReadBool(FStoreKey+FormManager.FOwnerForm.Name+'_Visible',FormManager.FOwnerForm.Visible);
    if FState then
    begin
      case ReadInt(FStoreKey+FormManager.FOwnerForm.Name+'_WindowState',Integer(TForm(FormManager.FOwnerForm).WindowState)+1) of
        1:TForm(FormManager.FOwnerForm).WindowState:=wsMinimized;
        2:TForm(FormManager.FOwnerForm).WindowState:=wsNormal;
        3:TForm(FormManager.FOwnerForm).WindowState:=wsMaximized;
      end;
    end;
  end;
end;

procedure TAHMFormStore.SaveToStore;
begin
  if not(csDesigning in FormManager.Componentstate) then
  if Assigned(FStore) then
  with FStore do
  begin
    if (FState and (TForm(FormManager.FOwnerForm).WindowState=wsNormal)) or not(FState) then
    if FSize then
    begin
      WriteInt(FStoreKey+FormManager.FOwnerForm.Name+'_Width',FormManager.FOwnerForm.Width);
      WriteInt(FStoreKey+FormManager.FOwnerForm.Name+'_Height',FormManager.FOwnerForm.Height);
    end;
    if FState and (TForm(FormManager.FOwnerForm).WindowState=wsNormal) or not(FState) then
    if FLocation then
    begin
      WriteInt(FStoreKey+FormManager.FOwnerForm.Name+'_Top',FormManager.FOwnerForm.Top);
      WriteInt(FStoreKey+FormManager.FOwnerForm.Name+'_Left',FormManager.FOwnerForm.Left);
    end;
    if FVisible then
    WriteBool(FStoreKey+FormManager.FOwnerForm.Name+'_Visible',FormManager.FOwnerForm.Visible);
    if FState then
    begin
      case TForm(FormManager.FOwnerForm).WindowState of
        wsMinimized : WriteInt(FStoreKey+FormManager.FOwnerForm.Name+'_WindowState', 1);
        wsNormal    : WriteInt(FStoreKey+FormManager.FOwnerForm.Name+'_WindowState', 2);
        wsMaximized : WriteInt(FStoreKey+FormManager.FOwnerForm.Name+'_WindowState', 3);
      end;
    end;
    WriteStr(FStorekey,FStoreKey);
  end;
end;

procedure TAHMFormStore.SetLocation(const Value: Boolean);
begin
  FLocation:=Value;
  if Value then SaveToStore;
end;

procedure TAHMFormStore.SetSize(const Value: Boolean);
begin
  FSize:=Value;
  if Value then SaveToStore;
end;

procedure TAHMFormStore.SetState(const Value: Boolean);
begin
  FState := Value;
  if Value then SaveToStore;
end;

procedure TAHMFormStore.SetStore(const Value: TAHMStoreData);
begin
  FStore := Value;
  if Value <> nil then Value.FreeNotification(FormManager);
end;

procedure TAHMFormStore.SetStoreKey(const Value: String);
begin
  FStoreKey := Value;
end;

procedure TAHMFormStore.SetVisible(const Value: Boolean);
begin
  FVisible := Value;
  if Value then SaveToStore;
end;

procedure TAHMFormManager.LoadStore;
begin
  FFormStore.LoadFromStore;
end;

procedure TAHMFormManager.Notification(AComponent: TComponent;
  Operation: TOperation);
Var I : Integer;
begin
  if Buttons<>nil then
  for I:=0 to Buttons.Count-1 do
  if Buttons[I].FPopupMenu<>nil then
  if (AComponent = Buttons[I].FPopupMenu) and (Operation = opRemove) then Buttons[I].FPopupMenu := nil;
  if FFormStore<>nil then
  if (AComponent=FFormStore.Store) and (Operation=opRemove) then
  begin
    FFormStore.SaveToStore;
    FFormStore.FStore:=nil;
  end;
  inherited Notification(AComponent, Operation);
  if (AComponent=FParent) and (Operation=opRemove) then FParent:=nil;
end;

procedure TAHMFormManager.SaveStore;
begin
  FFormStore.SaveToStore;
end;

function TAHMFormManager.GetFormProperties: TAHMFormPropertySet;
Var NStyle,NExStyle: LongInt;
    CHandle : THandle;
begin
  CHandle:=OwnerHandle;
  result:=[];
  NStyle:=GetWindowLong(CHandle, GWL_STYLE);
  NExStyle:=GetWindowLong(CHandle, GWL_EXSTYLE);
  if (NStyle and WS_DlgFrame)<>0 then Include(Result,wsDlgFrame);
  if (NStyle and WS_Thickframe)<>0 then Include(Result,wsThickframe);
  if (NStyle and WS_Caption)<>0 then Include(Result,wsCaption);
  if (NStyle and WS_Border)<>0 then Include(Result,wsBorder);
  if (NStyle and WS_MINIMIZEBOX)<>0 then Include(Result,wsMinimizebox);
  if (NStyle and WS_MAXIMIZEBOX)<>0 then Include(Result,wsMaximizebox);
  if (NStyle and WS_SYSMENU)<>0 then Include(Result,wsSysMenu);
  if (NExStyle and WS_EX_AppWindow)<>0 then Include(Result,wsexAppWindow);
  if (NExStyle and WS_EX_ClientEdge)<>0 then Include(Result,wsexClientEdge);
  if (NExStyle and WS_EX_ContextHelp)<>0 then Include(Result,wsexContextHelp);
  if (NExStyle and WS_EX_DlgModalFrame)<>0 then Include(Result,wsexDLGMODALFRAME);
  if (NExStyle and WS_EX_StaticEdge)<>0 then Include(Result,wsexStaticEdge);
  if (NExStyle and WS_EX_Toolwindow)<>0 then Include(Result,wsexToolwindow);
  if (NExStyle and WS_EX_Transparent)<>0 then Include(Result,wsexTransparent);
  if (NExStyle and WS_EX_AcceptFiles)<>0 then Include(Result,wsexAcceptFiles);
end;

procedure TAHMFormManager.SetFormProperties(
  const Value: TAHMFormPropertySet);
Var NStyle,NExStyle: LongInt;
    CHandle : THandle;
begin
  CHandle:=OwnerHandle;
  if (CHandle=0) then Exit;
  NStyle:=GetWindowLong(CHandle, GWL_STYLE);
  NExStyle:=GetWindowLong(CHandle, GWL_EXSTYLE);
  NExStyle:=NExStyle or WS_EX_CONTROLPARENT;
  if (wsCaption in Value) then NStyle:=NStyle or WS_Caption else NStyle:=NStyle and not WS_Caption;
  if (wsBorder in Value) then NStyle:=NStyle or WS_Border else NStyle:=NStyle and not WS_Border;
  if (wsDlgFrame in Value) then NStyle:=NStyle or WS_DlgFrame else NStyle:=NStyle and not WS_DlgFrame;
  if (wsMinimizeBox in Value) then NStyle:=NStyle or WS_MinimizeBox else NStyle:=NStyle and not WS_MinimizeBox;
  if (wsMaximizeBox in Value) then NStyle:=NStyle or WS_MaximizeBox else NStyle:=NStyle and not WS_MaximizeBox;
  if (wsSysmenu in Value) then NStyle:=NStyle or WS_Sysmenu else NStyle:=NStyle and not WS_Sysmenu;
  if (wsThickframe in Value) then NStyle:=NStyle or WS_THICKFRAME   else NStyle:=NStyle and not WS_THICKFRAME;
  if (wsexAppWindow in Value) then NExStyle:=NExStyle or WS_EX_AppWindow else NExStyle:=NExStyle and not WS_EX_APPWINDOW;
  if (wsexClientEdge in Value) then NExStyle:=NExStyle or WS_EX_CLIENTEDGE else NExStyle:=NExStyle and not WS_EX_CLiENTEDGE;
  if (wsexContextHelp in Value) then NExStyle:=NExStyle or WS_EX_ContextHelp else NExStyle:=NExStyle and not WS_EX_ContextHelp;
  if (wsexDlgModalFrame in Value) then NExStyle:=NExStyle or WS_EX_DLGMODALFRAME else NExStyle:=NExStyle and not WS_EX_DLGMODALFRAME;
  if (wsexStaticEdge in Value) then NExStyle:=NExStyle or WS_EX_STATICEDGE else NExStyle:=NExStyle and not WS_EX_STATICEDGE;
  if (wsexToolwindow in Value) then NExStyle:=NExStyle or WS_EX_TOOLWINDOW else NExStyle:=NExStyle and not WS_EX_TOOLWINDOW;
  if (wsexTransparent in Value) then NExStyle:=NExStyle or WS_EX_Transparent else NExStyle:=NExStyle and not WS_EX_Transparent;
  if (wsexAcceptFiles in Value) then NExStyle:=NExStyle or WS_EX_AcceptFiles else NExStyle:=NExStyle and not WS_EX_AcceptFiles;
  if (csDesigning in Componentstate) then
  if not(DsgnPreview in Value) and (DsgnPreview in FFormProperties) then ResetProperties;
  if Parent<>nil then NStyle:=NStyle and not WS_DLGFRAME;
  FFormProperties:=Value;
  if not(csdesigning in componentstate) or ((csdesigning in componentstate) and (dsgnPreview in Value)) then
  begin
    SetWindowLong(CHandle, GWL_EXSTYLE,NExStyle);
    SetWindowLong(CHandle, GWL_STYLE,NStyle);
    SetWindowPos(CHandle, 0, 0,0,0,0,SWP_DRAWFRAME or SWP_FRAMECHANGED or SWP_NOACTIVATE or
      SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
    if (FOwnerForm as TCustomForm).Active then
    SendMessage(CHandle,WM_PAINT,GetDC(CHandle),0);
  end;
  if (wsexAcceptFiles in FFormProperties) then DragAcceptFiles(OwnerHandle,True) else DragAcceptFiles(OwnerHandle,False);
end;

Procedure TAHMFormManager.ResetProperties;
Var NStyle,NExStyle: LongInt;
begin
  if (FOwnerForm<>nil) and (OwnerHandle<>0) then
  begin
    NStyle:=GetWindowLong(OwnerHandle, GWL_STYLE);
    NExStyle:=GetWindowLong(OwnerHandle, GWL_EXSTYLE);
    NExStyle:=NExStyle or WS_EX_CONTROLPARENT;
    NStyle:=NStyle or WS_DlgFrame or WS_ThickFrame or WS_SysMenu or WS_MinimizeBox or WS_MaximizeBox or WS_Caption or WS_Border;
    NExStyle:=NExStyle and not(WS_EX_AppWindow or WS_EX_ClientEdge or WS_EX_DLGModalFrame or WS_EX_StaticEdge or WS_EX_ToolWindow or WS_EX_CONTEXTHELP or WS_EX_TRANSPARENT);
    SetWindowLong(OwnerHandle, GWL_EXSTYLE,NExStyle);
    SetWindowLong(OwnerHandle, GWL_STYLE,NStyle);
    SetWindowPos(OwnerHandle, 0, 0,0,0,0, SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
    SendMessage(OwnerHandle,WM_PAINT,GetDC(OwnerHandle),0);
  end;
end;

Procedure TAHMFormManager.Setalign(Const Value : TAlign);
begin
  FAlign:=Value;
  if assigned(FParent) then TControl(FOwnerForm).Align:=FAlign;
end;

procedure TAHMFormManager.SetParent(const Value: TCustomPanel);
Var I : Integer;
begin
  FOwnerHookClass.UnhookWin;
//  FMDIHookClass.UnhookWin; {caused problem with assign}
  if (FOwnerForm is TForm) then
  if ((FOwnerForm as TForm).FormStyle=fsMDIChild) then
  begin
    if not(csDesigning in Componentstate) then FOwnerForm.Parent:=nil;
    FParent:=nil;
    SetFormProperties(FFormProperties);
    exit;
  end;
  if  (Value<>nil) then
  begin
    For I:=0 to FOwnerForm.Controlcount-1 do
    if FOwnerForm.Controls[I]=Value then exit;
    FParent := Value;
    if not(csDesigning in Componentstate) then FOwnerForm.Parent:=Value;
    FOwnerForm.UpdateControlState;
    SetFormProperties(FFormProperties);
  end else
  begin
    if not(csDesigning in Componentstate) then FOwnerForm.Parent:=nil;
    FParent:=nil;
    SetFormProperties(FFormProperties);
  end;
  if Value <> nil then Value.FreeNotification(self);
  if assigned(FParent) then TControl(FOwnerForm).Align:=FAlign;
  FOwnerHookClass.HookWin;
  FMDIHookClass.ReloadHook;
end;

procedure TAHMFormManager.Update;
begin
  SetFormProperties(FFormProperties);
end;

Procedure AHMDrawTransparentBitmap(xCanvas: TCanvas; bmp: TBitmap; xStart,
                           yStart: Integer; cTransparentColor: LongInt);
begin
  with TImageList.CreateSize(bmp.Width,bmp.Height) do
  try
    Draw(xCanvas, xStart, yStart,AddMasked(bmp,cTransparentcolor));
  finally
    Free;
  end;
end;

Constructor TAHMFormGradient.Create;
begin
  inherited create;
  FBeginColor:=clBtnShadow;
  FEndColor:=clBtnHighlight;
  FFillStyle:=Horizontal;
  FColorCount:=32;
  FColorStrings := TStringlist.create;
end;

Destructor TAHMFormGradient.Destroy;
begin
  FColorStrings.free;
  inherited Destroy;
end;

Procedure TAHMFormGradient.SetColorStrings(value : TStrings);
begin
  FColorStrings.assign(value);
  Changed;
end;

Procedure TAHMFormGradient.SetStyle(value : TAHMFormFillStyle);
begin
  FFillstyle:=value;
  Changed;
end;

Procedure TAHMFormGradient.MultiDraw(const Cdc:HDC;iWidth,iHeight : Integer;CStrings : TStrings;NoGrad:TColor;Norm : Boolean);
var
  BeginRGBValue  : array[0..2] of Byte;
  RGBDifference  : array[0..2] of Integer;
  ColorBand : TRect;
  I         : Integer;
  R,G,B     : Byte;
  R2,G2,B2  : Byte;
  WorkBmp   : TBitmap;
  L1,L2,i2,FnColor : Integer;
  FStrings : TStrings;
  fbegincol,fendcol:TColor;
  fws,fwe,fhs,fhe : Integer;
begin
  fstrings:=TStringlist.create;
  fstrings.assign(Cstrings);
  if norm then
  begin
    fstrings.insert(0,colortostring(fbegincolor));
    fstrings.add(colortostring(fendcolor));
  end else
  begin
    fstrings.insert(0,colortostring(fendcolor));
    fstrings.add(colortostring(fbegincolor));
  end;
  WorkBmp := TBitmap.Create;
  try
    workbmp.dormant;
    workbmp.Width  := iWidth;
    workbmp.Height := iHeight;
    workbmp.Canvas.pen.width:=1;
    workbmp.canvas.brush.color:=nograd;
    workbmp.canvas.pen.color:=nograd;
    workbmp.canvas.brush.style:=bssolid;
    Patblt(workbmp.Canvas.handle,0,0,iwidth,iheight,PatCopy);
    workbmp.Canvas.Pen.width:=1;
    workbmp.canvas.brush.color:=stringtocolor(fstrings[0]);
    workbmp.canvas.pen.color:=stringtocolor(fstrings[0]);
    Patblt(workbmp.Canvas.handle,0,0,iwidth,iheight,PatCopy);
    workbmp.Canvas.Pen.Style := psSolid;
    workbmp.Canvas.Pen.Mode := pmCopy;
    fncolor:=fstrings.count-1;
    for i2:=0 to fstrings.count-2 do
    for I := 0 to FColorCount -1 do
    begin
      fbegincol:=stringtocolor(fstrings[i2]);
      fendcol  :=stringtocolor(fstrings[i2+1]);
      BeginRGBValue[0]:=GetRValue(ColorToRGB(fBeginCol));
      BeginRGBValue[1]:=GetGValue(ColorToRGB(fBeginCol));
      BeginRGBValue[2]:=GetBValue(ColorToRGB(fBeginCol));
      RGBDifference[0]:=GetRValue(ColorToRGB(fEndCol))-BeginRGBValue[0];
      RGBDifference[1]:=GetGValue(ColorToRGB(fEndCol))-BeginRGBValue[1];
      RGBDifference[2]:=GetBValue(ColorToRGB(fEndCol))-BeginRGBValue[2];
      if (FColorCount > 1) then
      begin
        R  := BeginRGBValue[0] + round(MulDiv (I, RGBDifference[0],FColorCount-1));
        G  := BeginRGBValue[1] + round(MulDiv (I, RGBDifference[1],FColorCount-1));
        B  := BeginRGBValue[2] + round(MulDiv (I, RGBDifference[2],FColorCount-1));
        R2 := BeginRGBValue[0] + round(MulDiv (FColorCount-1-I,
              RGBDifference[0],FColorCount - 1));
        G2 := BeginRGBValue[1] + round(MulDiv (FColorCount-1-I,
              RGBDifference[1],FColorCount - 1));
        B2 := BeginRGBValue[2] + round(MulDiv (FColorCount-1-I,
              RGBDifference[2],FColorCount - 1));
      end else
      begin
        R  := BeginRGBValue[0];
        G  := BeginRGBValue[1];
        B  := BeginRGBValue[2];
        R2 := BeginRGBValue[0];
        G2 := BeginRGBValue[1];
        B2 := BeginRGBValue[2];
      end;
      if r<1 then r:=1;
      if g<1 then g:=1;
      if b<1 then b:=1;
      Workbmp.Canvas.Pen.Color:=RGB (R, G, B);
      Workbmp.Canvas.Brush.color:=RGB (R, G, B);
      Workbmp.Canvas.Brush.style:=bssolid;
      case ffillstyle of
        Circle :
        begin
          fhe:=Round(iHeight/(fncolor))+1; fhs:=round(fhe*i2);
          fwe:=Round(iWidth/(fncolor))+1; fws:=round(fwe*i2);
          Colorband.left   :=MulDiv(I  ,fwe,FColorCount);
          Colorband.right  :=MulDiv(I+2,fwe,FColorCount);
          Colorband.Top    :=MulDiv(I  ,fhe,FColorCount);
          Colorband.bottom :=MulDiv(I+2,fhe,FColorCount);
          for l1:=Colorband.left to Colorband.right do
          begin
            Workbmp.Canvas.Moveto(fws+l1,0);
            Workbmp.Canvas.Lineto(iWidth-l1-fws,iHeight);
          end;
          for l1:=Colorband.top to Colorband.bottom do
          begin
            Workbmp.Canvas.Moveto(0,l1+fhs);
            Workbmp.Canvas.Lineto(iWidth,iHeight-l1-fhs);
          end;
        end;
        Spectral :
        begin
          fhe:=Round(iHeight/(fncolor))+1; fhs:=round(fhe*i2);
          fwe:=Round(iWidth/(fncolor))+1; fws:=round(fwe*i2);
          Colorband.left  :=MulDiv(I  ,fwe,FColorCount);
          Colorband.right :=MulDiv(I+2,fwe,FColorCount);
          Colorband.Top   :=MulDiv(I  ,fhe,FColorCount);
          Colorband.bottom:=MulDiv(I+2,fhe,FColorCount);
          for l1:=Colorband.left to Colorband.right do
          begin
            if odd(l1) then Workbmp.Canvas.Pen.Color:=RGB (R, G, B)
                       else Workbmp.Canvas.Pen.Color:=RGB (R2, G2, B2);
            Workbmp.Canvas.Moveto(l1+fws,0);
            Workbmp.Canvas.Lineto(iWidth-l1-fws,iHeight);
          end;
          for l1:=Colorband.top to Colorband.bottom do
          begin
            if odd(l1) then Workbmp.Canvas.Pen.Color:=RGB (R, G, B)
                       else Workbmp.Canvas.Pen.Color:=RGB (R2, G2, B2);
            Workbmp.Canvas.Moveto(0,l1+fhs);
            Workbmp.Canvas.Lineto(iWidth,iHeight-l1-fhs);
          end;
        end;
        SquareMiddle :
        begin
          fhe:=Round(iHeight/(fncolor)); fhs:=round(fhe/2*i2);
          fwe:=Round(iWidth/(fncolor)); fws:=round(fwe/2*i2);
          Colorband.left  :=MulDiv(I,round(fwe/2),FColorCount);
          Colorband.right :=iwidth-Colorband.left;
          Colorband.Top   :=MulDiv(I,round(fhe/2),FColorCount);
          Colorband.bottom:=iHeight-Colorband.top;
          Patblt(Workbmp.Canvas.handle,fws+Colorband.left,fhs+Colorband.top,
            Colorband.right-Colorband.left-fws*2,Colorband.bottom-Colorband.top-fhs*2,PatCopy);
        end;
        RoundMiddle :
        begin
          fhe:=Round(iHeight/(fncolor))+1;
          fhs:=round(fhe/2*i2)+1;
          fwe:=Round(iWidth/(fncolor))+1;
          fws:=round(fwe/2*i2)+1;
          Colorband.left:=MulDiv (I,round(fwe/2)+1,FColorCount);
          Colorband.right:=iWidth-Colorband.left;
          Colorband.Top:=MulDiv (I,round(fhe/2)+1,FColorCount);
          Colorband.bottom:=iHeight-Colorband.top;
          Ellipse(Workbmp.Canvas.Handle,fws+Colorband.left,
                  fhs+Colorband.top,Colorband.right-fws,Colorband.bottom-fhs);
        end;
        LeftBottom :
        begin
          fhe:=Round(iHeight/(fncolor))+1; fhs:=round(fhe*i2);
          fwe:=Round(iWidth/(fncolor))+1; fws:=round(fwe*i2);
          Colorband.left:=MulDiv(I,fwe,FColorCount);
          Colorband.right:=iwidth;
          Colorband.Top:=MulDiv (I,fhe,FColorCount);
          Colorband.bottom:=iheight;
          Patblt(Workbmp.Canvas.handle,fws+Colorband.left,fhs+Colorband.top,
            Colorband.right-Colorband.left,Colorband.bottom-Colorband.top,PatCopy);
        end;
        DoppelFlash :
        begin
          fhe:=Round(iHeight/(fncolor))+1; fhs:=round(fhe*i2)+1;
          fwe:=Round(iWidth/(fncolor))+1; fws:=round(fwe*i2)+1;
          ColorBand.Right   := iwidth;
          ColorBand.Bottom  := iheight;
          ColorBand.Left    := MulDiv(I,fwe,FColorCount);
          ColorBand.Top     := MulDiv(I,fhe,FColorCount);
          Ellipse(Workbmp.Canvas.Handle,fws+Colorband.left,
                  fhs+Colorband.top,Colorband.right,Colorband.bottom);
          Ellipse(Workbmp.Canvas.Handle,iwidth-Colorband.left-fws,iheight-Colorband.top-fhs,
                  iwidth-Colorband.right,iheight-Colorband.bottom);

        end;
        SingleFlash :
        begin
          fhe:=Round(iHeight/(fncolor)); fhs:=round(fhe*i2);
          fwe:=Round(iWidth/(fncolor)); fws:=round(fwe*i2);
          ColorBand.Right   := iwidth;
          ColorBand.Bottom  := iheight;
          ColorBand.Left    := MulDiv(I,fwe,FColorCount);
          ColorBand.Top     := MulDiv(I,fhe,FColorCount);
          Ellipse(Workbmp.Canvas.Handle,fws+Colorband.left,
                  fhs+Colorband.top,Colorband.right,Colorband.bottom);
        end;
        MiddleHBar :
        begin
          fhe:=Round(iHeight/(fncolor))+1;
          fhs:=round((fhe/2)*i2)+1;
          ColorBand.Left :=  iheight-MulDiv(I  ,Round(fhe/2)+1,FColorCount);
          ColorBand.Right := iheight-MulDiv(I+2,Round(fhe/2)+1,FColorCount);
          ColorBand.Top    := MulDiv (I  ,Round(fhe/2),FColorCount);
          ColorBand.Bottom := MulDiv (I+2,Round(fhe/2),FColorCount);
          Patblt(Workbmp.Canvas.handle,0,Colorband.Left-1-fhs,
                iwidth,ColorBand.right-Colorband.left,PatCopy);
          Patblt(Workbmp.Canvas.handle,0,fhs+Colorband.top,
                iwidth,Colorband.bottom-Colorband.top+1,PatCopy);
        end;
        MiddleVBar :
        begin
          fwe:=Round(iWidth/(fncolor))+1;
          fws:=round((fwe/2)*i2)+1;
          ColorBand.Left   := iwidth-MulDiv(I  ,Round(fwe/2)+1,FColorCount);
          ColorBand.Right  := iwidth-MulDiv(I+2,Round(fwe/2)+1,FColorCount);
          ColorBand.Top    := MulDiv(I  ,Round(fwe/2),FColorCount);
          ColorBand.Bottom := MulDiv(I+2,Round(fwe/2),FColorCount);
          Patblt(Workbmp.Canvas.handle,Colorband.Left-1-fws,0,
                 ColorBand.right-Colorband.left,iheight,PatCopy);
          Patblt(Workbmp.Canvas.handle,fws+Colorband.top,0,
                 Colorband.bottom-Colorband.top+1,iheight,PatCopy);
        end;
        VerticalDoppelBar :
        begin
          fwe:=Round(iWidth/(fncolor))+1;
          fws:=round((fwe/3)*i2)+1;
          ColorBand.Top    := MulDiv (I  ,Round(fwe/3)+1,FColorCount);
          ColorBand.Bottom := MulDiv (I+1,Round(fwe/3)+1,FColorCount);
          Patblt(Workbmp.Canvas.handle,fws+Colorband.top,0,
                 Colorband.bottom-Colorband.top,iheight,PatCopy);
          Patblt(Workbmp.Canvas.handle,2*Round(iwidth/3)-Colorband.Bottom-fws,0,
                 Colorband.Bottom-Colorband.Top,iheight,PatCopy);
          Patblt(Workbmp.Canvas.handle,fws+2*Round(iwidth/3)+Colorband.top,0,
                 Colorband.bottom-Colorband.top,iheight,PatCopy);
        end;
        HorizontalDoppelBar:
        begin
          fhe:=Round(iHeight/(fncolor))+1;
          fhs:=round((fhe/3)*i2)+1;
          ColorBand.Top    := MulDiv (I  ,Round(fhe/3)+1,FColorCount);
          ColorBand.Bottom := MulDiv (I+1,Round(fhe/3)+1,FColorCount);
          Patblt(Workbmp.Canvas.handle,0,fhs+Colorband.top,
                 iwidth,Colorband.bottom-Colorband.top,PatCopy);
          Patblt(Workbmp.Canvas.handle,0,2*Round(iheight/3)-Colorband.bottom-fhs,
                 iwidth,Colorband.bottom-Colorband.top,PatCopy);
          Patblt(Workbmp.Canvas.handle,0,fhs+2*Round(iheight/3)+Colorband.top,
                 iwidth,Colorband.bottom-Colorband.top,PatCopy);
        end;
        Horizontal :
        begin
          fhe:=Round(iHeight/(fncolor))+1;
          fhs:=fhe*i2;
          ColorBand.Left   := 0;
          ColorBand.Right  := iWidth;
          ColorBand.Top    := MulDiv (I    ,fhe,FColorCount);
          ColorBand.Bottom := MulDiv (I + 2,fhe,FColorCount);
          Patblt(Workbmp.Canvas.handle,Colorband.left,fhs+Colorband.top,
            Colorband.right-Colorband.left,fhs+Colorband.bottom-Colorband.top,PatCopy);
        end;
        Vertical :
        begin
          fwe:=Round(iWidth/(fncolor))+1;
          fws:=fwe*i2;
          ColorBand.Top    := 0;
          ColorBand.Bottom := iHeight;
          ColorBand.Left   := MulDiv (I    , fwe,FColorCount);
          ColorBand.Right  := MulDiv (I + 2, fwe,FColorCount);
          Patblt(Workbmp.Canvas.handle,fws+Colorband.left,Colorband.top,
            fws+Colorband.right-Colorband.left,Colorband.bottom-Colorband.top,PatCopy);
        end;
      end;
    end;
    BitBlt(Cdc,0,0,iwidth,iheight,
          Workbmp.canvas.handle,0,0,srcCopy);
  finally
    WorkBmp.Free;
  end;
  fstrings.free;
end;


Procedure TAHMFormGradient.SetBeginColor(Value : TColor);
begin
  FBeginColor:=value;
  changed;
end;

Procedure TAHMFormGradient.SetEndColor(Value : TColor);
begin
  FEndColor:=value;
  changed;
end;

Procedure TAHMFormGradient.SetColorCount(Value : Integer);
begin
  if (value>1) and (value<256) then FColorCount:=value;
  changed;
end;


Constructor TAHMFormTexture.Create;
begin
  inherited create;
  FImageStyle := isTile;
  FTransparentColor := clNone;
  FTransparentBackground := clBtnFace;
  FImage := TBitmap.create;
end;

Destructor TAHMFormTexture.Destroy;
begin
  FImage.free;
  inherited Destroy;
end;


Procedure TAHMFormTexture.SetTransparentColor(Value : TColor);
begin
  FTransparentColor:=value;
  Changed;
end;

Procedure TAHMFormTexture.SetTransparentBackground(Value : TColor);
begin
  FTransparentBackground:=value;
  Changed;
end;

Procedure TAHMFormTexture.Draw(const Cdc : HDC;Width,Height : Integer;Noimg : TColor);
var i,j,nx,ny : integer;
    hbitm : TBitmap;
begin
  if not(fimage.Empty)  then
  begin
    hbitm:=TBitmap.create;
    hbitm.width :=fimage.width;
    hbitm.height:=fimage.height;
    hbitm.canvas.brush.color:=FTransparentBackground;
    hbitm.canvas.brush.style:=bsSolid;
    hbitm.Canvas.BrushCopy(rect(0,0,hbitm.width,hbitm.height),fimage,
                           rect(0,0,hbitm.width,hbitm.height),FTransparentColor);
    if FImageStyle=isTile then
    begin
      nx:=width div fimage.width;
      ny:=height div fimage.height;
      for i:=0 to nx do
      for j:=0 to ny do
      if FTransparentColor=clNone then
        Bitblt(Cdc,i*fimage.width,j*fimage.height,
               fimage.width,fimage.height,fimage.canvas.handle,0,0,Srccopy)
      else
        Bitblt(Cdc,i*hbitm.width,j*hbitm.height,
               hbitm.width,hbitm.height,hbitm.canvas.handle,0,0,Srccopy);
    end else
    if FImageStyle=isStretched then
    begin
      if FTransparentColor=clNone then
        Stretchblt(Cdc,0,0,width,height,
            fimage.canvas.handle,0,0,fimage.width,fimage.height,Srccopy)
                       else
        Stretchblt(Cdc,0,0,width,height,
             hbitm.canvas.handle,0,0,hbitm.width,hbitm.height,Srccopy);
    end else
    begin
      SetBkColor(Cdc, ColorToRGB(NoImg));
      SetBkMode (Cdc, OPAQUE);
      if width >fimage.width  then nx:=((width-fimage.width) div 2)
                              else nx:=0;
      if height>fimage.height then ny:=((height-fimage.height) div 2)
                              else ny:=0;
      if FTransparentColor=clNone then
      Bitblt(Cdc,nx,ny,fimage.width,fimage.height,fimage.canvas.handle,0,0,Srccopy)
      else Bitblt(Cdc,nx,ny,hbitm.width,hbitm.height,hbitm.canvas.handle,0,0,Srccopy);

    end;
    hbitm.free;
  end;
end;

Procedure TAHMFormTexture.SetImageStyle(Value : TAHMFormImageStyle);
begin
  FImageStyle:=value;
  Changed;
end;

Procedure TAHMFormTexture.Setimage(Value : TBitmap);
begin
  FImage.assign(Value);
  Changed;
end;


Constructor TAHMFormBrushFill.Create;
begin
  inherited create;
  FBrushStyle := bssolid;
  FBrushColor := clbtnface;
end;


Procedure TAHMFormBrushFill.SetBrushStyle(value : TBrushStyle);
begin
  FBrushStyle:=value;
  Changed;
end;

Procedure TAHMFormBrushFill.SetBrushColor(value : TColor);
begin
  FBrushColor:=value;
  Changed;
end;


constructor TAHMFormBackground.Create(AOwner : TAHMFormManager);
begin
  inherited create;
  FFormManager:=AOwner;
  FBackStyle:=bNormal;
  FTexture    := TAHMFormTexture.create;
  FGradient   := TAHMFormGradient.create;
  FBrushFill  := TAHMFormBrushFill.create;
  FGradient.onchange  := backchange;
  FTexture.onchange   := backchange;
  FBrushFill.onchange := backchange;
end;

destructor TAHMFormBackground.Destroy;
begin
  FGradient.onchange :=nil;
  FTexture.onchange :=nil;
  FBrushFill.onchange:=nil;
  FTexture.free;
  FGradient.free;
  FBrushFill.free;
  inherited Destroy;
end;

Function TAHMFormBackground.Draw(DC : HDC;fWidth,fHeight : Integer;Norm:Boolean) : Boolean;
var tx,tx2 : TBitmap;
    FBrush : TBrush;
begin
  if (FBackStyle=bNormal) or ((csDesigning in FFormManager.Componentstate) and not(dsgnPreview in FFormManager.FFormProperties))
  or ((FBackStyle=bTexture) and (Texture.Image.Empty)) then
  begin
    result:=false;
    exit;
  end else result:=true;
  tx:=TBitmap.create;
  tx2:=TBitmap.create;
  FBrush := TBrush.Create;
  tx.width:=fwidth; tx.height:=fheight;
  tx2.width:=fwidth; tx2.height:=fheight;
  if (Backgroundstyle=BNormal) and
   not(wsexTransparent in FFormManager.Properties) then
  begin
    fbrush.style:=bsSolid;
    fbrush.color:=(FFormManager.FOwnerForm as TCustomForm).Color;
    Windows.FillRect(DC,rect(0,0,fwidth,fheight),fBrush.Handle);
  end;
  if FBackStyle=bGradient then FGradient.Multidraw(DC,fWidth,fHeight,FGradient.ColorsInbetween,(FFormManager.FOwnerForm as TCustomForm).Color,norm)
  else if FBackStyle=bTexture then FTexture.draw(DC,fWidth,fHeight,(FFormManager.FOwnerForm as TCustomForm).Color)
  else if (FBackstyle=bBrushFillUseCurrent) or (FBackstyle=bBrushFillFormColor) then
  begin
    tx.canvas.brush.style  := FBrushFill.BrushStyle;
    tx.canvas.brush.color  := FBrushFill.BrushColor;
    tx.canvas.Fillrect(rect(0,0,fwidth,fheight));
    tx2.canvas.brush.style := FBrushFill.BrushStyle;
    tx2.canvas.brush.color := clBlack;
    tx2.canvas.Fillrect(rect(0,0,fwidth,fheight));
    tx.canvas.brushcopy(rect(0,0,fwidth,fheight),tx2,rect(0,0,fwidth,fheight),clblack);
    if FBackStyle=bBrushFillFormColor then
    begin
      tx2.canvas.brush.style:= bsSolid;
      tx2.canvas.brush.color:= (FFormManager.FOwnerForm as TCustomForm).Color;
      tx2.canvas.Fillrect(rect(0,0,fwidth,fheight));
      tx2.canvas.brushcopy(rect(0,0,fwidth,fheight),tx,rect(0,0,fwidth,fheight),clwhite);
      BitBlt(tx.Canvas.handle,0,0,fwidth,fheight,tx2.canvas.handle,0,0,srcCopy);
    end;
    BitBlt(DC,0,0,fwidth,fheight,tx.canvas.handle,0,0,srcCopy);
  end;
  FBrush.free;
  tx.free;
  tx2.free;
end;

procedure TAHMFormBackground.DrawTrans(Canvas : TCanvas;Width,Height : Integer;Norm:Boolean;TRC:TColor);
var tbit1,tbit2 : TBitmap;
    trectx : TRect;
begin
  trectx:=rect(0,0,width,height);
  TBit1:=TBitmap.create;
  TBit2:=TBitmap.create;
  TBit1.width:=width;
  TBit1.height:=Height;
  TBit2.width:=width;
  TBit2.height:=Height;
  Draw(TBit1.Canvas.Handle,Width,Height,Norm);
  BitBlt(TBit2.Canvas.Handle,0,0,width,height,canvas.handle,0,0,SrcCopy);
  AHMDrawTransparentBitmap(TBit1.canvas,TBit2,0,0,TRC);
  BitBlt(Canvas.Handle,0,0,width,height,TBit1.canvas.handle,0,0,SrcCopy);
  Tbit2.free;
  Tbit1.free;
end;

procedure TAHMFormBackground.BackChange(Sender : TObject);
begin
  if assigned(fonchanged) then fonchanged(self);
end;

procedure TAHMFormBackground.SetGradient(value : TAHMFormGradient);
begin
  FGradient.assign(value);
  Backchange(self);
end;

procedure TAHMFormBackground.SetBrushFill(value : TAHMFormBrushFill);
begin
  FBrushFill.assign(value);
  Backchange(self);
end;

procedure TAHMFormBackground.SetTexture(value : TAHMFormTexture);
begin
  FTexture.assign(value);
  Backchange(self);
end;

procedure TAHMFormBackground.SetBackStyle(value : TAHMFormBackStyle);
begin
  FBackStyle:=value;
  Backchange(self);
end;

procedure TAHMFormManager.OnBackChange(Sender: TObject);
begin
  FOwnerForm.Invalidate;
  if OwnerHandle<>0 then
  SendMessage(FMDIHandle,WM_ERASEBKGND,GETDC(Ownerhandle),0);
end;

function TAHMFormManager.GetOwnerHandle: Hwnd;
begin
  if (FOwnerForm<>nil) and not(csDestroying in FOwnerForm.Componentstate) then
    result:=TCustomForm(FOwnerForm).Handle
  else
    result:=0;
end;

function TAHMFormManager.GetMDIHandle: Hwnd;
begin
  if (FOwnerForm=nil) then
  begin
    result:=0;
    exit;
  end else
  if (TForm(FOwnerForm).FormStyle=fsMDIForm) and (TForm(FOwnerForm).Clienthandle<>0) then
   result:=TForm(FOwnerForm).Clienthandle else result:=TCustomForm(FOwnerForm).Handle;
end;

procedure TAHMFormManager.ReloadMDIHook(Sender: TObject);
begin
  if not(csdestroying in Componentstate) then
  begin
    FMDIHandle:=GetMDIHandle;
    SendMessage(FMDIHandle,WM_ERASEBKGND,GETDC(Ownerhandle),0);
  end;
end;

procedure TAHMFormManager.ReloadOwnerHook(Sender: TObject);
begin
  if not(csdestroying in Componentstate) then
  begin
    SetFormProperties(FFormProperties);
    SendMessage(OwnerHandle,WM_NCPAINT,GETDC(Ownerhandle),0);
  end;
end;

end.
