![]() |
Komponente: noch grün hinter den Ohren
Hi. Ich habe so gut wie keine Erfahrung damit, Komponenten für Delphi zu erstellen, trotzdem will ich mir eine erste Komponente erstellen, die ich einfach immer wieder brauchen werde. War klar, daß ich einige Fehler machen würde. Und hier sind sie, die Fehler und der Code:
Code:
01.unit ColorMixer;
02. 03.interface 04. 05. uses 06. SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, 07. Forms, Dialogs, StdCtrls; 08. 09. type 10. TColorMixer=class(TObject) 11. private 12. FColor1_Original: TColor; 13. FColor2_Added: TColor; 14. FMixStrengthPercentage: Byte; 15. FColor3_Result: TColor; 16. protected 17. function Colorize(Sender: TObject; ColorOriginal, ColorAdded: TColor; PercentageStrength: Byte): TColor; 18. public 19. constructor Create( AOwner: TComponent ); override; 20. property Color1_Original: TColor read FColor1_Original default clBlack; 21. property Color2_Added: TColor read FColor2_Added default clWhite; 22. property MixStrengthPercentage: Byte read FMixStrengthPercentage; 23. published 24. property Color3_Result: TColor read FColor3_Result 25. write SetColor3_Result 26. default clGray; 27. end; 28. 29. procedure Register; 30. 31.implementation 32. 33. constructor TColorMixer.Create(AOwner: TComponent); 34. begin 35. inherited Create(AOwner); 36. end; 37. 38. function TAlpha.Colorize(Sender: TObject; ColorOriginal, ColorAdded: TColor; PercentageStrength: Byte): TColor; 39. var 40. Color1, Color2: LongInt; 41. ValueR, ValueG, ValueB, Value1, Value2: Byte; 42. begin 43. PercentageStrength:=Round(2.55*PercentageStrength); 44. Color1:=ColorToRGB(ColorOriginal); 45. Color2:=ColorToRGB(ColorAdded); 46. Value1:=Byte(Color1); 47. Value2:=Byte(Color2); 48. ValueR:=PercentageStrength*(Value1-Value2) shr 8+Value2; 49. Value1:=Byte(Color1 shr 8); 50. Value2:=Byte(Color2 shr 8); 51. ValueG:=PercentageStrength*(Value1-Value2) shr 8+Value2; 52. Value1:=Byte(Color1 shr 16); 53. Value2:=Byte(Color2 shr 16); 54. ValueB:=PercentageStrength*(Value1-Value2) shr 8+Value2; 55. Result:=(ValueB shl 16)+(ValueG shl 8)+ValueR; 56. end; 57. 58. procedure Register; 59. begin 60. RegisterComponents('Sven Littkowski`s Best',[TColorMixer]); // Eher "Sven Littkowski's Worst"... 61. end; 62. 63.end. Zitat:
|
AW: Komponente: noch grün hinter den Ohren
Mit diesen Hinweisen müsstest du eigentlich auch ohne Sourcecode etwas anfangen können:
[Zeile 10] Komponenten müssen entweder direkt von TComponent oder von einer Nachfahrklasse von TComponent abgeleitet werden. [Zeile 25] Wenn man auf eine Property über eine Setter-Methode zugreifen will, dann muss man diese natürlich auch deklarieren und implementieren. [Zeile 38] Der Name deiner Klasse ist nicht TAlpha, sondern TColorMixer. |
AW: Komponente: noch grün hinter den Ohren
Ja, guter Hinweis. Einerseits bin ich absolut unerfahren mit dem Herstellen von Komponenten, abdererseits (TAlpha) habe ich Elemente aus einem Programm kopiert und war sehr schludrig mit dem korrekten Implementieren.
Einige Fragen habe ich aber noch: 1. Ich will eigentlich erreichen, daß im Object Inspector alle drei Farbfelder und daß prozentuale Mischverhältnis sichtbar sind, davon bis auf Color3 auch alle vom Benutzer manipulierbar. Was muß ich dazu tun? Wie gesagt, ich fange bei 0 an bei den Komponenten... :-( 2. Außerdem würde ich gerne ein Farbergebnis in RealTime haben. Ich ahne, daß ich die Klasse TTimer einfügen muß, liege ich darin richtig? Aber wie bringe ich den Timer dazu, ständig zu laufen? Und wie baue ich überhaupt dieses Dingelchen ein? 3. Und ich würde gerne das Default-Icon in der Komponentenleiste von Delphi durch ein eigenes Icon ersetzen, auch hier totales Neuland. |
AW: Komponente: noch grün hinter den Ohren
Farbe 1,2 und Percentage mit Getter und Setter versehen, Farbe 3 nur mit Getter.
Timer benötigst Du keinen. |
AW: Komponente: noch grün hinter den Ohren
Und in den Settern baust du dann jeweils noch die Aktualisierung von Farbe 3 ein, das sollte glaub ich das sein, was du mit Realtime meinst?
|
AW: Komponente: noch grün hinter den Ohren
"Color3" als Getter = "FColor3"?
|
AW: Komponente: noch grün hinter den Ohren
Delphi-Quellcode:
Die Property sind nur im Objektinspektor sichtbar, wenn diese auch published sind.
property Color1_Original: TColor read FColor1_Original default clBlack;
21. property Color2_Added: TColor read FColor2_Added default clWhite; 22. property MixStrengthPercentage: Byte read FMixStrengthPercentage; Der Setter fehlt natürlich auch. |
AW: Komponente: noch grün hinter den Ohren
Hier der inzwischen veränderte Code.
Code:
unit ColorMixer;
interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TColorMixer=class(TComponent) private FColor1_Original: TColor; FColor2_Added: TColor; FMixStrengthPercentage: Byte; FColor3_Result: TColor; SetColor3_Result: TColor; protected function Colorize(Sender: TObject; ColorOriginal, ColorAdded: TColor; PercentageStrength: Byte): TColor; public constructor Create( AOwner: TComponent); override; published property Color1_Original: TColor read FColor1_Original write SetColor1_Original default clBlack; property Color2_Added: TColor read FColor2_Added write SetColor2_Added default clWhite; property MixStrengthPercentage: Byte read FMixStrengthPercentage write SetFMixStrengthPercentage default 50; property Color3_Result: TColor read FColor3_Result default clGray ; end; procedure Register; implementation constructor TColorMixer.Create(AOwner: TComponent); begin inherited Create(AOwner); end; function TColorMixer.Colorize(Sender: TObject; ColorOriginal, ColorAdded: TColor; PercentageStrength: Byte): TColor; var Color1, Color2: LongInt; ValueR, ValueG, ValueB, Value1, Value2: Byte; begin PercentageStrength:=Round(2.55*PercentageStrength); Color1:=ColorToRGB(ColorOriginal); Color2:=ColorToRGB(ColorAdded); Value1:=Byte(Color1); Value2:=Byte(Color2); ValueR:=PercentageStrength*(Value1-Value2) shr 8+Value2; Value1:=Byte(Color1 shr 8); Value2:=Byte(Color2 shr 8); ValueG:=PercentageStrength*(Value1-Value2) shr 8+Value2; Value1:=Byte(Color1 shr 16); Value2:=Byte(Color2 shr 16); ValueB:=PercentageStrength*(Value1-Value2) shr 8+Value2; Result:=(ValueB shl 16)+(ValueG shl 8)+ValueR; end; procedure Register; begin RegisterComponents('Sven Littkowski`s Best',[TColorMixer]); end; end. Zitat:
|
AW: Komponente: noch grün hinter den Ohren
property Color1_Original: TColor read FColor1_Original write SetColor1_Original default clBlack;
property Color2_Added: TColor read FColor2_Added write SetColor2_Added default clWhite; property MixStrengthPercentage: Byte read FMixStrengthPercentage write SetFMixStrengthPercentage default 50; :wink: Gruß K-H |
AW: Komponente: noch grün hinter den Ohren
22 bis 24: Wenn du schon eine Settermethode angeben willst, dann solltest du diese auch implementieren.
"Field or method identifier expected" = "Feld/Variable oder Methode/Prozedur erwartet" ... bei dir wurde aber was Unbekanntes/Nichtdeklariertes (nicht) gefunden 16: Dieses Feld wurde deklariert, aber du hast es nirgendwo verwendet. |
AW: Komponente: noch grün hinter den Ohren
Schau Dir einmal SHIFT-CTRL-C an (allerdings abhängig von Deiner Delphi-Edition/Version).
|
AW: Komponente: noch grün hinter den Ohren
Vielen Dank für alle bisherigen Antworten, Ihr alle habt mir wesentlich weitergeholfen. Hier der Code, wie er jetzt ist:
unit ColorMixer;
Code:
Die Komponente läßt sich jetzt zwar kompilieren, aber es sind nach Einfügen auf einem Formular nur die zwei zu mischenden Farbfelder sichtbar sowie das Mischungsverhältnis, und auch bei versuchtem Ändern in andere Farben bleiben sie schwarz.
interface
uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TColorMixer=class(TComponent) private FColor1_Original: TColor; FColor2_Added: TColor; FMixStrengthPercentage: Byte; FColor3_Result: TColor; SetColor1_Original: TColor; SetColor2_Added: TColor; SetFMixStrengthPercentage: Byte; protected function Colorize(Sender: TObject; ColorOriginal, ColorAdded: TColor; PercentageStrength: Byte): TColor; public constructor Create( AOwner: TComponent); override; published property Color1_Original: TColor read FColor1_Original write SetColor1_Original default clBlack; property Color2_Added: TColor read FColor2_Added write SetColor2_Added default clWhite; property MixStrengthPercentage: Byte read FMixStrengthPercentage write SetFMixStrengthPercentage default 50; property Color3_Result: TColor read FColor3_Result default clGray ; end; procedure Register; implementation constructor TColorMixer.Create(AOwner: TComponent); begin inherited Create(AOwner); end; function TColorMixer.Colorize(Sender: TObject; ColorOriginal, ColorAdded: TColor; PercentageStrength: Byte): TColor; var Color1, Color2: LongInt; ValueR, ValueG, ValueB, Value1, Value2: Byte; begin PercentageStrength:=Round(2.55*PercentageStrength); Color1:=ColorToRGB(ColorOriginal); Color2:=ColorToRGB(ColorAdded); Value1:=Byte(Color1); Value2:=Byte(Color2); ValueR:=PercentageStrength*(Value1-Value2) shr 8+Value2; Value1:=Byte(Color1 shr 8); Value2:=Byte(Color2 shr 8); ValueG:=PercentageStrength*(Value1-Value2) shr 8+Value2; Value1:=Byte(Color1 shr 16); Value2:=Byte(Color2 shr 16); ValueB:=PercentageStrength*(Value1-Value2) shr 8+Value2; Result:=(ValueB shl 16)+(ValueG shl 8)+ValueR; end; procedure Register; begin RegisterComponents('Sven Littkowski`s Best',[TColorMixer]); end; end. Was ich aber will, ist zu ereichen, daß die Farben geändert werden können, und das auch die resultierende Farbe sofort nach Setzen der zu mischenden Farben und des Farbverhältnisses im Objektinspektor angezeigt wird. |
AW: Komponente: noch grün hinter den Ohren
FColor1_Original und SetColor1_Original sind zwei unterschiedliche Felder.
Wenn du auf ein Blatt was draufschreibst, dann steht das doch auch nicht automatisch auf einem anderem Blatt mit drauf, so daß man dort das Geschriebene wieder ablesen könnte. Ich empfehle einfach mal irgendein Tutorial zum Aufbau von Klassen oder gar eines für die Komponentenentwicklung zu lesen und abzuarbeiten. PS: Getter = eine Funktion, welche einen Wert an ein Property weitergibt Setter = eine Prozedur, welche den Wert von einem Property speicher Felder = eine Variable in einer Klasse Property = eine öffentliche Schnittstelle (virtuelles Feld), welche man auf Felder, Getter oder Setter umleitet. PSS: wir haben auch eine [DELPHI]-Code-Tag (der Button mit dem Delphi-Helm) |
AW: Komponente: noch grün hinter den Ohren
Ja, Kritik angenommen. Du hast sehr Recht, im Grudne genommen sollte ich erst mal etwas darüber lesen. Werde dies auch nachholen, da ich dies auch so sehe.
Danke für die Auflistung der Prozedur- oder Funktionsnamen. Ich werde sie gleich mal ausprobieren. Will die Komponente noch heute fertigstellen. Ich bin eher der Mensch, der Anhand praktischer Übungen lernt. Lesen tue ich auch gerne, aber das Verständnis kommt eher beim praktischen Experimentieren, auch das Interesse übrigens. |
AW: Komponente: noch grün hinter den Ohren
Zitat:
![]() War aber wohl mehr ein Erlkönig :mrgreen: |
AW: Komponente: noch grün hinter den Ohren
Hier ist wieder einmal ein Update meines gegenwärtigen (widerwärtigen?) Codes:
Delphi-Quellcode:
Die Komponente läßt sich kompilieren und in die Delphi-Komponentenleiste einfügen, nur ... bewirken tut sich halt noch nichts, ha ha ha!
unit ColorMixer;
interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TColorMixer=class(TComponent) private FColor1_Original: TColor; FColor2_Added: TColor; FMixStrengthPercentage: Byte; FColor3_Result: TColor; protected procedure SetColor1_Original(Value: TColor); procedure SetColor2_Added(Value: TColor); procedure SetMixStrengthPercentage(Value: Byte); procedure SetColor3_Result(Value: TColor); function Colorize: TColor; public constructor Create( AOwner: TComponent); override; published property Color1_Original: TColor read FColor1_Original write SetColor1_Original default $00000000; property Color2_Added: TColor read FColor2_Added write SetColor2_Added default $00FFFFFF; property MixStrengthPercentage: Byte read FMixStrengthPercentage write SetMixStrengthPercentage default 50; property Color3_Result: TColor read FColor3_Result write SetColor3_Result default $00888888; end; procedure Register; implementation constructor TColorMixer.Create(AOwner: TComponent); begin inherited Create(AOwner); end; procedure TColorMixer.SetColor1_Original(Value: TColor); begin if Value<>FColor1_Original then begin FColor1_Original:=Value; end; end; procedure TColorMixer.SetColor2_Added(Value: TColor); begin if Value<>FColor2_Added then begin FColor2_Added:=Value; end; end; procedure TColorMixer.SetMixStrengthPercentage(Value: Byte); begin if Value<>FMixStrengthPercentage then begin FMixStrengthPercentage:=Value; end; end; procedure TColorMixer.SetColor3_Result(Value: TColor); begin if Value<>FColor3_Result then begin FColor3_Result:=Colorize; end; end; function TColorMixer.Colorize: TColor; var Color1, Color2: LongInt; ValueR, ValueG, ValueB, Value1, Value2: Byte; begin MixStrengthPercentage:=Round(2.55*MixStrengthPercentage); Color1:=ColorToRGB(Color1_Original); Color2:=ColorToRGB(Color2_Added); Value1:=Byte(Color1); Value2:=Byte(Color2); ValueR:=MixStrengthPercentage*(Value1-Value2) shr 8+Value2; Value1:=Byte(Color1 shr 8); Value2:=Byte(Color2 shr 8); ValueG:=MixStrengthPercentage*(Value1-Value2) shr 8+Value2; Value1:=Byte(Color1 shr 16); Value2:=Byte(Color2 shr 16); ValueB:=MixStrengthPercentage*(Value1-Value2) shr 8+Value2; Result:=(ValueB shl 16)+(ValueG shl 8)+ValueR; end; procedure Register; begin RegisterComponents('Sven Littkowski`s Best',[TColorMixer]); end; end. Probleme: - Komponente soll im Objektinspektor gleich beim Farbändern die "Color3_Result" aktualisieren. - Alle drei Farben werden trotz eigener Default-Werte immer als clBlack angezeigt, der Mixwert immer als 0 (statt 50). - Kann das (unnötige) Wählen einer Farbe für "Color3_Result" blockiert werden? - Will ein eigenes Icon für meine Komponente in die Komponentenleiste von Delphi einbinden. PS Sir Rufo, jaaaa, jetzt habe ich's getan, ha ha ha! |
AW: Komponente: noch grün hinter den Ohren
- Komponente soll im Objektinspektor gleich beim Farbändern die "Color3_Result" aktualisieren.
>> einfach Colorize, wobei in Deinem Code die Resultfarbe gar nicht gesetzt wird, in den Settern aufrufen...oder besser den den Getter der ReultFarbe geich an Colorize hängen - Alle drei Farben werden trotz eigener Default-Werte immer als clBlack angezeigt, der Mixwert immer als 0 (statt 50). >> ![]() - Kann das (unnötige) Wählen einer Farbe für "Color3_Result" blockiert werden? >>den Setter entfernen - Will ein eigenes Icon für meine Komponente in die Komponentenleiste von Delphi einbinden. >> ![]() |
AW: Komponente: noch grün hinter den Ohren
Du musst deine Setter anpassen, das mit ihnen auch Color 3 neu berechnet wird, was ja Colorize macht:
Delphi-Quellcode:
Der Setter für Color 3 macht keinen Sinn, da Color drei ja nicht gesetzt werden soll, sondern nur berechet, was ja jetzt die Setter machen, wenn du sie wie oben änderst. Also weg mit
procedure TColorMixer.SetColor1_Original(Value: TColor);
begin if Value<>FColor1_Original then begin FColor1_Original:=Value; FColor3_Result:=Colorize; end; end;
Delphi-Quellcode:
und natürlich die property entsprechend anpassen.
SetColor3_Result(Value: TColor)
[Edit] Bummi war schneller. Kann ich aber gleich selber eine Frage anschieben: Zitat:
|
AW: Komponente: noch grün hinter den Ohren
Zitat:
|
AW: Komponente: noch grün hinter den Ohren
Vielen Dank für die Links. Ich hatte mir die Links
- ![]() - ![]() durchgelesen und versucht, in meiner Unit umzusetzen. Hier erstmal ein Update des gegenwärtigen Codes:
Delphi-Quellcode:
Ich hatte mit dem Image Editor eine Resource hergestellt, zuerst ein Icon, als dieses trotzdem kein Komponentenbild bei der Neukompilierung ergab, dann ein BMP. Nach wie vor kein schönes Bildchen bei Neukompilierung, dafür aber ein unterhaltender STACK OVERFLOW, wenn ich die Komponente auf ein Formular bringe, und das vorzeitige Schließen von Delphi, whuuaaa haa ha ha ha! :-) :-( Der wahnwitzig-tolldreiste Wahn breitet sich nun langsam in mir aus...
unit ColorMixer;
interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TColorMixer=class(TComponent) private FColor1_Original: TColor; FColor2_Added: TColor; FMixStrengthPercentage: Byte; FColor3_Result: TColor; protected procedure SetColor1_Original(Value: TColor); procedure SetColor2_Added(Value: TColor); procedure SetMixStrengthPercentage(Value: Byte); procedure SetColor3_Result(Value: TColor); function Colorize: TColor; public constructor Create( AOwner: TComponent); override; published property Color1_Original: TColor read FColor1_Original write SetColor1_Original stored true default $00000000; property Color2_Added: TColor read FColor2_Added write SetColor2_Added stored true default $00FFFFFF; property MixStrengthPercentage: Byte read FMixStrengthPercentage write SetMixStrengthPercentage stored true default 50; property Color3_Result: TColor read FColor3_Result default $00888888; end; procedure Register; //{$R ColorMixer.res} {$R ColorMixer.dcr} implementation constructor TColorMixer.Create(AOwner: TComponent); var Filename, s: String; begin inherited Create(AOwner); Color1_Original:=$00000000; Color2_Added:=$00FFFFFF; MixStrengthPercentage:=50; // Color3_Result:=$00888888; if not (csDesigning in ComponentState) then begin if (Filename='')or(Filename='.') then begin s:=Application.ExeName; Filename:=ChangeFileExt(s,'.ini'); end; end; end; procedure TColorMixer.SetColor1_Original(Value: TColor); begin if Value<>FColor1_Original then begin FColor1_Original:=Value; Colorize; end; end; procedure TColorMixer.SetColor2_Added(Value: TColor); begin if Value<>FColor2_Added then begin FColor2_Added:=Value; Colorize; end; end; procedure TColorMixer.SetMixStrengthPercentage(Value: Byte); begin if Value<>FMixStrengthPercentage then begin FMixStrengthPercentage:=Value; Colorize; end; end; procedure TColorMixer.SetColor3_Result(Value: TColor); begin if Value<>FColor3_Result then begin FColor3_Result:=Colorize; end; end; function TColorMixer.Colorize: TColor; var Color1, Color2: LongInt; ValueR, ValueG, ValueB, Value1, Value2: Byte; begin MixStrengthPercentage:=Round(2.55*MixStrengthPercentage); Color1:=ColorToRGB(Color1_Original); Color2:=ColorToRGB(Color2_Added); Value1:=Byte(Color1); Value2:=Byte(Color2); ValueR:=MixStrengthPercentage*(Value1-Value2) shr 8+Value2; Value1:=Byte(Color1 shr 8); Value2:=Byte(Color2 shr 8); ValueG:=MixStrengthPercentage*(Value1-Value2) shr 8+Value2; Value1:=Byte(Color1 shr 16); Value2:=Byte(Color2 shr 16); ValueB:=MixStrengthPercentage*(Value1-Value2) shr 8+Value2; Result:=(ValueB shl 16)+(ValueG shl 8)+ValueR; end; procedure Register; begin RegisterComponents('Sven Littkowski`s Best',[TColorMixer]); end; end. Es scheint aber nicht an der eingebundenen Resource zu liegen. Ich hatte wahlweise die eine und dann die andere Resource aus dem Code entfernt und auch aus Delphi's Library. |
AW: Komponente: noch grün hinter den Ohren
nicht über die Setter initialisiseren, sondern so:
Delphi-Quellcode:
constructor TColorMixer.Create(AOwner: TComponent);
var Filename, s: String; begin inherited Create(AOwner); FColor1_Original:=$00000000; FColor2_Added:=$00FFFFFF; FMixStrengthPercentage:=50; |
AW: Komponente: noch grün hinter den Ohren
Vielen Dank, Thomas. Ich habe nun diese Stelle des Codes so modifiziert:
Delphi-Quellcode:
...
published property Color1_Original: TColor read FColor1_Original write SetColor1_Original stored true default $00000000; property Color2_Added: TColor read FColor2_Added write SetColor2_Added stored true default $00FFFFFF; property MixStrengthPercentage: Byte read FMixStrengthPercentage write SetMixStrengthPercentage stored true default 50; property Color3_Result: TColor read FColor3_Result default $00888888; end; procedure Register; //{$R ColorMixer.res} //{$R ColorMixer.dcr} implementation constructor TColorMixer.Create(AOwner: TComponent); var Filename, s: String; begin inherited Create(AOwner); FColor1_Original:=$00000000; FColor2_Added:=$00FFFFFF; FMixStrengthPercentage:=50; // Color3_Result:=$00888888; if not (csDesigning in ComponentState) then begin if (Filename='')or(Filename='.') then begin s:=Application.ExeName; Filename:=ChangeFileExt(s,'.ini'); end; end; end; Nun gibt es zumindest keinen vorzeitigen Abbruch von Delphi wegen STACK OVERFLOW, wenn ich die Komponente auf das Formular ziehe. Aber irgendwo steckt noch immer ein Fehler, denn nun bekomme ich Besuch vom STACK OVERFLOW, sobald ich eine Farbe im Objekt Inspektor verändere. Ich meine, daß dies wahrscheinlich irgendwo bei den PUBLISHED Feldern liegt, muß ich dort auch noch etwas ändern? Sobald ich diese Komponente zum Laufen gebracht habe, werde ich andere Komponenten viel besser entwickeln können, ohne all meine vielen Fragen. :-) Vielen Dank an Euch alle für all die Zeit und Mühe. Ich schätze Eure Unterstützung sehr. |
AW: Komponente: noch grün hinter den Ohren
tja, jetzt knallt es unter anderem da
Delphi-Quellcode:
Du ruft den Setter von FMixStrengthPercentage auf und der dann wieder...Colorizefunction TColorMixer.Colorize: TColor; var Color1, Color2: LongInt; ValueR, ValueG, ValueB, Value1, Value2: Byte; begin MixStrengthPercentage:=
Delphi-Quellcode:
usw....
procedure TColorMixer.SetMixStrengthPercentage(Value: Byte);
begin if Value<>FMixStrengthPercentage then begin FMixStrengthPercentage:=Value; Colorize; end; end; IMHO solltest Du alle Aufrufe von Colorize bis auf den Getter rausschmeißen und die Werte nicht über die Setter setzen, außer diese tun mehr als den Wert zu setzen (wobei Rekursionen zu vermeiden sind >> Stackoverflow) |
AW: Komponente: noch grün hinter den Ohren
Vielen Dank erneut.
So sieht der Code zur Zeit aus:
Delphi-Quellcode:
Die Zeiten des STACK OVERFLOWs sind nun vorbei, allerdings haben die Zeiten des reibungslosen und ordnungsgemäßen Funktionierens auch noch nicht angefangen...
unit ColorMixer;
interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TColorMixer=class(TComponent) private FColor1_Original: TColor; FColor2_Added: TColor; FMixStrengthPercentage: Byte; FColor3_Result: TColor; protected procedure SetColor1_Original(Value: TColor); procedure SetColor2_Added(Value: TColor); procedure SetMixStrengthPercentage(Value: Byte); procedure SetColor3_Result(Value: TColor); function Colorize: TColor; public constructor Create( AOwner: TComponent); override; published property Color1_Original: TColor read FColor1_Original write SetColor1_Original stored true default $00000000; property Color2_Added: TColor read FColor2_Added write SetColor2_Added stored true default $00FFFFFF; property MixStrengthPercentage: Byte read FMixStrengthPercentage write SetMixStrengthPercentage stored true default 50; property Color3_Result: TColor read FColor3_Result default $00888888; end; procedure Register; //{$R ColorMixer.res} //{$R ColorMixer.dcr} implementation constructor TColorMixer.Create(AOwner: TComponent); var Filename, s: String; begin inherited Create(AOwner); FColor1_Original:=$00000000; FColor2_Added:=$00FFFFFF; FMixStrengthPercentage:=50; if not (csDesigning in ComponentState) then begin if (Filename='')or(Filename='.') then begin s:=Application.ExeName; Filename:=ChangeFileExt(s,'.ini'); end; end; end; procedure TColorMixer.SetColor1_Original(Value: TColor); begin if Value<>FColor1_Original then begin FColor1_Original:=Value; end; end; procedure TColorMixer.SetColor2_Added(Value: TColor); begin if Value<>FColor2_Added then begin FColor2_Added:=Value; end; end; procedure TColorMixer.SetMixStrengthPercentage(Value: Byte); begin if Value<>FMixStrengthPercentage then begin FMixStrengthPercentage:=Value; end; end; procedure TColorMixer.SetColor3_Result(Value: TColor); var Color1, Color2: LongInt; ValueR, ValueG, ValueB, Value1, Value2: Byte; begin if Value<>FColor3_Result then begin FColor3_Result:=Colorize; end; end; function TColorMixer.Colorize: TColor; var Color1, Color2: LongInt; ValueR, ValueG, ValueB, Value1, Value2: Byte; begin FMixStrengthPercentage:=Round(2.55*FMixStrengthPercentage); Color1:=ColorToRGB(FColor1_Original); Color2:=ColorToRGB(FColor2_Added); Value1:=Byte(Color1); Value2:=Byte(Color2); ValueR:=FMixStrengthPercentage*(Value1-Value2) shr 8+Value2; Value1:=Byte(Color1 shr 8); Value2:=Byte(Color2 shr 8); ValueG:=FMixStrengthPercentage*(Value1-Value2) shr 8+Value2; Value1:=Byte(Color1 shr 16); Value2:=Byte(Color2 shr 16); ValueB:=FMixStrengthPercentage*(Value1-Value2) shr 8+Value2; result:=(ValueB shl 16)+(ValueG shl 8)+ValueR; end; procedure Register; begin RegisterComponents('Sven Littkowski`s Best',[TColorMixer]); end; end. Ich habe mir meine Gedanken gemacht, warum ich - trotz gelesener Tutorials (siehe Links einige Postings zuvor) und guten Hinweisen zu Teilproblemen - ich nicht weiterkomme. Ich will Euch alle ja auch nicht immer mit meinen Fragen nerven. Ist halt meine allerserte Komponente. Vieleicht würde es mir weiterhelfen, den Code einer einigermaßen vergleichbaren Komponente mir mal durchzulesen. Also von einer Komponente, wo Eingaben gemacht werden, und dadurch ein Ergebnis entsteht. Kennt jemand so eine Komponente? Wenn ich mir deren Quellcode durchlese, würde ich bestimmt dies auch auf meine Komponente anwenden können, hoffe ich. Meine Befürchtung ist, daß man hier denken könnte, ich will es mir einfach machen. Und ich bin der Menschentyp, der gut von funktionierenden Vorbildern lernen kann. Ich suche also eine Beispielskomüponente, die - nicht zu umfangreich ist - Eingaben vom benutzer erwartet - ein davon abhängiges Resultat in einem der Felder liefert. Meine Komponente gibt zur Zeit immer nur ein schwarz zurück... Und auch das Bild für die Komponentenleiste will nicht kommen, deshalb habe ich beide Resourcen erstmal ungültig gemacht (zwei, weil weder das Bitmap noch danach das Icon angezeigt wurden und ich unsicher war). Hatte beide Resourcen (ein Icon und ein Bitmap) im Image Editor als jeweils Resource erstellt. |
AW: Komponente: noch grün hinter den Ohren
Also zuerst mal, ich finde Du maschst das im Vergleich zu vielen Newbies sehr gut, zu anderen hast Du nur einen kleinen Fehler drin.
Delphi-Quellcode:
um Beispiele zu sehen brauchst Du eigentlich nur bei einer Komponente Deiner Wahl mit STRG auf den Klssennamen klicken und den Code einzusehen.
property Color3_Result: TColor read Colorize;
Bei Klick auf TButton landest Du bei TButton = class(TCustomButton) bei Klick auf TCustomButton dann bei TCustomButton = class(TButtonControl) und so weiter... STRG+Shift + Pfeil ab und Du bist in der Implementierung... STRG+Shift + Pfeil auf und Du bist wieder in der Deklaration. |
AW: Komponente: noch grün hinter den Ohren
Super, das hat geholfen! Die Farben funktionieren jetzt so, wie sie es sollen! Gut, daß dieses Forum kompetente Mitglieder hat. Vielen Dank, Thomas.
Ein allerletztes Problem bleibt noch zu lösen: das für die Komponentenleiste vonD elphi als Resource erstellte Bild. Ich hatte es als BMP (und vorsichtshalber gleich auch noch als Icon) in Delphi's Image Editor erstellt. Aber das Einbinden als Resource bewirkt nichts. Hier ein Auszug des entsprechenden Codes:
Delphi-Quellcode:
Ich hatte beide Zeilen jeweils alleine, und auch mal doppelt (zusammen) ausprobiert, aber nach wie vor verwendet Delphi das Standard-Icon. Die Resource-Dateien befinden sich im selben Verzeichnis wie die Unit (Komponente), und benutzen auch den selben Namen vor dem Punkt wie die Hauptdatei ("ColorMixer"). Dies hatte ich so gemacht, nachdem ich mir die in diesem Thread genannten Links zum Thema Resourcen einbinden durchgelesen hatte.
unit ColorMixer;
interface ... procedure Register; //{$R ColorMixer.res} // Icon {$R ColorMixer.dcr} // BMP implementation ... |
AW: Komponente: noch grün hinter den Ohren
z.B. mit dem XN ResourceEditor eine neues Projekt aufmachen, Resource hinzufügen (Bitmap), 24*24 Pixel 8-Bit, den Namen auf TCOLORMIXER festlegen und das ganze als ColorMixer.dcr neben der pas-Datei speichern.
|
AW: Komponente: noch grün hinter den Ohren
Und damit kann dieser Thread geschlossen werden - Problem gelöst!
Vielen großen Dank erneut, Thomas! Ich hatte das folgende falsch gemacht: - Bitmap-Objekt innerhalb der Resource nicht "TColorMixer" benannt - Nicht die richtige Dimension (24x24 Pixel) benutzt Gibt es irgendwo eine Stelle, wo ich die Dateien hochladen kann (ColorMixer.pas und ColorMixer.dcu), um die Komponente allen Interessierten zur Verfügung stellen zu können? |
AW: Komponente: noch grün hinter den Ohren
Es gibt hier eine OpenSource-Sparte, die ist für so etwas gut geeignet.
|
AW: Komponente: noch grün hinter den Ohren
Vielen Dank, bereite Upload vor... :-)
Und außerhalb dieses Forums? Ich kenne nur die "Delphi Super Page" (Polen/USA). Andere gute Sites für den Upload? |
AW: Komponente: noch grün hinter den Ohren
|
AW: Komponente: noch grün hinter den Ohren
Hmmmm..... Kann hier nicht uploaden ("Neues Thema erstellen"), da ich dafür als normaler User nicht die dafür benötigten Rechte habe (bekam die entsprechende Fehlermeldung). Macht aber nichts, ich werde dann halt meine Komponente als FreeWare bei Delphi Super Page und SourceForge und Torry veröffentlichen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:05 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-2025 by Thomas Breitkreuz