Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Style Manager - Darstellung TButton (https://www.delphipraxis.net/187465-style-manager-darstellung-tbutton.html)

Jens Hartmann 2. Dez 2015 09:02

Style Manager - Darstellung TButton
 
Hallo zusammen,

ich habe mal ein wenig mit dem "Erscheinungsbild" meiner Anwendung gespielt. In XE2 habe ich ja die Möglichkeit, verschiedene Styles auszuwählen. Jetzt ist mir aufgefallen, wenn ich z.B.

Delphi-Quellcode:
  TStyleManager.TrySetStyle('Iceberg Classico');
verwende, dann erscheinen meine Button in einem hellen grau. Bei Maus-Move Ereignis, färbt der Button sich blaulich. Verlässt die Maus den Button wieder, wird er wieder grau.

Bei einem Button.Click Event, wird der Button ebenfalls blaulich, bleibt aber in diesem blaulich.

Ist das ein BUG in den Styles oder kann man das beeinflussen?

Gruß Jens

4dk2 2. Dez 2015 09:54

AW: Style Manager - Darstellung TButton
 
Hey,
schau dir mal VCLStyleViewer.exe und BitmapStyleDesigner.exe in c:\Program Files\Embarcadero\RAD Studio\(deineversion)\bin\
an.
Er bleibt blau, weil er dann den Focus hat. Also der gepunktete Rahmen wenn du keinen Style verwendest.

Einen Bug hat der TButton jedoch, und zwar wenn du im buttonOnclick ihn auf enable=false setzt und dann wieder auf true.
Dann bleibt er blau, auch wenn ein anderes elemnet den focus hat.

Falls du dafür ne Lösung brauchst, meld dich nochmal.

Jens Hartmann 2. Dez 2015 10:58

AW: Style Manager - Darstellung TButton
 
Zitat:

Zitat von 4dk2
Einen Bug hat der TButton jedoch, und zwar wenn du im buttonOnclick ihn auf enable=false setzt und dann wieder auf true.
Dann bleibt er blau, auch wenn ein anderes elemnet den focus hat.

Falls du dafür ne Lösung brauchst, meld dich nochmal.

Genau das ist mein Problem. Je nach Status "Enable" ich die Button und dann entseht genau das Problem...

Gruß Jens

4dk2 2. Dez 2015 11:11

AW: Style Manager - Darstellung TButton
 
OK, dann wird es jetzt nen bisl komplizierter:
du musst eine unit anlegen z.b. uButtonFix.pas

die musst du dann amn besten als letztes element in der Form unit einbinden.
und in der brauchst du dann folgenden kode.
Das ist nen auszug aus meiner VCLStyleFix unit, ich hoffe das funktioniert soweit, sonst nochmal melden :)
Die Paint Routine hab ich auhc nicht selber programmiert, sondern nur um den FocusBug erweitert.
Was die Routine vorher behandelt hat sind unterschiedliche Bugs wenn man noch nen Image via ImageIndex nutzt.

interessant könnte für dich auch noch
https://github.com/RRUZ/vcl-styles-utils
sein.
Dort werden auch die Bugs behoben (bis auf den Focusfix) und Emba selber hat die in XE10 eingebunden.



Delphi-Quellcode:

  TCustomButtonH = class(TCustomButton);

  // we need this helper to access some strict private fields
  TButtonStyleHookHelper = class Helper for TButtonStyleHook
  protected
    function Pressed: Boolean;
    function DropDown: Boolean;
  end;

  // to avoid writting a lot of extra code we are to use TButtonStyleHook class and override the paint method
  TButtonStyleHookFix = class(TButtonStyleHook)
  protected
    procedure Paint(Canvas: TCanvas); override;
  end;

implementation

{ TButtonStyleHookHelper }

function TButtonStyleHookHelper.DropDown: Boolean;
begin
  Result := Self.FDropDown;
end;

function TButtonStyleHookHelper.Pressed: Boolean;
begin
  Result := Self.FPressed;
end;




{ TButtonStyleHookFix }

procedure TButtonStyleHookFix.Paint(Canvas: TCanvas);
var
  LDetails: TThemedElementDetails;
  DrawRect: TRect;
  pbuttonImagelist: BUTTON_IMAGELIST;
  IW, IH, IY: Integer;
  LTextFormatFlags: TTextFormatFlags;
  ThemeTextColor: TColor;
  Buffer: string;
  BufferLength: Integer;
  SaveIndex: Integer;
  X, Y, I: Integer;
  BCaption: String;
  ctFocused: Boolean;
begin

  if StyleServices.Available then
  begin
    BCaption := Text;
    ctFocused := Control.Focused;


    if Pressed then
      LDetails := StyleServices.GetElementDetails(tbPushButtonPressed)
    else if MouseInControl and Control.Enabled then
      LDetails := StyleServices.GetElementDetails(tbPushButtonHot)
    else if ctFocused and Control.Enabled then
      LDetails := StyleServices.GetElementDetails(tbPushButtonDefaulted)
    else if Control.Enabled then
      LDetails := StyleServices.GetElementDetails(tbPushButtonNormal)
    else
      LDetails := StyleServices.GetElementDetails(tbPushButtonDisabled);

    DrawRect := Control.ClientRect;
    StyleServices.DrawElement(Canvas.Handle, LDetails, DrawRect);

    if Button_GetImageList(Handle, pbuttonImagelist) and (pbuttonImagelist.himl <> 0) and
      ImageList_GetIconSize(pbuttonImagelist.himl, IW, IH) then
    begin
      if (GetWindowLong(Handle, GWL_STYLE) and BS_COMMANDLINK) = BS_COMMANDLINK then
        IY := DrawRect.Top + 15
      else
        IY := DrawRect.Top + (DrawRect.Height - IH) div 2;

      // here the image is drawn properly according to the ImageAlignment value
      case TCustomButton(Control).ImageAlignment of
        Vcl.StdCtrls.iaLeft:
          begin
            ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, DrawRect.Left + 3, IY, ILD_NORMAL);
            Inc(DrawRect.Left, IW + 3);
          end;
        Vcl.StdCtrls.iaRight:
          begin
            ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, DrawRect.Right - IW - 3, IY, ILD_NORMAL);
            Dec(DrawRect.Right, IW - 3);
          end;

        Vcl.StdCtrls.iaCenter:
          begin
            ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, (DrawRect.Right - IW) div 2, IY, ILD_NORMAL);
          end;

        Vcl.StdCtrls.iaTop:
          begin
            ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, (DrawRect.Right - IW) div 2, 3, ILD_NORMAL);
          end;

        Vcl.StdCtrls.iaBottom:
          begin
            ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, (DrawRect.Right - IW) div 2,
              (DrawRect.Height - IH) - 3, ILD_NORMAL);
          end;

      end;

    end;

    if (GetWindowLong(Handle, GWL_STYLE) and BS_COMMANDLINK) = BS_COMMANDLINK then
    begin
      if pbuttonImagelist.himl = 0 then
        Inc(DrawRect.Left, 35);

      Inc(DrawRect.Top, 15);
      Inc(DrawRect.Left, 5);
      Canvas.Font := TCustomButtonH(Control).Font;
      Canvas.Font.Style := [];
      Canvas.Font.Size := 12;
      LTextFormatFlags := TTextFormatFlags(DT_LEFT);
      if StyleServices.GetElementColor(LDetails, ecTextColor, ThemeTextColor) then
        Canvas.Font.Color := ThemeTextColor;
      StyleServices.DrawText(Canvas.Handle, LDetails, BCaption, DrawRect, LTextFormatFlags, Canvas.Font.Color);
      SetLength(Buffer, Button_GetNoteLength(Handle) + 1);
      if Length(Buffer) <> 0 then
      begin
        BufferLength := Length(Buffer);
        if Button_GetNote(Handle, PChar(Buffer), BufferLength) then
        begin
          LTextFormatFlags := TTextFormatFlags(DT_LEFT or DT_WORDBREAK);
          Inc(DrawRect.Top, Canvas.TextHeight('Wq') + 2);
          Canvas.Font.Size := 8;
          StyleServices.DrawText(Canvas.Handle, LDetails, Buffer, DrawRect, LTextFormatFlags, Canvas.Font.Color);
        end;
      end;

      if pbuttonImagelist.himl = 0 then
      begin
        if Pressed then
          LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyphPressed)
        else if MouseInControl then
          LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyphHot)
        else if Control.Enabled then
          LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyphNormal)
        else
          LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyphDisabled);
        DrawRect.Right := 35;
        DrawRect.Left := 3;
        DrawRect.Top := 10;
        DrawRect.Bottom := DrawRect.Top + 32;
        StyleServices.DrawElement(Canvas.Handle, LDetails, DrawRect);
      end;

    end
    else if (GetWindowLong(Handle, GWL_STYLE) and BS_SPLITBUTTON) = BS_SPLITBUTTON then
    begin
      Dec(DrawRect.Right, 15);
      DrawControlText(Canvas, LDetails, Text, DrawRect, DT_VCENTER or DT_CENTER);
      if DropDown then
      begin
        LDetails := StyleServices.GetElementDetails(tbPushButtonPressed);
        SaveIndex := SaveDC(Canvas.Handle);
        try
          IntersectClipRect(Canvas.Handle, Control.Width - 15, 0, Control.Width, Control.Height);
          DrawRect := Rect(Control.Width - 30, 0, Control.Width, Control.Height);
          StyleServices.DrawElement(Canvas.Handle, LDetails, DrawRect);
        finally
          RestoreDC(Canvas.Handle, SaveIndex);
        end;
      end;

      with Canvas do
      begin
        Pen.Color := StyleServices.GetSystemColor(clBtnShadow);
        MoveTo(Control.Width - 15, 3);
        LineTo(Control.Width - 15, Control.Height - 3);
        if Control.Enabled then
          Pen.Color := StyleServices.GetSystemColor(clBtnHighlight)
        else
          Pen.Color := Font.Color;
        MoveTo(Control.Width - 14, 3);
        LineTo(Control.Width - 14, Control.Height - 3);
        Pen.Color := Font.Color;
        X := Control.Width - 8;
        Y := Control.Height div 2 + 1;
        for I := 3 downto 0 do
        begin
          MoveTo(X - I, Y - I);
          LineTo(X + I + 1, Y - I);
        end;
      end;

    end
    else
    begin
      // finally the text is aligned and drawn depending of the value of the ImageAlignment property
      case TCustomButton(Control).ImageAlignment of
        Vcl.StdCtrls.iaLeft, Vcl.StdCtrls.iaRight, Vcl.StdCtrls.iaCenter:
          DrawControlText(Canvas, LDetails, BCaption, DrawRect, DT_VCENTER or DT_CENTER);
        Vcl.StdCtrls.iaBottom:
          DrawControlText(Canvas, LDetails, BCaption, DrawRect, DT_TOP or DT_CENTER);
        Vcl.StdCtrls.iaTop:
          DrawControlText(Canvas, LDetails, BCaption, DrawRect, DT_BOTTOM or DT_CENTER);
      end;
    end;
  end;
end;

initialization

// AUSNAHMEN /FIX:
TStyleManager.Engine.RegisterStyleHook(TButton, TButtonStyleHookFix);

end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz