📄 bsskinhint.pas
字号:
procedure TbsSkinHintWindow.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.Style := Params.Style - WS_BORDER;
end;
procedure TbsSkinHintWindow.Paint;
var
R: TRect;
B: TBitMap;
W, H, X, Y: Integer;
begin
//
DrawBuffer := TBitMap.Create;
DrawBuffer.Width := Width;
DrawBuffer.Height := Height;
//
if FSD <> nil
then
with DrawBuffer.Canvas, FSD.HintWindow do
begin
B := TBitMap(FSD.FActivePictures[WindowPictureIndex]);
CreateSkinImageBS(LTPoint, RTPoint, LBPoint, RBPoint,
CLRect, NewLTPoint, NewRTPoint, NewLBPoint, NewRBPoint,
NewClRect, DrawBuffer, B,
Rect(0, 0, B.Width, B.Height), Width, Height, True,
FSD.HintWindow.LeftStretch, FSD.HintWindow.TopStretch,
FSD.HintWindow.RightStretch, FSD.HintWindow.BottomStretch);
end
else
with DrawBuffer.Canvas do
begin
Brush.Color := clInfoBk;
FillRect(ClientRect);
R := ClientRect;
Frame3D(DrawBuffer.Canvas, R, clBtnShadow, clBtnShadow, 1);
end;
//
if FSD <> nil
then
with DrawBuffer.Canvas, FSD.HintWindow do
begin
Brush.Style := bsClear;
if FspHint.UseSkinFont
then
begin
Font.Height := FontHeight;
Font.Style := FontStyle;
Font.Name := FontName;
Font.CharSet := FspHint.DefaultFont.CharSet;
end
else
Font.Assign(FspHint.FDefaultFont);
Font.Color := FontColor;
R := Rect(0, 0, 0, 0);
DrawText(Handle, PChar(Caption), -1, R, DT_CALCRECT or DT_LEFT);
W := RectWidth(R);
H := RectHeight(R);
X := NewClRect.Left + RectWidth(NewClRect) div 2 - W div 2;
Y := NewClRect.Top + RectHeight(NewClRect) div 2 - H div 2;
R := Rect(X, Y, X + W, Y + H);
DrawText(Handle, PChar(Caption), -1, R, DT_LEFT);
end
else
with DrawBuffer.Canvas do
begin
Font.Assign(FspHint.FDefaultFont);
Font.Color := clInfoText;
Brush.Style := bsClear;
R := Rect(2, 2, Width - 2, Height - 2);
DrawText(Handle, PChar(Caption), -1, R, DT_LEFT);
end;
//
Canvas.Draw(0, 0, DrawBuffer);
DrawBuffer.Free;
end;
procedure TbsSkinHintWindow.WMEraseBkGnd(var Msg: TWMEraseBkgnd);
begin
Msg.Result := 1;
end;
constructor TbsSkinHint.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
HintTimer := nil;
FSD := nil;
FDefaultFont := TFont.Create;
FActive := True;
HW := TbsSkinHintWindow.Create(Self);
HW.Visible := False;
if not (csDesigning in ComponentState)
then
begin
HintWindowClass := TbsSkinHintWindow;
with Application do begin
ShowHint := not ShowHint;
ShowHint := not ShowHint;
OnShowHint := SelfOnShowHint;
Application.HintShortPause := 100;
end;
end;
UseSkinFont := True;
end;
destructor TbsSkinHint.Destroy;
begin
HW.Free;
FDefaultFont.Free;
if HintTimer <> nil then HintTimer.Free;
inherited Destroy;
end;
procedure TbsSkinHint.SetDefaultFont(Value: TFont);
begin
FDefaultFont.Assign(Value);
end;
procedure TbsSkinHint.SetSkinData;
begin
FSD := Value;
end;
procedure TbsSkinHint.Notification;
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
end;
procedure TbsSkinHint.SetActive(Value: Boolean);
var
i: Integer;
begin
FActive := Value;
if FActive and (Application.MainForm <> nil)
then
with Application.MainForm do
for i := 0 to ComponentCount-1 do
if (Components[i] is TbsSkinHint) and (Components[i] <> Self)
then
if TbsSkinHint(Components[i]).Active
then TbsSkinHint(Components[i]).Active := False;
if not (csDesigning in ComponentState) and FActive
then Application.OnShowHint := SelfOnShowHint;
end;
procedure TbsSkinHint.SelfOnShowHint(var HintStr: string;
var CanShow: Boolean; var HintInfo: THintInfo);
begin
if Assigned(FOnShowHint) then FOnShowHint(HintStr, CanShow, HintInfo);
end;
function TbsSkinHint.GetCursorHeightMargin: Integer;
var
IconInfo: TIconInfo;
BitmapInfoSize, BitmapBitsSize, ImageSize: DWORD;
Bitmap: PBitmapInfoHeader;
Bits: Pointer;
BytesPerScanline: Integer;
function FindScanline(Source: Pointer; MaxLen: Cardinal;
Value: Cardinal): Cardinal; assembler;
asm
PUSH ECX
MOV ECX,EDX
MOV EDX,EDI
MOV EDI,EAX
POP EAX
REPE SCASB
MOV EAX,ECX
MOV EDI,EDX
end;
begin
{ Default value is entire icon height }
Result := GetSystemMetrics(SM_CYCURSOR);
if GetIconInfo(GetCursor, IconInfo) then
try
GetDIBSizes(IconInfo.hbmMask, BitmapInfoSize, BitmapBitsSize);
Bitmap := AllocMem(DWORD(BitmapInfoSize) + BitmapBitsSize);
try
Bits := Pointer(DWORD(Bitmap) + BitmapInfoSize);
if GetDIB(IconInfo.hbmMask, 0, Bitmap^, Bits^) and
(Bitmap^.biBitCount = 1) then
begin
{ Point Bits to the end of this bottom-up bitmap }
with Bitmap^ do
begin
BytesPerScanline := ((biWidth * biBitCount + 31) and not 31) div 8;
ImageSize := biWidth * BytesPerScanline;
Bits := Pointer(DWORD(Bits) + BitmapBitsSize - ImageSize);
{ Use the width to determine the height since another mask bitmap
may immediately follow }
Result := FindScanline(Bits, ImageSize, $FF);
{ In case the and mask is blank, look for an empty scanline in the
xor mask. }
if (Result = 0) and (biHeight >= 2 * biWidth) then
Result := FindScanline(Pointer(DWORD(Bits) - ImageSize),
ImageSize, $00);
Result := Result div BytesPerScanline;
end;
Dec(Result, IconInfo.yHotSpot);
end;
finally
FreeMem(Bitmap, BitmapInfoSize + BitmapBitsSize);
end;
finally
if IconInfo.hbmColor <> 0 then DeleteObject(IconInfo.hbmColor);
if IconInfo.hbmMask <> 0 then DeleteObject(IconInfo.hbmMask);
end;
end;
procedure TbsSkinHint.HintTime1(Sender: TObject);
var
R: TRect;
P: TPoint;
begin
GetCursorPos(P);
P.Y := P.Y + GetCursorHeightMargin;
R := Rect(P.X, P.Y, P.X, P.Y);
HW.ActivateHint(R, HintText);
HW.Visible := True;
HintTimer.Enabled := False;
HintTimer.Interval := Application.HintHidePause;
HintTimer.OnTimer := HintTime2;
HintTimer.Enabled := True;
end;
procedure TbsSkinHint.HintTime2(Sender: TObject);
begin
HideHint;
end;
procedure TbsSkinHint.ActivateHint2(const AHint: string);
begin
if HintTimer <> nil then HintTimer.Free;
HintText := AHint;
HintTimer := TTimer.Create(Self);
HintTimer.Enabled := False;
HintTimer.Interval := Application.HintPause;
HintTimer.OnTimer := HintTime1;
HintTimer.Enabled := True;
end;
procedure TbsSkinHint.ActivateHint(P: TPoint; const AHint: string);
var
R: TRect;
begin
R := Rect(P.X, P.Y, P.X, P.Y);
HW.ActivateHint(R, AHint);
HW.Visible := True;
end;
function TbsSkinHint.IsVisible: Boolean;
begin
Result := HW.Visible;
end;
procedure TbsSkinHint.HideHint;
begin
if HintTimer <> nil
then
begin
HintTimer.Enabled := False;
HintTimer.Free;
HintTimer := nil;
end;
if HW.Visible
then
begin
HW.Visible := False;
SetWindowPos(HW.Handle, HWND_TOPMOST, 0, 0, 0,
0, SWP_HideWINDOW or SWP_NOACTIVATE or SWP_NOSIZE);
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -