📄 bsskinhint.pas
字号:
{*******************************************************************}
{ }
{ Almediadev Visual Component Library }
{ BusinessSkinForm }
{ Version 6.07 }
{ }
{ Copyright (c) 2000-2007 Almediadev }
{ ALL RIGHTS RESERVED }
{ }
{ Home: http://www.almdev.com }
{ Support: support@almdev.com }
{ }
{*******************************************************************}
{$P+,S-,W-,R-}
{$WARNINGS OFF}
{$HINTS OFF}
unit bsSkinHint;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
bsSkinData, ExtCtrls, ImgList;
type
TbsSkinHint = class;
TbsSkinHintWindow = class(THintWindow)
private
NewClRect: TRect;
NewLTPoint, NewRTPoint,
NewLBPoint, NewRBPoint: TPoint;
FspHint: TbsSkinHint;
DrawBuffer: TBitMap;
FSD: TbsSkinData;
FRgn: HRGN;
FOldAlphaBlend: Boolean;
FOldAlphaBlendValue: Byte;
procedure WMNCPaint(var Message: TMessage); message WM_NCPAINT;
procedure WMEraseBkGnd(var Msg: TWMEraseBkgnd); message WM_EraseBkgnd;
function FindHintComponent: TBSSKINHINT;
procedure CalcHintSize(Cnvs: TCanvas; S: String; var W, H: Integer);
procedure CalcHintSizeEx(Cnvs: TCanvas; AHint, AHintTitle: String;
AImageIndex: Integer; AImageList: TCustomImageList;
var W, H: Integer);
procedure CheckText(var S: String);
protected
procedure SetHintWindowRegion;
procedure CreateParams(var Params: TCreateParams); override;
procedure Paint; override;
procedure PaintEx;
public
AExtendedStyle: Boolean;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure ActivateHint(Rect: TRect; const AHint: string); override;
procedure ActivateHintEx(Rect: TRect;
const AHintTitle, AHint: string; AImageIndex: Integer; AImageList: TCustomImageList);
end;
TbsSkinHint = class(TComponent)
private
FOnShowHint: TShowHintEvent;
FActive: Boolean;
FSD: TbsSkinData;
HW: TbsSkinHintWindow;
FAlphaBlend: Boolean;
FAlphaBlendValue: Byte;
FAlphaBlendAnimation: Boolean;
FDefaultFont: TFont;
FUseSkinFont: Boolean;
HintTimer: TTimer;
HintText: String;
FLineSeparator: String;
procedure SetActive(Value: Boolean);
procedure SetDefaultFont(Value: TFont);
procedure HintTime1(Sender: TObject);
procedure HintTimeEx1(Sender: TObject);
procedure HintTime2(Sender: TObject);
protected
FHintTitle: String;
FHintImageIndex: Integer;
FHintImageList: TCustomImageList;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
procedure SetSkinData(Value: TbsSkinData);
procedure SelfOnShowHint(var HintStr: string;
var CanShow: Boolean; var HintInfo: THintInfo);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetCursorHeightMargin: Integer;
procedure ActivateHint(P: TPoint; const AHint: string);
procedure ActivateHint2(const AHint: string);
procedure ActivateHintEx(P: TPoint;
const AHintTitle, AHint: string;
AImageIndex: Integer; AImageList: TCustomImageList);
procedure ActivateHintEx2(const AHintTitle, AHint: string;
AImageIndex: Integer; AImageList: TCustomImageList);
function IsVisible: Boolean;
procedure HideHint;
published
property LineSeparator: String read FLineSeparator write FLineSeparator;
property SkinData: TbsSkinData read FSD write SetSkinData;
property Active: Boolean read FActive write SetActive;
property AlphaBlend: Boolean read FAlphaBlend write FAlphaBlend;
property AlphaBlendValue: Byte read FAlphaBlendValue write FAlphaBlendValue;
property AlphaBlendAnimation: Boolean
read FAlphaBlendAnimation write FAlphaBlendAnimation;
property DefaultFont: TFont read FDefaultFont write SetDefaultFont;
property UseSkinFont: Boolean read FUseSkinFont write FUseSkinFont;
property OnShowHint: TShowHintEvent read FOnShowHint write FOnShowHint;
end;
implementation
Uses bsUtils, bsSkinCtrls;
const
CS_DROPSHADOW_ = $20000;
constructor TbsSkinHintWindow.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FRgn := 0;
FOldAlphaBlend := False;
FOldAlphaBlendValue := 0;
end;
destructor TbsSkinHintWindow.Destroy;
begin
inherited Destroy;
if FRgn <> 0 then DeleteObject(FRgn);
end;
procedure TbsSkinHintWindow.CheckText(var S: String);
var
I: Integer;
begin
while Pos(FspHint.LineSeparator, S) <> 0 do
begin
I := Pos(FspHint.LineSeparator, S);
Delete(S, I, Length(FspHint.LineSeparator));
Insert(#10, S, I);
Insert(#13, S, I + 1);
end;
end;
procedure TbsSkinHintWindow.WMNCPaint(var Message: TMessage);
begin
end;
procedure TbsSkinHintWindow.SetHintWindowRegion;
var
TempRgn: HRgn;
MaskPicture: TBitMap;
begin
if (FSD <> nil) and (FSD.HintWindow.MaskPictureIndex <> -1)
then
begin
TempRgn := FRgn;
with FSD.HintWindow do
begin
MaskPicture := TBitMap(FSD.FActivePictures[MaskPictureIndex]);
CreateSkinRegion
(FRgn, LTPoint, RTPoint, LBPoint, RBPoint, ClRect,
NewLTPoint, NewRTPoint, NewLBPoint, NewRBPoint, NewClRect,
MaskPicture, Width, Height);
end;
SetWindowRgn(Handle, FRgn, False);
if TempRgn <> 0 then DeleteObject(TempRgn);
end
else
if FRgn <> 0 then
begin
SetWindowRgn(Handle, 0, False);
DeleteObject(FRgn);
FRgn := 0;
end;
end;
procedure TbsSkinHintWindow.ActivateHintEx(Rect: TRect;
const AHintTitle, AHint: string; AImageIndex: Integer;
AImageList: TCustomImageList);
const
WS_EX_LAYERED = $80000;
AnimationStep = 1;
var
HintWidth, HintHeight: Integer;
CanSkin: Boolean;
i: Integer;
TickCount, ABV: Integer;
S: String;
begin
AExtendedStyle := True;
FspHint := FindHintComponent;
if FspHint = nil then Exit;
if not FspHint.Active then Exit;
CanSkin := ((FspHint.FSD <> nil) and (not FspHInt.FSD.Empty) and
(FspHint.FSD.HintWindow.WindowPictureIndex <> -1));
//
if CanSkin then FSD := FspHint.FSD else FSD := nil;
if FSD <> nil
then
begin
with Canvas, FSD.HintWindow do
begin
if FspHint.UseSkinFont
then
begin
Font.Height := FontHeight;
Font.Name := FontName;
Font.Style := FontStyle;
end
else
Font.Assign(FspHint.FDefaultFont);
end;
end
else
with Canvas do
begin
Font.Assign(FspHint.FDefaultFont);
end;
if (FspHint.SkinData <> nil) and (FspHint.SkinData.ResourceStrData <> nil)
then
Canvas.Font.CharSet := FspHint.SkinData.ResourceStrData.CharSet
else
Canvas.Font.CharSet := FspHint.DefaultFont.CharSet;
S := AHint;
CheckText(S);
Caption := S;
CalcHintSizeEx(Canvas, Caption, AHintTitle, AImageIndex, AImageList,
HintWidth, HintHeight);
Rect.Right := Rect.Left + HintWidth;
Rect.Bottom := Rect.Top + HIntHeight;
//
if (Rect.Right > Screen.Width) then OffsetRect(Rect, -HintWidth - 2, 0);
if (Rect.Bottom > Screen.Height) then OffsetRect(Rect, 0, -HintHeight - 2);
//
BoundsRect := Rect;
//
if CheckW2KWXP
then
begin
if FspHint.AlphaBlend and not FOldAlphaBlend
then
begin
SetWindowLong(Handle, GWL_EXSTYLE,
GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
end
else
if not FspHint.AlphaBlend and FOldAlphaBlend
then
begin
SetWindowLong(Handle, GWL_EXSTYLE,
GetWindowLong(Handle, GWL_EXSTYLE) and (not WS_EX_LAYERED));
end;
FOldAlphaBlend := FspHint.AlphaBlend;
if FspHint.AlphaBlend and FspHint.AlphaBlendAnimation
then
begin
SetAlphaBlendTransparent(Handle, 0);
end;
if (FOldAlphaBlendValue <> FspHint.AlphaBlendValue) and FspHint.AlphaBlend
then
begin
if not FspHint.AlphaBlendAnimation
then
SetAlphaBlendTransparent(Handle, FspHint.AlphaBlendValue);
FOldAlphaBlendValue := FspHint.AlphaBlendValue;
end;
end;
//
SetHintWindowRegion;
SetWindowPos(Handle, HWND_TOPMOST, Rect.Left, Rect.Top, 0,
0, SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE);
Visible := True;
Self.RePaint;
if CheckW2KWXP and FspHint.AlphaBlend and FspHint.AlphaBlendAnimation
then
begin
i := 0;
TickCount := 0;
ABV := FspHint.AlphaBlendValue;
repeat
if (GetTickCount - TickCount > 3)
then
begin
TickCount := GetTickCount;
Inc(i, 20);
if i > ABV then i := ABV;
Self.RePaint;
SetAlphaBlendTransparent(Handle, i);
end;
until i >= ABV;
end;
end;
procedure TbsSkinHintWindow.CalcHintSizeEx(Cnvs: TCanvas; AHint, AHintTitle: String;
AImageIndex: Integer; AImageList: TCustomImageList;
var W, H: Integer);
var
R: TRect;
TH, PW, PH, OX, OY: Integer;
begin
R := Rect(0, 0, 0, 0);
DrawText(Cnvs.Handle, PChar(AHint), -1, R, DT_CALCRECT or DT_LEFT);
W := RectWidth(R);
H := RectHeight(R);
TH := 0;
if AHintTitle <> ''
then
begin
R := Rect(0, 0, 0, 0);
DrawText(Cnvs.Handle, PChar(AHintTitle), -1, R, DT_CALCRECT or DT_LEFT);
H := H + RectHeight(R) + 10;
if RectWidth(R) > W then W := RectWidth(R);
TH := RectHeight(R);
end;
if (AImageList <> nil) and (AImageIndex >= 0) and (AImageIndex < AImageList.Count)
then
begin
W := W + AImageList.Width + 10;
if AImageList.Height + TH + 5 > H then
H := AImageList.Height + TH + 5;
end;
if FSD <> nil
then
begin
W := W + 10;
with FSD.HintWindow do
begin
PW := TBitMap(FSD.FActivePictures[WindowPictureIndex]).Width;
PH := TBitMap(FSD.FActivePictures[WindowPictureIndex]).Height;
W := W + ClRect.Left + (PW - ClRect.Right);
H := H + ClRect.Top + (PH - ClRect.Bottom);
OX := W - PW;
OY := H - PH;
if RTPoint.X + OX < LTPoint.X
then
begin
W := W + LTPoint.X - (RTPoint.X + OX);
OX := W - PW;
end;
if RBPoint.X + OX < LBPoint.X
then
begin
W := W + LBPoint.X - (RBPoint.X + OX);
OX := W - PW;
end;
if LBPoint.Y + OY < LTPoint.Y
then
begin
H := H + LTPoint.Y - (LBPoint.Y + OY);
OY := H - PH;
end;
if RBPoint.Y + OY < RTPoint.Y
then
begin
H := H + RTPoint.Y - (RBPoint.Y + OY);
OX := H - PH;
end;
NewClRect := ClRect;
Inc(NewClRect.Right, OX);
Inc(NewClRect.Bottom, OY);
NewLTPoint := LTPoint;
NewRTPoint := Point(RTPoint.X + OX, RTPoint.Y);
NewLBPoint := Point(LBPoint.X, LBPoint.Y + OY);
NewRBPoint := Point(RBPoint.X + OX, RBPoint.Y + OY);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -