{
   This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later 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 General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}
unit Umyctrls;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ExtCtrls, commctrl;

type

  Tmyhintwindow = class(THintWindow)
  private
    showTimer:TTimer;
    hideTimer:TTimer;
    Fgrp:TGraphic;
    Fgrp_w,Fgrp_h:integer;
//    Fstartpos:tpoint;

    procedure showTimerOnTimer(sender:tobject);
    procedure hideTimerOnTimer(sender:tobject);
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
    procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
  protected
    procedure Paint; override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
  public
    olddata:pointer;
    msglist:tstringlist;
    NoStretch:boolean;

    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
    procedure DoActivateHint(data:pointer;
        grp:TGraphic=nil;size:integer=0;showtime:integer=350);
    procedure DoDeActive(olddatanil:boolean=true);
  end;

implementation

{Tmyhintwindow}
constructor Tmyhintwindow.Create(AOwner : TComponent);
begin
  inherited;
  self.DoubleBuffered:=true;
  msglist:=tstringlist.Create;
  olddata:=nil;
  NoStretch:=false;

  hideTimer:=TTimer.Create(self);
  hideTimer.Interval:=10000;
  hideTimer.OnTimer:=hideTimerOnTimer;
  hideTimer.Enabled:=false;

  showTimer:=TTimer.Create(self);
  showTimer.OnTimer:=showTimerOnTimer;
  showTimer.Enabled:=false;

  ActivateHint(rect(0,0,0,0),'');
end;

destructor Tmyhintwindow.Destroy;
begin
  msglist.Free;
  hideTimer.Free;
  inherited;
end;

procedure Tmyhintwindow.hideTimerOnTimer(sender:tobject);
begin
  hideTimer.Enabled:=false;
  DoDeActive(sender<>nil);
end;

procedure Tmyhintwindow.showTimerOnTimer(sender:tobject);
var
  r,r1:trect;
  s,s1:string;
  i,w,h:integer;
  pt:tpoint;
  tw:integer;
begin
  showTimer.Enabled:=false;
//  pt:=mouse.CursorPos;
//  if (abs(Fstartpos.X-pt.X)>50) or (abs(Fstartpos.Y-pt.Y)>50) then
//    exit;

  w:=0;
  for i:=0 to msglist.Count-1 do begin
    s1:=msglist.Strings[i];
    tw:=Canvas.TextWidth(s1);
    if tw>w then w:=tw
  end;
  w:=w+8;
  h:=Canvas.TextHeight('gh')*msglist.Count;
  h:=h+14;

  r.Left := Mouse.CursorPos.X;
  r.Right := r.Left + w + 20;
  r.Top:= Mouse.CursorPos.Y + 15;
  r.Bottom := r.Top + h;
  if Fgrp<>nil then begin
    r.Bottom := r.Bottom + 3 + Fgrp_h;
    if r.Right-r.Left < Fgrp_w then
      r.Right:=r.Left+Fgrp_w+20;
  end;

  ActivateHint(r,'');
  hideTimer.Enabled:=true;
end;

procedure Tmyhintwindow.DoActivateHint(data:pointer;
    grp:TGraphic=nil;size:integer=0;showtime:integer=350);
begin
  Fgrp:=grp;
  if Fgrp<>nil then begin
    Fgrp_w:=Fgrp.Width;
    Fgrp_h:=Fgrp.Height;
  end;
  if size>0 then begin
    Fgrp_w:=size;
    Fgrp_h:=size;
  end;
//  Fstartpos:=mouse.CursorPos;
  olddata:=data;

  hideTimerOnTimer(nil);
  showTimer.Interval:=showtime;
  showTimer.Enabled:=true;
end;

procedure Tmyhintwindow.DoDeActive(olddatanil:boolean=true);
begin
  self.ReleaseHandle;
  if showTimer.Enabled then showTimer.Enabled:=false;
  if olddatanil then
    olddata:=nil;
end;

procedure Tmyhintwindow.WMNCHitTest(var Message: TWMNCHitTest);
begin
  Message.Result := HTTRANSPARENT;
end;

procedure Tmyhintwindow.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  Message.Result := 1;
end;

procedure Tmyhintwindow.MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer);
begin
  DoDeActive;
  inherited;
end;

procedure Tmyhintwindow.Paint;
var
  r,cr:trect;
  i,h:integer;
  s1:string;
begin
  canvas.Brush.Color:=clInfoBk;
  canvas.FillRect(ClientRect);

  h:=Canvas.TextHeight('gh');
  for i:=0 to msglist.Count-1 do begin
    s1:=msglist.Strings[i];
    canvas.TextOut(4,7+(h*i),s1);
  end;

  if Fgrp<>nil then begin
    cr:=ClientRect;
    r.Left:=((cr.Right-cr.Left) div 2)-(Fgrp_w div 2);
    r.Right:=r.Left+Fgrp_w;
    r.Top:=cr.Bottom-Fgrp_h;
    r.Bottom:=cr.Bottom;
    if NoStretch then
      Canvas.Draw(r.Left,r.Top,Fgrp)
    else
      Canvas.StretchDraw(r,Fgrp);
  end;
end;

end.
