Autor Beitrag
ALF Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Fr 05.11.10 13:17 
Hi, hab das mal nur überflogen.
Unabhängig von Pen, der eh nur 1Pixel ist und bleibt, ausser beim '//Rahmen'= BorderSize 3Pixel als Beispiel, sehe ich aber auch nur, das Progress nicht den Border berücksichtigt sondern ebenfalls bei 0 anfängt zu Zeichnen und nicht nach den Border, so auf den ersten Blick.
Denn, wenn der '//Rahmen' 3Pixel=BorderSize breit ist, muss es bei '//Hintergrund und //Fortschritt' Pen=1 und bei 'CalcPixel' berücksichtigt werden oder nicht?

Vom Prinzip her, kommt es zum Schluss auf das selbe herraus wie ich es jetzt mache. //CalcPixel muss den Rahmen beim berechen mit berücksichtigen! so oder so :wink:

Gruss ALf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
buster
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 66
Erhaltene Danke: 7

WIN 7
Delphi 2010 Prof
BeitragVerfasst: Fr 05.11.10 15:22 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
... mir kommen eure Lösungen unnötig kompliziert vor.

Finde ich auch :)

Entweder man berechnet sich die verfügbare Breite über
ausblenden Delphi-Quelltext
1:
UseableWidth := MAXWIDTH - (2 * PENWIDTH);					

und berechnet dann
ausblenden Delphi-Quelltext
1:
FPixels := UseableWidth * FPercent div 100;					

und tut dann halt dergleichen:
ausblenden Delphi-Quelltext
1:
2:
3:
Canvas.Rectangle(10075100+MAXWIDTH, 90);
Canvas.FillRect(Rect(100+PENWIDTH,75+PENWIDTH,100+MAXWIDTH-PENWIDTH,90-PENWIDTH)); // für den Hintergrund
Canvas.FillRect(Rect(100+PENWIDTH,75+PENWIDTH,100+PENWIDTH+FPixels,90-PENWIDTH)); // für den Fortschritt

oder man belässt es einfach bei der alten Fläche und rechnet den Rahmen drumherum noch dazu (wenn es denn möglich ist), in der Art
ausblenden Delphi-Quelltext
1:
2:
3:
Canvas.Rectangle(100-PENWIDTH, 75-PENWIDTH, 100+MAXWIDTH+PENWIDTH, 90+PENWIDTH);
Canvas.FillRect(Rect(100,75,100+MAXWIDTH,90)); // für den Hintergrund
Canvas.FillRect(Rect(100,75,100+FPixels,90)); // für den Fortschritt
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 05.11.10 16:18 
user profile iconbuster hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
FPixels := UseableWidth * FPercent div 100;					
buster
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 66
Erhaltene Danke: 7

WIN 7
Delphi 2010 Prof
BeitragVerfasst: Fr 05.11.10 16:40 
Jaaaa...??? und? Prozentrechnung??? ;) (wenns 50% sind, dann sind es die Anzahl der Pixel mal 50 geteilt durch 100 ohne Rest, oder?)
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 05.11.10 17:19 
Ich nehms zurück. Ich hab da wohl eine Klammer halluziniert :)
buster
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 66
Erhaltene Danke: 7

WIN 7
Delphi 2010 Prof
BeitragVerfasst: Fr 05.11.10 17:21 
jo, ist ja auch schon spääät ;)
ALF Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Sa 06.11.10 01:13 
Habt ihr euch mal das alles angeschaut! Sieht das nicht unübersichtlich aus?
Es gibt nur einen Pen der 1x verändert wird und das ist der für den Rahmen. Danach bleibt der Pen beim Zeichnen 1Pixel gross. Wenn ich jetzt noch Vertikal, von rechts nach links, von oben nach unten und umgekehrt zeichnen will,
müsste ich das alles so eingeben wie @Lucki es macht. Sorry @Lucki, in diesem Fall zu aufwendig und meiner Meinung nach umständlich! Eventuell sogar anfällig irgendwo mal ne Zahl falsch anzugeben!
Da man dies dann in jeder Zeichenroutine wieder eintragen muss.

Ich verwende einfach:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
procedure TGaugeButton.Paint;
var
   TheImage: TBitmap;
   OverlayImage: TBltBitmap;
   PaintRect: TRect;
   Distance: Integer;
begin
    with Canvas do
    begin
       TheImage:= TBitmap.Create;
       try
          TheImage.Height:= Height;
          TheImage.Width:= Width;

         PaintRect:= ClientRect;
         if FBorderStyle = bsSingle then
            InflateRect(PaintRect, -FBorderWidth, -FBorderWidth);

        OverlayImage:= TBltBitmap.Create;
        try
           OverlayImage.MakeLike(TheImage);
           PaintBorder(OverlayImage);                        //Hier wird die BorderFarbe gemallt
           PaintAsBar(OverlayImage, PaintRect);              //hier wird progress gezeichnet
           PaintALink(OverlayImage);                         //speziell für mich 
        
           PaintAsText(OverlayImage, PaintRect);             //speziel für mich           
           TheImage.Canvas.Draw(00, OverlayImage);

        finally
          OverlayImage.Free;
        end;
  
        Canvas.Draw(00, TheImage);
    finally
       TheImage.Destroy;
    end;
end;


procedure TGaugeButton.PaintBorder(AnImage: TBitmap);
begin
    AnImage.Canvas.Brush.Color:= FBorderColor;
    AnImage.Canvas.FillRect(AnImage.Canvas.ClipRect);
end;


procedure TGaugeButton.PaintAsBar(AnImage: TBitmap; PaintRect: TRect);
var
   FillSize: Longint;
   W, I, mergepos: Integer;
   RsValue, GsValue, BsValue, ReValue, GeValue, BeValue: Double;
begin
    W:= PaintRect.Right;
                                                         
    AnImage.Canvas.Brush.Color:= FBackColor;             
    AnImage.Canvas.FillRect(PaintRect);                  
    AnImage.Canvas.Pen.Width:= 1;
    AnImage.Canvas.Brush.Color:= FStartColor;            

     //---------------das ist die einzigste stelle Wo ich was berücksichtigen muss------------///
    Fillsize := trunc(SolveForX(PercentDone, W)*(W - PaintRect.Left) / W +PaintRect.Left);
    //---------------------------------------------------------------------------------------////
                                                           
    AnImage.Canvas.FillRect(Rect(PaintRect.Left, PaintRect.Top, FillSize, PaintRect.Bottom));
end;
Ich persöhnlich finde meine Variante übersichtlicher
Aber na gut, was nun besser ist..???
Wichtig ist das es optimal ist und gut funktioniert. :wink:

Gruss ALf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 06.11.10 04:57 
Also mein Code war nur relativ schnell runtergeschrieben. Ich wollte deutlich machen, dass ich die Berechnung etwas umständlich fand. Mit den Zeichenroutinen kenne ich mich nicht so aus, deswegen kann man da bestimmt noch optimieren bzw. es besser machen.
ALF Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Sa 06.11.10 08:14 
Jo das weiß ich doch :wink:
Die Idee, mit der Formel den evtl Border gleich dort mit zu berücksichtigen, find ich doch nur einfacher, als ihn beim zeichnen zu berücksichtigen. Ob man es nun so macht oder nicht, bleibt doch letztentlich jedem selbst überlassen :mrgreen: :zwinker:

Dabei wollte ich doch nur den Dreisatz noch mal erklärt haben :lol:
Gruss ALf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 06.11.10 11:52 
Ich benutze für sowas lieber die integrierten Möglichkeiten der API, z.B. für Rechtecke und Berechnung des Bereichs der Textausgabe.

Im Anhang nen kleines Beispiel für einen GaugeButton mit Themes (im Programm sind diese nicht akitiviert, nur bei der Komponente). Die drei Trackbars regeln Minimum, Position und Maximum (auch umgekehrt mit Max < Min geht natürlich).

Code zum Zeichnen selbst:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
procedure TGaugeButton.Paint;
var
  DrawRect, ChunkRect, CaptionRect: TRect;
begin
  inherited;
  DrawRect := ClientRect;
  Canvas.Brush.Style := bsClear;
  // progress bar
  InflateRect(DrawRect, -2, -2);
  if FMouseDown then
    OffsetRect(DrawRect, 11);
  ThemeServices.DrawElement(Canvas.Handle, ThemeServices.GetElementDetails(tpBar), DrawRect);
  // progress chunk
  InflateRect(DrawRect, -1, -1);
  ChunkRect := DrawRect;
  if FMax > FMin then
    Dec(ChunkRect.Right, (FMax - FPosition) * (ChunkRect.Right - ChunkRect.Left) div (FMax - FMin))
  else if FMax < FMin then
    Inc(ChunkRect.Left, (FMax - FPosition) * (ChunkRect.Right - ChunkRect.Left) div (FMax - FMin));
  ThemeServices.DrawElement(Canvas.Handle, ThemeServices.GetElementDetails(tpChunk), ChunkRect);
  // caption
  CaptionRect := DrawRect;
  DrawText(Canvas.Handle, PChar(Text), Length(Text), CaptionRect, DT_CENTER or DT_WORDBREAK or DT_CALCRECT);
  InflateRect(DrawRect, - (DrawRect.Right - CaptionRect.Right) div 2,
    - (DrawRect.Bottom - CaptionRect.Bottom) div 2);
  DrawText(Canvas.Handle, PChar(Text), Length(Text), DrawRect, DT_CENTER or DT_WORDBREAK);
end;
Einloggen, um Attachments anzusehen!

Für diesen Beitrag haben gedankt: ALF, BenBE
ALF Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Sa 06.11.10 15:46 
Um Missverständnisse auszuräumen. Meine Komponente(ProgressBar oder Gauge) ist kein Button als solches. Sie beinhaltet lediglich zusätzlich 4 Buttons, die für spezielle Aufgaben bestimmt sind. Darum auch diese private Bezeichnung (GaugeButton) von mir :wink:

Aber Dein Code @jaenicke, die gesamte Gauge als Button zu machen, hat mich natürlich wieder mal voll überzeugt und werde es als Option zusätzlich mit anbieten. Ob Er es dann nutzen will, kann Er ja dann selber entscheiden. :beer:
Für diese Idee ein dickes Danke

Gruss ALf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 06.11.10 15:48 
Genauso kannst du das auch mit mehreren Buttons machen. ;-)
Dann natürlich mit etwas mehr Logik.

Ich wollte vor allem zeigen, dass Windows durchaus fertige Funktionen zu bieten hat um solche Bereiche zu berechnen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 07.11.10 01:38 
Hier einmal ein Beispiel für mehrere Buttons mit Theming und Alphablending. Mir war langweilig und es hat mich interessiert. :D
Einloggen, um Attachments anzusehen!
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 07.11.10 07:23 
Ich hoffe, das handled wenigstens FMin=FMax ;-) Ansonsten nette Beispiele. IIRC gab's auch eine DeflateRect-Funktion o.s.ä. Bin mir da aber grad nicht sicher und hab kein Delphi verfügbar.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 07.11.10 11:17 
user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Ich hoffe, das handled wenigstens FMin=FMax ;-)
Es fängt es ab, ja. Ich behandle es nicht weiter (wozu auch?), aber die Division durch Null verhindere ich.

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
IIRC gab's auch eine DeflateRect-Funktion o.s.ä. Bin mir da aber grad nicht sicher und hab kein Delphi verfügbar.
Wäre mir und Delphi neu. :mrgreen: ;-)
Man kann ja negative Werte an InflateRect übergeben, deshalb braucht man das auch nicht.
ALF Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: So 07.11.10 15:21 
Hi, optisch natürlich super. Würde mich und meine einfache Arbeit um Wochen zurückwerfen, würde ich versuchen es so umzusetzen!
Vom Verstehen(Lerneffekt), was, wie, wo und warum so und nicht so, mal ganz abgesehen!

Gruss ALf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!