⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bsskinhint.pas

📁 delphi 皮肤控件
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{*******************************************************************}
{                                                                   }
{       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 + -