Make a skinned hint in delphi…mmmm is this a hard thing? Of course not all you had to do is:
1) Create a new unit and put the fallowing code into it
unit skinedhint;
interface
uses
Windows, Messages, Classes, Graphics, Controls,Forms,
Dialogs, ExtCtrls,math;
type
THintStyle = (hsXP, hsVista);
type
TMyHintWindow = class(THintWindow)
private
FBitmap: TBitmap;
FRegion: THandle;
procedure FreeRegion;
protected
procedure CreateParams (var Params: TCreateParams); override;
procedure Paint; override;
procedure Erase(var Message: TMessage); message WM_ERASEBKGND;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure ActivateHint(Rect: TRect; const AHint: String); Override;
end;
var
HintStyle: THintStyle;
implementation
uses skinunit;
constructor TMyHintWindow.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FBitmap := TBitmap.Create;
FBitmap.PixelFormat := pf24bit;
end;
destructor TMyHintWindow.Destroy;
begin
FBitmap.Free;
FreeRegion;
inherited;
end;
procedure TMyHintWindow.CreateParams(var Params: TCreateParams);
const
CS_DROPSHADOW = $20000;
begin
inherited;
Params.Style := Params.Style - WS_BORDER;
Params.WindowClass.Style := Params.WindowClass.style or CS_DROPSHADOW;
end;
procedure TMyHintWindow.FreeRegion;
begin
if FRegion 0 then
begin
SetWindowRgn(Handle, 0, True);
DeleteObject(FRegion);
FRegion := 0;
end;
end;
procedure TMyHintWindow.ActivateHint(Rect: TRect; const AHint: String);
begin
Caption := AHint;
Canvas.Font := Screen.HintFont;
FBitmap.Canvas.Font := Screen.HintFont;
canvas.Font.Color:=clred;
DrawText(Canvas.Handle, PChar(Caption), Length(Caption), Rect, DT_CALCRECT or DT_NOPREFIX);
case HintStyle of
hsVista:
begin
Width := (Rect.Right - Rect.Left) + 16;
Height := (Rect.Bottom - Rect.Top) + 10;
end;
hsXP:
begin
Width := (Rect.Right - Rect.Left) + 10;
Height := (Rect.Bottom - Rect.Top) + 6;
end;
end;
FBitmap.Width := Width;
FBitmap.Height := Height;
Left := Rect.Left;
Top := Rect.Top;
FreeRegion;
if HintStyle = hsVista then
begin
with Rect do
FRegion := CreateRoundRectRgn(1, 1, Width, Height, 3, 3);
if FRegion 0 then
SetWindowRgn(Handle, FRegion, True);
end;
SetWindowPos(Handle, HWND_TOPMOST, Left, Top, 0, 0, SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE);
end;
procedure DrawGradientVertical(Canvas: TCanvas; Rect: TRect; FromColor, ToColor: TColor);
var
i, Y: Integer;
R, G, B: Byte;
begin
i := 0;
for Y := Rect.Top to Rect.Bottom - 1 do
begin
R := GetRValue(FromColor) + Ceil(((GetRValue(ToColor) - GetRValue(FromColor)) / Rect.Bottom-Rect.Top) * i);
G := GetGValue(FromColor) + Ceil(((GetGValue(ToColor) - GetGValue(FromColor)) / Rect.Bottom-Rect.Top) * i);
B := GetBValue(FromColor) + Ceil(((GetBValue(ToColor) - GetBValue(FromColor)) / Rect.Bottom-Rect.Top) * i);
Canvas.Pen.Color := RGB(R,G, B);
Canvas.MoveTo(Rect.Left, Y);
Canvas.LineTo(Rect.Right, Y);
Inc(i);
end;
end;
procedure TMyHintWindow.Paint;
var
CaptionRect: TRect;
begin
case HintStyle of
hsVista:
begin
DrawGradientVertical(FBitmap.Canvas, GetClientRect,col.Hint1, col.Hint2); //bitmap
with FBitmap.Canvas do
begin
Font.Color := RGB(242,242,242);
Brush.Style := bsClear;
Pen.Color := RGB(112, 112,112); //ceea ce iconjoara
RoundRect(1, 1, Width - 1, Height - 1, 6, 6);
RoundRect(1, 1, Width - 1, Height - 1, 3, 3);
end;
CaptionRect := Rect(8, 5, Width, Height);
end;
hsXP:
begin
with FBitmap.Canvas do
begin
Font.Color := clBlack;
Brush.Style := bsSolid;
Brush.Color := clInfoBk;
Pen.Color := RGB(255,255,255);
Rectangle(0, 0, Width, Height);
end;
CaptionRect := Rect(5, 3, Width, Height);
end;
end;
DrawText(FBitmap.Canvas.Handle, PChar(Caption), Length(Caption), CaptionRect, DT_WORDBREAK or DT_NOPREFIX);
BitBlt(Canvas.Handle, 0, 0, Width, Height, FBitmap.Canvas.Handle, 0, 0, SRCCOPY);
end;
procedure TMyHintWindow.Erase(var Message: TMessage);
begin
Message.Result := 0;
end;
end.
interface
uses
Windows, Messages, Classes, Graphics, Controls,Forms,
Dialogs, ExtCtrls,math;
type
THintStyle = (hsXP, hsVista);
type
TMyHintWindow = class(THintWindow)
private
FBitmap: TBitmap;
FRegion: THandle;
procedure FreeRegion;
protected
procedure CreateParams (var Params: TCreateParams); override;
procedure Paint; override;
procedure Erase(var Message: TMessage); message WM_ERASEBKGND;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure ActivateHint(Rect: TRect; const AHint: String); Override;
end;
var
HintStyle: THintStyle;
implementation
uses skinunit;
constructor TMyHintWindow.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FBitmap := TBitmap.Create;
FBitmap.PixelFormat := pf24bit;
end;
destructor TMyHintWindow.Destroy;
begin
FBitmap.Free;
FreeRegion;
inherited;
end;
procedure TMyHintWindow.CreateParams(var Params: TCreateParams);
const
CS_DROPSHADOW = $20000;
begin
inherited;
Params.Style := Params.Style - WS_BORDER;
Params.WindowClass.Style := Params.WindowClass.style or CS_DROPSHADOW;
end;
procedure TMyHintWindow.FreeRegion;
begin
if FRegion 0 then
begin
SetWindowRgn(Handle, 0, True);
DeleteObject(FRegion);
FRegion := 0;
end;
end;
procedure TMyHintWindow.ActivateHint(Rect: TRect; const AHint: String);
begin
Caption := AHint;
Canvas.Font := Screen.HintFont;
FBitmap.Canvas.Font := Screen.HintFont;
canvas.Font.Color:=clred;
DrawText(Canvas.Handle, PChar(Caption), Length(Caption), Rect, DT_CALCRECT or DT_NOPREFIX);
case HintStyle of
hsVista:
begin
Width := (Rect.Right - Rect.Left) + 16;
Height := (Rect.Bottom - Rect.Top) + 10;
end;
hsXP:
begin
Width := (Rect.Right - Rect.Left) + 10;
Height := (Rect.Bottom - Rect.Top) + 6;
end;
end;
FBitmap.Width := Width;
FBitmap.Height := Height;
Left := Rect.Left;
Top := Rect.Top;
FreeRegion;
if HintStyle = hsVista then
begin
with Rect do
FRegion := CreateRoundRectRgn(1, 1, Width, Height, 3, 3);
if FRegion 0 then
SetWindowRgn(Handle, FRegion, True);
end;
SetWindowPos(Handle, HWND_TOPMOST, Left, Top, 0, 0, SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE);
end;
procedure DrawGradientVertical(Canvas: TCanvas; Rect: TRect; FromColor, ToColor: TColor);
var
i, Y: Integer;
R, G, B: Byte;
begin
i := 0;
for Y := Rect.Top to Rect.Bottom - 1 do
begin
R := GetRValue(FromColor) + Ceil(((GetRValue(ToColor) - GetRValue(FromColor)) / Rect.Bottom-Rect.Top) * i);
G := GetGValue(FromColor) + Ceil(((GetGValue(ToColor) - GetGValue(FromColor)) / Rect.Bottom-Rect.Top) * i);
B := GetBValue(FromColor) + Ceil(((GetBValue(ToColor) - GetBValue(FromColor)) / Rect.Bottom-Rect.Top) * i);
Canvas.Pen.Color := RGB(R,G, B);
Canvas.MoveTo(Rect.Left, Y);
Canvas.LineTo(Rect.Right, Y);
Inc(i);
end;
end;
procedure TMyHintWindow.Paint;
var
CaptionRect: TRect;
begin
case HintStyle of
hsVista:
begin
DrawGradientVertical(FBitmap.Canvas, GetClientRect,col.Hint1, col.Hint2); //bitmap
with FBitmap.Canvas do
begin
Font.Color := RGB(242,242,242);
Brush.Style := bsClear;
Pen.Color := RGB(112, 112,112); //ceea ce iconjoara
RoundRect(1, 1, Width - 1, Height - 1, 6, 6);
RoundRect(1, 1, Width - 1, Height - 1, 3, 3);
end;
CaptionRect := Rect(8, 5, Width, Height);
end;
hsXP:
begin
with FBitmap.Canvas do
begin
Font.Color := clBlack;
Brush.Style := bsSolid;
Brush.Color := clInfoBk;
Pen.Color := RGB(255,255,255);
Rectangle(0, 0, Width, Height);
end;
CaptionRect := Rect(5, 3, Width, Height);
end;
end;
DrawText(FBitmap.Canvas.Handle, PChar(Caption), Length(Caption), CaptionRect, DT_WORDBREAK or DT_NOPREFIX);
BitBlt(Canvas.Handle, 0, 0, Width, Height, FBitmap.Canvas.Handle, 0, 0, SRCCOPY);
end;
procedure TMyHintWindow.Erase(var Message: TMessage);
begin
Message.Result := 0;
end;
end.
2) Now create a new project and put the fallowing code in the form creation procedure
HintWindowClass := TMyHintWindow;
HintStyle := hsVista;
HintStyle := hsVista;
That’s all…now you’ll have gradient colored hints.

