Autor |
Beitrag |
Gausi
Beiträge: 8535
Erhaltene Danke: 473
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Sa 21.02.09 16:38
Ich bastle gerade an einem TSkinButton rum. Basis ist der Colorbutton von hier.
Über Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TSkinButton.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params); with Params do Style := Style or BS_OWNERDRAW; end; | wird geregelt, dass der Button selbst gezeichnet werden kann. Ich würde das gerne zur Laufzeit ändern können, um dadurch den Skin an bzw. auszuschalten.
Oder, wenn das nicht geht - wie erreiche ich in der Zeichenroutine
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure TSkinButton.CNDrawItem(var Message: TWMDrawItem); var SaveIndex: Integer; begin with Message.DrawItemStruct^ do begin SaveIndex := SaveDC(hDC); FCanvas.Lock; try FCanvas.Handle := hDC; FCanvas.Font := Font; FCanvas.Brush := Brush; DrawButton(rcItem, itemState); finally FCanvas.Handle := 0; FCanvas.Unlock; RestoreDC(hDC, SaveIndex); end; end; Message.Result := 1; end; | , dass die Windows-eigene Zeichenroutine aufgerufen wird? Damit der Button wieder wie ein normaler Button aussieht?
_________________ We are, we were and will not be.
Zuletzt bearbeitet von Gausi am Mo 23.02.09 13:05, insgesamt 1-mal bearbeitet
|
|
Gausi
Beiträge: 8535
Erhaltene Danke: 473
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mo 23.02.09 12:18
Keiner ne Idee?
_________________ We are, we were and will not be.
|
|
jaenicke
Beiträge: 19276
Erhaltene Danke: 1741
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 23.02.09 13:09
Meiner Meinung nach ist das nicht möglich. Da ich mir da aber nicht 100%ig sicher bin, hatte ich mich erstmal der Stimme enthalten.
Wenn, dann müsste das ja mit SetWindowLongPtr gehen, eine andere Idee hätte ich da nicht, aber das hatte ich glaube ich ausprobiert.
Ich denke da müsstest du den Button neu erstellen. So habe ich das übrigens auch mal gemacht. Um genau zu sein hatte ich innerhalb der Komponente den eigentlichen Button nochmal darin erstellt. So konnte ich diese Logik etwas verallgemeinern, so dass ich das nicht für jede Komponente neu machen musste.
Eigentlich wollte ich das auch noch auf meine Gradient Components ausdehnen, aber bei denen bin ich ja noch nicht mal zu Farbschemata gekommen bisher.
|
|
Gausi
Beiträge: 8535
Erhaltene Danke: 473
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mo 23.02.09 13:21
jaenicke hat folgendes geschrieben : | Meiner Meinung nach ist das nicht möglich. |
Sowas hatte ich fast befürchtet.
jaenicke hat folgendes geschrieben : | Ich denke da müsstest du den Button neu erstellen. So habe ich das übrigens auch mal gemacht. Um genau zu sein hatte ich innerhalb der Komponente den eigentlichen Button nochmal darin erstellt. |
Ich bin nicht ganz so fit in der Komponenten-Entwicklung - könntest du da mal ein Stück Code posten, auf das ich dann aufbauen kann?
Heisst das, dass der Vorfahrtyp der Komponente einfach TComponent ist, mit einer Property vom Typ TButton, die je nach Property "FullSkin" so oder so gestaltet wird?
_________________ We are, we were and will not be.
|
|
jaenicke
Beiträge: 19276
Erhaltene Danke: 1741
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 23.02.09 14:44
Ja, nicht von TComponent, aber so meinte ich das.
Ich hab mal schnell ne kleine Demo zusammengefrickelt, nur Caption und SetBounds wird derzeit weitergeleitet, die restlichen Properties müssten alle noch entsprechend implementiert werden, aber es zeigt, dass das so funktioniert.
Eine CheckBox schaltet zwischen Skinned ColorButton und Standard Themed um, der linke Button ist ein normaler Button. Wobei ich zumindest hier unter Vista den ColorButton als normalen Button sehe, aber ich hatte auch grad keine Lust mir das genauer anzuschauen was da passiert, also im ColorButton.
Einloggen, um Attachments anzusehen!
|
|
Gausi
Beiträge: 8535
Erhaltene Danke: 473
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mo 23.02.09 16:26
Ah ja, danke.
Das mit TWinControl als Vorfahrtyp ist mir auch schon eingefallen - sonst sind ja auch die Basis-Eigenschaften wie Width und Height erstmal unbekannt.
Das funktioniert soweit ganz gut, auch mit TBitBtn anstelle von TButton (denn so brauche ich das eigentlich). Gut, jetzt habe ich etwas stupide Arbeit vor mir, aber das sollte schaffbar sein. Unter Vista sieht das mit meinem Demoprojekt auch so aus, wie ich es erwarten würde.
_________________ We are, we were and will not be.
|
|
jaenicke
Beiträge: 19276
Erhaltene Danke: 1741
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 23.02.09 17:19
Gausi hat folgendes geschrieben : | Gut, jetzt habe ich etwas stupide Arbeit vor mir, aber das sollte schaffbar sein. |
Das lässt sich ja relativ gut automatisieren. Zuerst Variablennamen bei Read/Write hinschreiben / kopieren, das geht per Makro, dann Strg + Shift + C, jetzt hast du die. Dann statt dem F am Anfang Get/Set für Getter / Setter, Strg + Shift + C, fertig. Dann noch überall eintragen.
Ich glaube das geht so auch ohne Plugins bei D2006 / TD. Ganz automatisch geht das nur, wenn ich irgendwann mal zu meinem Code Assistenten komme...
|
|
delfiphan
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 23.02.09 20:34
Das geht viel einfacher: If-Abfrage o.ä. in TSkinButton.CreateParams einbauen und zum Wechseln TSkinButton.RecreateWnd aufrufen.
|
|
Garf
Beiträge: 54
Erhaltene Danke: 2
D3Prof, D7PE, TDE
|
Verfasst: Di 24.02.09 09:49
Wenn der Button kein Handle haben muss, würde sich ein TSpeedbutton als Grundlage anbieten.
|
|
Gausi
Beiträge: 8535
Erhaltene Danke: 473
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Di 24.02.09 10:16
Der Speedbutton bringt mir nichts, da ich den Button auch per Tastatur ansteuern möchte. Deswegen mach ich das ganze ja: Bei meinem Player sind die ganzen Buttons im Skin-Modus einfach nur TImages, im normalen Modus (und im alten Skinmodus) TBitBtns. Das schalte ich recht umständlich im Code um.
Ich würde das jetzt gerne möglichst abwärtskompatibel einfacher lösen. Und da ist der Workaround von jaenicke glaube ich am Besten geeignet. Wenn ich das Umschalten zwischen BitBtn und Skinbutton in der Komponente erledigen lasse, kann ich den Rest des Codes vereinfachen und übersichtlicher gestalten.
@Delfiphan: Das hört sich auch sehr gut, ist aber für meine Zwecke doch ungeeignet, wie sich mittlerweie herausgestellt hat. Als "Standard-Button" brauche ich den BitBtn, und der hat dieselben CreateParams. Da die Zeichenroutine von BitBtn aber als Private deklariert ist, kann ich die nicht überschreiben oder aufrufen, und den Code aus Delphi2007 in das Delphi7-Projekt zu kopieren dürfte erstens nicht ganz legal sein und funktioniert zweitens nicht, da in D7 eine Unit fehlt, die der neue Source braucht. Die Alternative wäre natürlich, endlich mal auf D2007 umzusteigen, aber da will ich jetzt durch.
_________________ We are, we were and will not be.
|
|
delfiphan
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Di 24.02.09 11:44
TBitBtn ist auch nur von TButton abgeleitet. Schreib doch deine eigene private CNDrawItem message-Methode. Dort zeichnest du dann den Button entweder selbst oder rufst inherited auf. Bei message-Methoden geht das.
|
|
jaenicke
Beiträge: 19276
Erhaltene Danke: 1741
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 24.02.09 11:51
Inherited bringt doch auch nicht den Standardbutton zur Anzeige, oder?
Schließlich muss für das Auslesen BS_OWNERDRAW gesetzt sein, das verhindert aber gleichzeitig das normale Zeichnen des Buttons.
|
|
Gausi
Beiträge: 8535
Erhaltene Danke: 473
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Di 24.02.09 11:57
Da ich den Standard-Button eh nicht gebrauchen kann, sondern halt doch den BitBtn, könnte das funktionieren. Und wenn ich mir das hier so durchlese, bin ich da sehr zuversichtlich.
Ich denke, so langsam lichtet sich der Nebel.
_________________ We are, we were and will not be.
|
|
delfiphan
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Di 24.02.09 16:47
|
|
Gausi
Beiträge: 8535
Erhaltene Danke: 473
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Di 24.02.09 20:03
Sehr schön. Das klappt, und vereinfacht die ganze Sache ganz erheblich.
War zwar ne schwere Geburt, aber jetzt ist der Weg wohl klar, wie ich damit weiter verfahren muss. Z.B. möchte ich die Glyphs mehrzeilig machen, damit man den Play/Pause-Button einfacher handhaben kann - anstelle ein neues Glyph zuzuweisen, ändere ich nur den "Glyphstatus", und der Button macht den Rest von alleine.
Danke euch beiden.
_________________ We are, we were and will not be.
|
|
|