📄 sspeedbutton.pas
字号:
destructor TsSpeedButton.Destroy;
begin
StopFading(Self);
if Assigned(FCommonData) then FreeAndNil(FCommonData);
inherited Destroy;
end;
procedure TsSpeedButton.DoDrawText(var Rect: TRect; Flags: Integer);
var
Text:{$IFDEF TNTUNICODE}WideString{$ELSE}string {$ENDIF};
begin
Text := Caption;
Flags := DrawTextBiDiModeFlags(Flags) and not DT_SINGLELINE;
FCommonData.FCacheBMP.Canvas.Font.Assign(Font);
{$IFDEF TNTUNICODE}
WriteTextExW(FCommonData.FCacheBMP.Canvas, PWideChar(Text), True, Rect,
Flags, FCommonData, CurrentState <> 0);
{$ELSE}
WriteTextEx(FCommonData.FCacheBMP.Canvas, PChar(Text), True, Rect,
Flags,
FCommonData, CurrentState <> 0);
{$ENDIF}
end;
procedure TsSpeedButton.DrawCaption;
var
R, CalcRect : TRect;
begin
if ShowCaption then begin
FCommonData.FCacheBmp.Canvas.Font.Assign(Font);
FCommonData.FCacheBMP.Canvas.Brush.Style := bsClear;
R := CaptionRect;
{ Calculate vertical layout }
CalcRect := R;
DoDrawText(R, DT_EXPANDTABS or DT_WORDBREAK or GetStringFlags(Self, FTextAlignment));
end;
end;
procedure TsSpeedButton.DrawGlyph;
begin
DrawSpeedButtonGlyph(Self);
end;
function TsSpeedButton.GenMargin: integer;
begin
if Margin < 0 then Result := 0 else Result := Margin + 3;
end;
function TsSpeedButton.GlyphHeight: integer;
begin
if (Glyph <> nil) and (Glyph.Height > 0) then begin
Result := Glyph.Height;
end
else if (Images <> nil) and (ImageIndex > -1) then begin
Result := Images.Height;
end
else Result := 0;
end;
function TsSpeedButton.GlyphWidth: integer;
begin
if (Glyph <> nil) and (Glyph.Width > 0) then begin
Result := Glyph.Width div NumGlyphs;
end
else if (Images <> nil) and (ImageIndex > -1) then begin
Result := Images.Width;
end
else Result := 0;
end;
procedure TsSpeedButton.GraphRepaint;
begin
if (csCreating in ControlState) or (csDestroying in ComponentState) or (csLoading in ComponentState) or not Assigned(Parent) or not Visible then Exit;
if Parent.HandleAllocated then begin
SendMessage(Parent.Handle, SM_ALPHACMD, MakeWParam(0, AC_SETGRAPHCONTROL), longint(Self));
Repaint;
SendMessage(Parent.Handle, SM_ALPHACMD, MakeWParam(0, AC_SETGRAPHCONTROL), 0);
end;
end;
function TsSpeedButton.ImgRect: TRect;
var
x, y : integer;
dh, dw : integer;
begin
x := 0;
y := 0;
Result := Rect(0, 0, 0, 0);
dw := (Width - ArrowWidth - GlyphWidth - Spacing * integer(ShowCaption and (GlyphWidth > 0) and (Caption <> '')) - TextRectSize.cx) div 2 - GenMargin;
dh := (Height - GlyphHeight - Spacing * integer(ShowCaption and (GlyphWidth > 0) and (Caption <> '')) - TextRectSize.cy) div 2 - GenMargin;
case Layout of
blGlyphLeft : begin
case Alignment of
taLeftJustify : begin
x := GenMargin;
y := (Height - GlyphHeight) div 2;
end;
taCenter : begin
x := GenMargin + dw;
y := (Height - GlyphHeight) div 2;
end;
taRightJustify : begin
x := GenMargin + 2 * dw;
y := (Height - GlyphHeight) div 2;
end;
end;
end;
blGlyphRight : begin
case Alignment of
taLeftJustify : begin
x := Width - ArrowWidth - GenMargin - 2 * dw - Spacing * integer(ShowCaption and (GlyphWidth > 0) and (Caption <> '')) - GlyphWidth;
y := (Height - GlyphHeight) div 2;
end;
taCenter : begin
x := (Width - ArrowWidth - GlyphWidth + Spacing * integer(ShowCaption and (GlyphWidth > 0) and (Caption <> '')) + TextRectSize.cx) div 2;
y := (Height - GlyphHeight) div 2;
end;
taRightJustify : begin
x := Width - ArrowWidth - GlyphWidth - GenMargin;
y := (Height - GlyphHeight) div 2;
end;
end;
end;
blGlyphTop : begin
x := (Width - ArrowWidth - GlyphWidth) div 2 + 1;
y := GenMargin + dh;
end;
blGlyphBottom : begin
x := (Width - ArrowWidth - GlyphWidth) div 2 + 1;
y := Height - GenMargin - dh - GlyphHeight;
end;
end;
if CurrentState = 2 then begin
inc(x);
inc(y);
end;
// inc(x, integer(FState in [bsDown, bsExclusive]));
// inc(y, integer(FState in [bsDown, bsExclusive]));
Result := Rect(x, y, x + GlyphWidth, y + GlyphHeight);
end;
procedure TsSpeedButton.Loaded;
begin
inherited;
FCommonData.Loaded;
if FCommonData.Skinned then ControlStyle := ControlStyle + [csOpaque];
end;
procedure TsSpeedButton.Paint;
begin
if Assigned(FCommonData.SkinManager) and FCommonData.SkinManager.Active and (FCommonData.SkinIndex < 1) then FCommonData.UpdateIndexes; // v4.84
if (not FCommonData.Skinned) or not (Visible or (csDesigning in ComponentState)) then begin
if Visible or (csDesigning in ComponentState) then UpdateGlyph;
inherited
end
else begin
if (width < 1) or (height < 1) or SkinData.Updating then Exit;
if Assigned(FadeTimer) and FadeTimer.Enabled and Assigned(FadeTimer.TmpBmp) and (FadeTimer.TmpBmp.Width = Width) then begin
BitBlt(Canvas.Handle, 0, 0, Width, Height, FadeTimer.TmpBmp.Canvas.Handle, 0, 0, SRCCOPY);
end
else begin
FCommonData.BGChanged := (FStoredDown <> Down) or FCommonData.BGChanged or FCommonData.HalfVisible;
FStoredDown := Down;
FCommonData.HalfVisible := {not RectInRect(Parent.ClientRect, BoundsRect) optimize - in WM_MOVE set BGChanged if needed !!!} SkinData.RepaintIfMoved;
if not FCommonData.BGChanged then begin
if (FOldNumGlyphs <> NumGlyphs) then begin
FCommonData.BGChanged := True;
FOldNumGlyphs := NumGlyphs;
end
else if (FOldSpacing <> Spacing) then begin
FCommonData.BGChanged := True;
FOldSpacing := Spacing;
end;
end
else begin
FOldNumGlyphs := NumGlyphs;
FOldSpacing := Spacing;
end;
if FCommonData.BGChanged and not FCommonData.UrgentPainting then PrepareCache;
UpdateCorners(FCommonData, 0);
BitBlt(Canvas.Handle, 0, 0, Width, Height, FCommonData.FCacheBmp.Canvas.Handle, 0, 0, SRCCOPY);
end;
end;
end;
procedure TsSpeedButton.PrepareCache;
var
CI : TCacheInfo;
si, mi, w : integer;
Mode, x, y : integer;
R : TRect;
begin
if Self = nil then Exit;
FCommonData.InitCacheBmp;
FCommonData.FCacheBmp.Canvas.Font.Assign(Font);
CI := GetParentCache(FCommonData);
if CI.Ready and (CI.Bmp.Width = 0) then Exit;
case FButtonStyle of
tbsDivider: begin
if CI.Ready
then BitBlt(FCommonData.FCacheBMP.Canvas.Handle, 0, 0, Width, Height, CI.Bmp.Canvas.Handle, Left, Top, SRCCOPY)
else FillDC(FCommonData.FCacheBMP.Canvas.Handle, ClientRect, TsHackedControl(Parent).Color);
si := FCommonData.SkinManager.GetSkinIndex(s_Divider);
if FCommonData.SkinManager.IsValidSkinIndex(si) then begin
mi := FCommonData.SkinManager.GetMaskIndex(si, s_Divider, s_BordersMask);
if Assigned(FCommonData.SkinManager) and FCommonData.SkinManager.IsValidImgIndex(mi) then begin
w := FCommonData.SkinManager.MaskSize(mi).cx;
DrawSkinRect(FCommonData.FCacheBmp,
Rect((Width - w) div 2, 0, (Width + w) div 2, Height),
True, CI, FCommonData.SkinManager.ma[mi], 0, False);
end;
end
else begin
end;
end;
tbsSeparator: begin
if CI.Ready
then BitBlt(FCommonData.FCacheBMP.Canvas.Handle, 0, 0, Width, Height, CI.Bmp.Canvas.Handle, Left, Top, SRCCOPY)
else FillDC(FCommonData.FCacheBMP.Canvas.Handle, ClientRect, TsHackedControl(Parent).Color);
end
else begin
if not CI.Ready then ParentCenterColor := TsHackedControl(Parent).Color else {v4.61} ParentCenterColor := clFuchsia;
if not FDrawOverBorder then begin
PaintItemBG(FCommonData, ci, CurrentState, Rect(0, 0, Width - ArrowWidth, Height), Point(Left, Top), FCommonData.FCacheBMP, integer(Down), integer(Down));
DrawCaption;
DrawGlyph;
Mode := FCommonData.SkinManager.GetMaskIndex(FCommonData.SkinIndex, FCommonData.SkinSection, s_BordersMask);
inc(ci.X, Left);
inc(ci.Y, Top);
if FCommonData.SkinManager.IsValidImgIndex(Mode) then DrawSkinRect(FCommonData.FCacheBMP, Rect(0, 0, Width - ArrowWidth, Height), True, ci, FCommonData.SkinManager.ma[Mode], CurrentState, False);
end
else begin
PaintItem(FCommonData, CI, True, CurrentState, Rect(0, 0, Width - ArrowWidth, Height), Point(Left, Top), FCommonData.FCacheBMP, False, integer(Down), integer(Down));
UpdateCorners(SkinData, CurrentState);
DrawCaption;
DrawGlyph;
end;
if FButtonStyle = tbsDropDown then begin
if ((Assigned(DropDownMenu) and DroppedDown) or Down or (FState in [bsDown, bsExclusive])) then Mode := 2 else if ControlIsActive(FCommonData) then Mode := 1 else Mode := 0;
CI := GetParentCache(FCommonData);
if not FDrawOverBorder then begin
PaintItemBG(FCommonData, ci, Mode, Rect(Width - ArrowWidth, 0, Width, Height), Point(Left + Width - ArrowWidth, Top), FCommonData.FCacheBMP, integer(Down), integer(Down));
inc(ci.X, Left);
inc(ci.Y, Top);
w := FCommonData.SkinManager.GetMaskIndex(FCommonData.SkinIndex, FCommonData.SkinSection, s_BordersMask);
if FCommonData.SkinManager.IsValidImgIndex(Mode) then DrawSkinRect(FCommonData.FCacheBMP, Rect(Width - ArrowWidth, 0, Width, Height), True, ci, FCommonData.SkinManager.ma[w], Mode, False);
end
else begin
PaintItem(FCommonData, CI, True, Mode, Rect(Width - ArrowWidth, 0, Width, Height), Point(Left + Width - ArrowWidth, Top), FCommonData.FCacheBMP, False, integer(Down), integer(Down));
end;
if FCommonData.SkinManager.ConstData.MaskArrowBottom > -1 then with FCommonData.SkinManager do begin
R.Left := Width - ArrowWidth;
R.Right := Width;
x := R.Left + (ArrowWidth - WidthOf(FCommonData.SkinManager.ma[ConstData.MaskArrowBottom].R) div FCommonData.SkinManager.ma[ConstData.MaskArrowBottom].ImageCount) div 2 + 1;// + 2;
y := (Height - HeightOf(ma[ConstData.MaskArrowBottom].R) div (1 + ma[ConstData.MaskArrowBottom].MaskType)) div 2;
CtrlParentColor := clFuchsia;
DrawSkinGlyph(FCommonData.FCacheBmp, Point(x, y), Mode, 1, ma[ConstData.MaskArrowBottom]);
end;
end;
CtrlParentColor := clFuchsia;
if not Enabled then begin
CI := GetParentCache(FCommonData); // v4.61
if CI.Ready and not SkinData.RepaintIfMoved and not FCommonData.UrgentPainting then begin
ParentCenterColor := CI.Bmp.Canvas.Pixels[CI.Bmp.Width div 2, CI.Bmp.Height div 2];
end;
BmpDisabledKind(FCommonData.FCacheBmp, FDisabledKind, Parent, CI, Point(Left, Top));
ParentCenterColor := clFuchsia;
end;
if Assigned(FOnPaint) then FOnPaint(Self, FCommonData.FCacheBmp);
end;
end;
FCommonData.BGChanged := False;
end;
procedure TsSpeedButton.SetAlignment(const Value: TAlignment);
begin
if FAlignment <> Value then begin
FAlignment := Value;
if Visible then FCommonData.BGChanged := True;
GraphRepaint;
end;
end;
procedure TsSpeedButton.SetBlend(const Value: integer);
begin
if FBlend <> Value then begin
if Value < 0 then FBlend := 0 else if Value > 100 then FBlend := 100 else FBlend := Value;
if Visible then FCommonData.BGChanged := True;
GraphRepaint;
end;
end;
procedure TsSpeedButton.SetButtonStyle(const Value: TToolButtonStyle);
begin
if FButtonStyle <> Value then begin
if not (csLoading in ComponentState) then begin
if Value = tbsDropDown then Width := Width + AddedWidth else if FButtonStyle = tbsDropdown then Width := Width - AddedWidth;
end;
FButtonStyle := Value;
if Visible then FCommonData.BGChanged := True;
GraphRepaint;
end;
end;
procedure TsSpeedButton.SetDisabledGlyphKind(const Value: TsDisabledGlyphKind);
begin
if FDisabledGlyphKind <> Value then begin
FDisabledGlyphKind := Value;
if Visible then FCommonData.BGChanged := True;
GraphRepaint;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -