{******************************************************************}
{ ModiLess.pas                                                     }
{                                                                  }
{ Author    : A.Nasir Senturk                                      }
{ Home Page : http://www.shenturk.com                              }
{ Email     : shenturk@gmail.com                                   }
{                                                                  }
{ Date      : 28.12.2006                                           }
{                                                                  }
{ Sizden iki şey rica edicem:                                      }
{ 1. Lutfen bu baslik kismini kaldirmayiniz.                       }
{ 2. Mumkunse bagis yapiniz.                                       }
{ *****************************************************************}

unit ModiLess;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, GdipApi, GdipObj, DirectDraw, TextUtil, ExtCtrls, WinInet,
  InetUtil, InetThrd, EditUtil;

type
  TModiLessForm = class(TForm)
    BackgrndLbl: TLabel;
    CloseBtn: TButton;
    HeaderTextLbl: TLabel;
    SecureImageLbl: TLabel;
    StatusTextLbl: TLabel;
    CancelLbl: TLabel;
    Countdown: TTimer;
    CountdownLbl: TLabel;
    LoaderTimer: TTimer;
    EntryEdit: TEdit;
    OkBtn: TButton;
    OkLbl: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure CancelLblClick(Sender: TObject);
    procedure CountdownTimer(Sender: TObject);
    procedure CancelLblMouseEnter(Sender: TObject);
    procedure CancelLblMouseLeave(Sender: TObject);
    procedure LoaderTimerTimer(Sender: TObject);
    procedure FormHide(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure EntryEditChange(Sender: TObject);
    procedure OkLblMouseEnter(Sender: TObject);
    procedure OkLblMouseLeave(Sender: TObject);
    procedure OkLblClick(Sender: TObject);
  private
    { Private declarations }
    OpacityMin,
    OpacityMax,
    Opacity: Byte;
    MainBuffer: TGPBitmap;
    DrawCanvas: TGPGraphics;

    ColorizedImage,
    OverlayImage,
    SecureImage,
    CloseImage,
    CancelImage,
    CancelImageEnter,
    CancelImageLeave: TGPBitmap;

    OkImage,
    OkImageEnter,
    OkImageLeave: TGPBitmap;

    Updating: Boolean;

    SessionCookie: string;
    SetCookie: string;
    UserCanceled: Boolean;
    TimeLeft: Integer;
    AliveTime: Integer;
    GdiEdit: TGdiEdit;
    BackColor: Cardinal;
    BackOpacity: Byte;
    CancelColor: Cardinal;
    BackPen: TGPPen;
    BackBrush: TGPSolidBrush;
    procedure AllocateHandle;
    procedure ReleaseHandle;
    procedure SetFormStyleEx;
    procedure AllocateDrawItems;
    procedure ReleaseDrawItems;
  protected

  public
    { Public declarations }
    RecognizedText: WideString;
    QuotaInfoText: WideString;
    procedure UpdateLayered;
    procedure UpdateMainWindow;
    procedure PaintBackground;
    procedure PaintButtons;
    procedure PaintSecureImage;
    procedure PaintStatusText;
    procedure PaintCancel;
    procedure PaintOk;
    procedure PaintCountdown;
    procedure PaintHeaderText;
    procedure PaintEdit;
    procedure HideForm;
    procedure ShowForm;
    function ShowModalForm: Integer;
    procedure HideFormEffect(const Min: Integer);
    procedure ShowFormEffect(const Max: Integer);
    procedure FadeInEffect(const Step, Wait, Max: Integer);
    procedure FadeOutEffect(const Step, Wait, Min: Integer);
    procedure LoadSecureImage(const FileName: string);
    procedure ReleaseSecureImage;
    procedure SetStatusText(const Text: WideString);
    procedure EnableCountdownTimer(Enable: Boolean);
    procedure ResetCountdown;
    procedure InitModiLessForm;
    procedure DoneModiLessForm;
    procedure ParseSetCookie;
  end;

implementation

uses Main, ConstDef, ShelApix, UniCode, OptnsDlg;

{$R *.dfm}

{ TModiLessForm }

procedure TModiLessForm.AllocateHandle;
begin
  MainBuffer := TGPBitmap.Create(Width, Height, PixelFormat32bppARGB);
  DrawCanvas := TGPGraphics.Create(MainBuffer);
end;

procedure TModiLessForm.FadeInEffect(const Step, Wait, Max: Integer);
begin
  if not EyMainForm.EnableFadeEffect then Exit;
  while Opacity < Max do
  begin
    Application.ProcessMessages;
    if Opacity + Step >= Max then
    begin
      Opacity := Max;
      UpdateMainWindow;
      Break;
    end;
    Opacity := Opacity + Step;
    UpdateMainWindow;
    Sleep(Wait);
  end;
end;

procedure TModiLessForm.FadeOutEffect(const Step, Wait, Min: Integer);
begin
  if not EyMainForm.EnableFadeEffect then Exit;
  while Opacity > Min do
  begin
    Application.ProcessMessages;
    if Opacity - Step <= Min then
    begin
      Opacity := Min;
      UpdateMainWindow;
      Break;
    end;
    Opacity := Opacity - Step;
    UpdateMainWindow;
    Sleep(Wait);
  end;
end;

procedure TModiLessForm.HideForm;
begin
  if not Self.Visible then Exit;
  Self.Hide;
end;

procedure TModiLessForm.PaintBackground;

  procedure PaintColorizedOverlay;
  begin
    DrawCanvas.DrawImage(OverlayImage,
      BackgrndLbl.Left + 6,
      BackgrndLbl.Top + 3,
      OverlayImage.GetWidth, OverlayImage.GetHeight);
  end;

  procedure PaintColorized(Color: Cardinal; Alpha: Byte);
  const
    CMatrix: ColorMatrix = (
      (1.0, 0.0, 0.0, 0.0, 1.0),
      (0.0, 1.0, 0.0, 0.0, 0.0),
      (0.0, 0.0, 1.0, 0.0, 0.0),
      (0.0, 0.0, 0.0, 1.0, 0.0),
      (0.0, 0.0, 0.0, 0.0, 1.0)
    );
  var
    Attr: TGPImageAttributes;
    Matrix: ColorMatrix;
  begin

    Matrix := CMatrix;

    Matrix[3, 3] := (Alpha / 255);
    Matrix[0, 0] := 2 * (GetRValue(Color) / 255);
    Matrix[1, 1] := 2 * (GetGValue(Color) / 255);
    Matrix[2, 2] := 2 * (GetBValue(Color) / 255);

    Attr := TGPImageAttributes.Create;
    try
      Attr.SetColorMatrix(Matrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);

      DrawCanvas.DrawImage(ColorizedImage,
        MakeRect(BackgrndLbl.Left, BackgrndLbl.Top,
        ColorizedImage.GetWidth, ColorizedImage.GetHeight),  // dest rect
        0, 0, ColorizedImage.GetWidth, ColorizedImage.GetHeight,       // source rect
        UnitPixel,
        Attr);

      PaintColorizedOverlay;

    finally
      Attr.Free;
    end;

  end;

begin
  if BackgrndLbl.Visible then
    PaintColorized(BackColor, BackOpacity);
end;

procedure TModiLessForm.PaintHeaderText;
var
  WideText: WideString;
  Colorize: Cardinal;
begin
  if HeaderTextLbl.Visible then
  begin
    WideText := 'Güvenlik Kodu';
    //Colorize := MakeColor($FF, $FF, ($FF div 120) * TimeLeft, 0);
    Colorize := $FFFFFFFF;
    PaintLabelTo(DrawCanvas, HeaderTextLbl, WideText, StringAlignmentNear,
      Colorize);
  end;
end;

procedure TModiLessForm.ReleaseHandle;
begin
  if Assigned(MainBuffer) then FreeAndNil(MainBuffer);
  if Assigned(DrawCanvas) then FreeAndNil(DrawCanvas);
end;

procedure TModiLessForm.ShowForm;
begin
  if Self.Visible then Exit;
  LoaderTimer.Enabled := True;
  Self.Show;
end;

procedure TModiLessForm.UpdateLayered;
begin

  Updating := True;
  try
    ReleaseHandle;
    AllocateHandle;
    PaintBackground;
    PaintButtons;
    PaintSecureImage;
    PaintHeaderText;
    PaintOk;
    PaintCancel;
    PaintStatusText;
    PaintCountdown;
    PaintEdit;
    UpdateMainWindow;
  finally
    Updating := False;
  end;
end;

procedure TModiLessForm.UpdateMainWindow;
var
  ScrDC, MemDC: HDC;
  BitmapHandle, PrevBitmap: HBITMAP;
  BlendFunc: _BLENDFUNCTION;
  Size: TSize;
  P, S: TPoint;
begin

  ScrDC := CreateCompatibleDC(0);
  MemDC := CreateCompatibleDC(ScrDC);

  MainBuffer.GetHBITMAP(0, BitmapHandle);
  PrevBitmap := SelectObject(MemDC, BitmapHandle);
  Size.cx := Width;
  Size.cy := Height;
  P := Point(Left, Top);
  S := Point(0, 0);

  with BlendFunc do
  begin
    BlendOp := AC_SRC_OVER;
    BlendFlags := 0;
    SourceConstantAlpha := Opacity;
    AlphaFormat := AC_SRC_ALPHA;
  end;

  UpdateLayeredWindow(Handle, ScrDC, @P, @Size, MemDC, @S, 0,
    @BlendFunc, ULW_ALPHA);

  SelectObject(MemDC, PrevBitmap);
  DeleteObject(BitmapHandle);

  DeleteDC(MemDC);
  DeleteDC(ScrDC);

end;

procedure TModiLessForm.FormCreate(Sender: TObject);
begin

  AllocateDrawItems;

  AliveTime := 60;
  TimeLeft := AliveTime;

  SetFormStyleEx;

  ColorizedImage := TGPBitmap.Create(UIPath + Background6Image);
  OverlayImage := TGPBitmap.Create(UIPath + Overlay6Image);

  Self.Width := ColorizedImage.GetWidth;
  Self.Height := ColorizedImage.GetHeight;
  Self.Left := Self.Left + (Screen.WorkAreaWidth - Self.Width) div 2;
  Self.Top := Self.Top + (Screen.WorkAreaHeight - Self.Height) div 2;

  CloseImage := TGPBitmap.Create(UIPath + CloseLeaveImage);

  OkImageEnter := TGPBitmap.Create(UIPath + OkEnterImage);
  OkImageLeave := TGPBitmap.Create(UIPath + OkLeaveImage);
  OkImage := OkImageLeave;

  CancelImageEnter := TGPBitmap.Create(UIPath + CancelEnterImage);
  CancelImageLeave := TGPBitmap.Create(UIPath + CancelLeaveImage);
  CancelImage := CancelImageLeave;

  OpacityMin := DefOpacityMin;
  OpacityMax := DefOpacityMax;

  if EyMainForm.EnableFadeEffect then Opacity := DefOpacityMin
  else Opacity := DefOpacityMax;

  GdiEdit := TGdiEdit.Create(Self);
  GdiEdit.Parent := Self;
  GdiEdit.Left := 50;
  GdiEdit.Top := 148;
  GdiEdit.Width := 140;
  GdiEdit.Height := 25;
  GdiEdit.Cursor := crIBeam;
  GdiEdit.Edit := EntryEdit;

  EntryEdit.Left := GdiEdit.Left;
  EntryEdit.Top := GdiEdit.Top;
  EntryEdit.Width := GdiEdit.Width;
  EntryEdit.Height := GdiEdit.Height;
  EntryEdit.Font.Assign(GdiEdit.Font);

  BackColor := IniFile.ReadInteger(sGeneral, sBackColor, Integer($00000000));
  BackOpacity := IniFile.ReadInteger(sGeneral, sBackOpacity, Integer($C0));

  UpdateLayered;

end;

procedure TModiLessForm.FormDestroy(Sender: TObject);
begin
  ReleaseDrawItems;
  ReleaseSecureImage;

  OkImageEnter.Free;
  OkImageLeave.Free;

  CancelImageEnter.Free;
  CancelImageLeave.Free;

  CloseImage.Free;
  OverlayImage.Free;
  ColorizedImage.Free;
  ReleaseHandle;
end;

procedure TModiLessForm.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  R: TRect;
begin
  if Button = mbLeft then
  begin
    ReleaseCapture;
    SendMessage( Handle, WM_SYSCOMMAND, SC_DRAGMOVE, 0 );
    GetWindowRect(Handle, R);
    Left := R.Left;
    Top := R.Top;
    UpdateLayered;
  end;
end;

procedure TModiLessForm.PaintSecureImage;
const
  ScaleWidth  = 150.0;
  ScaleHeight = 50.0;
begin
  if SecureImageLbl.Visible and Assigned(SecureImage) then
    DrawImageTo(DrawCanvas, SecureImageLbl.Left, SecureImageLbl.Top,
      ScaleWidth, ScaleHeight, SecureImage);
end;

procedure TModiLessForm.LoadSecureImage(const FileName: string);
begin
  ReleaseSecureImage;
  SecureImage := TGPBitmap.Create(FileName);
  UpdateLayered;
end;

procedure TModiLessForm.ReleaseSecureImage;
begin
  RecognizedText := '';
  if Assigned(SecureImage) then FreeAndNil(SecureImage);
end;

procedure TModiLessForm.PaintStatusText;
begin
  if StatusTextLbl.Visible then
  begin
    //DrawCanvas.FillRectangle(BackBrush, MakeRect(StatusTextLbl.BoundsRect));
    //DrawCanvas.DrawRectangle(BackPen, MakeRect(StatusTextLbl.BoundsRect));
    PaintLabelTo(DrawCanvas, StatusTextLbl, StatusTextLbl.Caption,
      StringAlignmentCenter, $FFFFFFFF, True, TextRenderingHintAntiAliasGridFit);
  end;
end;

procedure TModiLessForm.SetStatusText(const Text: WideString);
begin
  StatusTextLbl.Caption := Text;
  UpdateLayered;
end;

procedure TModiLessForm.PaintCancel;
begin
  if CancelLbl.Visible then
  begin
    DrawImageTo(DrawCanvas, CancelLbl.Left, CancelLbl.Top,
      CancelImage.GetWidth, CancelImage.GetHeight, CancelImage);
    {
    PaintLabelTo(DrawCanvas, CancelLbl, CancelLbl.Caption,
      StringAlignmentCenter, CancelColor);
    }
    {
    if CancelLbl.Enabled then CancelColor := aclYellow
    else CancelColor := aclGray;
    PaintLabelTo(DrawCanvas, CancelLbl, CancelLbl.Caption,
      StringAlignmentNear, CancelColor);
    }
  end;
end;

procedure TModiLessForm.CancelLblClick(Sender: TObject);
begin
  UserCanceled := True;
  //SetStatusText('İşlem iptal ediliyor...');
  ModalResult := mrCancel;
  HideForm;
end;

procedure TModiLessForm.CountdownTimer(Sender: TObject);
begin
  if TimeLeft > 0 then
  begin
    Dec(TimeLeft);
    CountdownLbl.Caption := Format('%.2d:%.2d',
      [TimeLeft div 60, TimeLeft mod 60] );
    if not CountdownLbl.Visible then CountdownLbl.Visible := True;
    if not Updating then UpdateLayered;
  end
  else begin
    ModalResult := mrCancel;
    HideForm;
  end;
end;

procedure TModiLessForm.PaintCountdown;
var
  Colorize: Cardinal;
begin
  if CountdownLbl.Visible then
  begin
    Colorize := MakeColor($FF, $FF, ($FF div AliveTime) * TimeLeft, 0);
    PaintLabelTo(DrawCanvas, CountdownLbl, CountdownLbl.Caption,
      StringAlignmentNear, Colorize);
  end;
end;

procedure TModiLessForm.ResetCountdown;
begin
  CountdownLbl.Caption := '';
  TimeLeft := AliveTime;
  UpdateLayered;
end;

procedure TModiLessForm.InitModiLessForm;
begin
  UserCanceled := False;
  EnableCountdownTimer(False);
  ResetCountdown;
  LoadSecureImage(DefNameJpeg);
  SetStatusText(
    'Lütfen yukarıdaki Güvenlik Kodunu'#13#10 +
    'aşağıdaki metin kutusuna küçük'#13#10 +
    'harflerle giriniz.');
end;

procedure TModiLessForm.DoneModiLessForm;
begin
  RecognizedText := '';
  EnableCountdownTimer(False);
  ReleaseSecureImage;
end;

procedure TModiLessForm.EnableCountdownTimer(Enable: Boolean);
begin
  Countdown.Enabled := Enable;
end;

procedure TModiLessForm.ParseSetCookie;
var
  BeginPos, EndPos: Integer;
  AnyText: string;
begin
  if SetCookie <> '' then
  begin
    BeginPos := Pos('JSESSIONID', SetCookie);
    if BeginPos > 0 then
    begin
      AnyText := Copy(SetCookie, BeginPos, MaxInt);
      EndPos := Pos(';', AnyText);
      if EndPos > 0 then
        SessionCookie := Copy(AnyText, BeginPos, EndPos - 1)
      else SessionCookie := AnyText;
    end;
  end;
end;

procedure TModiLessForm.CancelLblMouseEnter(Sender: TObject);
begin
  CancelColor := $FFFFFFFF;
  CancelImage := CancelImageEnter;
  UpdateLayered;
end;

procedure TModiLessForm.CancelLblMouseLeave(Sender: TObject);
begin
  CancelColor := $FF000000;
  CancelImage := CancelImageLeave;
  UpdateLayered;
end;

function TModiLessForm.ShowModalForm: Integer;
begin
  LoaderTimer.Enabled := True;
  Result := Self.ShowModal;
end;

procedure TModiLessForm.LoaderTimerTimer(Sender: TObject);
begin
  LoaderTimer.Enabled := False;
  BackColor := IniFile.ReadInteger(sGeneral, sBackColor, Integer($00000000));
  BackOpacity := IniFile.ReadInteger(sGeneral, sBackOpacity, Integer($C0));
  GdiEdit.Edit.Text := '';
  GdiEdit.Invalidate;
  UpdateLayered;
  ShowFormEffect(OpacityMax);
  EnableCountdownTimer(True);
end;

procedure TModiLessForm.ShowFormEffect(const Max: Integer);
begin
  if EyMainForm.EnableFadeEffect then
    FadeInEffect(DefOpacityStep, DefOpacityWait, Max)
  else begin
    Opacity := Max;
    UpdateMainWindow;
  end;
end;

procedure TModiLessForm.HideFormEffect(const Min: Integer);
begin
  if EyMainForm.EnableFadeEffect then
    FadeOutEffect(DefOpacityStep, DefOpacityWait, Min)
  else begin
    Opacity := Min;
    UpdateMainWindow;
  end;
end;

procedure TModiLessForm.PaintButtons;
begin
  if CloseBtn.Visible then
  begin
    DrawImageTo(DrawCanvas, CloseBtn.Left, CloseBtn.Top,
      CloseImage.GetWidth, CloseImage.GetHeight, CloseImage);
  end;
end;

procedure TModiLessForm.PaintEdit;
begin
  GdiEdit.Repaint;
  GdiEdit.Paint(DrawCanvas);
end;

procedure TModiLessForm.FormHide(Sender: TObject);
begin
  DoneModiLessForm;
  HideFormEffect(OpacityMin);
end;

procedure TModiLessForm.FormShow(Sender: TObject);
begin
  SetWindowPos(Self.Handle, HWND_TOP or HWND_TOPMOST, 0, 0, 0, 0,
    SWP_NOMOVE or SWP_NOSIZE or SWP_FRAMECHANGED);
  GdiEdit.SendToBack;
  EntryEdit.SetFocus;
end;

procedure TModiLessForm.EntryEditChange(Sender: TObject);
begin
  UpdateLayered;
end;

procedure TModiLessForm.PaintOk;
{
var
  OkColor: Cardinal;}
begin
  if OkLbl.Visible then
  begin
    DrawImageTo(DrawCanvas, OkLbl.Left, OkLbl.Top,
      OkImage.GetWidth, OkImage.GetHeight, OkImage);
    {
    if CancelLbl.Enabled then CancelColor := aclYellow
    else CancelColor := aclGray;
    PaintLabelTo(DrawCanvas, CancelLbl, CancelLbl.Caption,
      StringAlignmentNear, CancelColor);
    }
  end;
end;

procedure TModiLessForm.OkLblMouseEnter(Sender: TObject);
begin
  OkImage := OkImageEnter;
  UpdateLayered;
end;

procedure TModiLessForm.OkLblMouseLeave(Sender: TObject);
begin
  OkImage := OkImageLeave;
  UpdateLayered;
end;

procedure TModiLessForm.OkLblClick(Sender: TObject);
begin
  UserCanceled := True;
  ModalResult := mrOk;
  HideForm;
end;

procedure TModiLessForm.SetFormStyleEx;
var
  StyleEx: Cardinal;
begin
  StyleEx := GetWindowLong(Handle, GWL_EXSTYLE);
  if StyleEx and WS_EX_LAYERED = 0 then
    SetWindowLong(Handle, GWL_EXSTYLE, StyleEx or WS_EX_LAYERED);
end;

procedure TModiLessForm.AllocateDrawItems;
begin
  BackBrush := TGPSolidBrush.Create($60000000);
  BackPen := TGPPen.Create($8F808080);
end;

procedure TModiLessForm.ReleaseDrawItems;
begin
  if Assigned(BackBrush) then FreeAndNil(BackBrush);
  if Assigned(BackPen) then FreeAndNil(BackPen);
end;

end.

