Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Wie kommt man intern an die Komponente?


n-regen - Sa 22.07.06 10:47
Titel: Wie kommt man intern an die Komponente?
Hallo!
Ich hoffe, dass ich die Frage am richtigen Ort stelle, wenn nicht, bitte sagen.
Ich schreibe grad an einer neuen Komponente TNImage mit ein paar Zusatzfunktionen.
Wie komme ich jetzt innerhalb der Unit an die Komponente ran, die der User grad auf Form gesetzt hat?
Also:
Man verwendet ein NImage und startet eine Prozedur der Komponente, die auf die Komponente zugreift.
Wenn ich mich unklar ausgedrückt habe bitte schreiben.


n-regen - Sa 22.07.06 10:50

Mir ist was aufgefallen, was vielleicht die Lösung sein könnte:
TNImage.Create(TForm).Picture.Bitmap
Ich weiß jetzt halt nicht, ob das hinhaut.
Was haltet ihr davon?

EDIT:
Delphi hält nix davon ;-)
[Fehler] NImage.pas(44): E2010 Inkompatible Typen: 'TComponent' und 'Class reference'


mkinzler - Sa 22.07.06 11:06

Wenn dann

Delphi-Quelltext
1:
2:
3:
4:
5:
image := TNImage.Create(Form);
  image.owner := Form;
  image.Top := ...;
  ... 
  image.Picture.Bitmap ...


oder

Delphi-Quelltext
1:
2:
3:
4:
 with TNImage.Create(Form) do
begin
  Owner := Form;
  ...


n-regen - Sa 22.07.06 15:13

Äh, mir ist inzwischen aufgefallen, dass man damit ja nur ein NImage erstellt, aber ich will ja auf das zugreifen, das der Programmierer in sein Prog eingebaut hat.


BenBE - Sa 22.07.06 15:16

Self ...


n-regen - Sa 22.07.06 17:06


Delphi-Quelltext
1:
2:
3:
4:
5:
var
  Pict, Bit: TBitmap;
begin
  Bit := Self.Picture.Bitmap;
end;

[Fehler] NImage.pas(44): E2003 Undefinierter Bezeichner: 'Self'
:?: :?: :?:
EDIT:
Zitat:

In der definierenden Deklaration einer Klassenmethode kann mit dem Bezeichner Self auf die Klasse zugegriffen werden, in der die Methode aufgerufen wird (dies kann auch ein Nachkomme der Klasse sein, in der sie definiert ist). Wird die Methode beispielsweise in der Klasse K aufgerufen, hat Self den Typ class of K. Daher können Sie Self nicht für den Zugriff auf Felder, Eigenschaften und normale (Objekt-) Methoden, sondern nur für Aufrufe von Konstruktoren und anderen Klassenmethoden verwenden.


mkinzler - Sa 22.07.06 17:10


Delphi-Quelltext
1:
Form.NImage.                    


n-regen - Sa 22.07.06 17:31

Undefinierter Bezeichner Form
:(


mkinzler - Sa 22.07.06 17:34

Form steht für den Namen der Form und NImage für den des Images.


jaenicke - Sa 22.07.06 17:44

user profile iconn-regen hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
var
  Pict, Bit: TBitmap;
begin
  Bit := Self.Picture.Bitmap;
end;

[Fehler] NImage.pas(44): E2003 Undefinierter Bezeichner: 'Self'
:?: :?: :?:
EDIT:
Zitat:

In der definierenden Deklaration einer Klassenmethode kann mit dem Bezeichner Self auf die Klasse zugegriffen werden, in der die Methode aufgerufen wird (dies kann auch ein Nachkomme der Klasse sein, in der sie definiert ist). Wird die Methode beispielsweise in der Klasse K aufgerufen, hat Self den Typ class of K. Daher können Sie Self nicht für den Zugriff auf Felder, Eigenschaften und normale (Objekt-) Methoden, sondern nur für Aufrufe von Konstruktoren und anderen Klassenmethoden verwenden.

Eben!

Die Frage ist, wo du das obige hingeschrieben hast!!! Wenn du das innerhalb einer Methode deiner Komponente getan hättest, dann hättest du auch den Fehler nicht erhalten!


n-regen - Sa 22.07.06 19:54

Das isses ja: ich verwende das so:


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:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
unit NImage;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls;

type
  TNImage = class(TImage)
  private
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
  published
    { Published-Deklarationen }
  end;

procedure Register;

procedure SmoothH;

implementation

procedure Register;
begin
  RegisterComponents('Beispiele', [TNImage]);
end;

procedure SmoothH;
type
  PixArray = array [1..3of Byte;
var
  Pict, Bit: TBitmap;
  temp: record
    v1,v2,v3,n1,n2,n3: Byte; //hier drin werden die drei Farbwerte
        //vor (v) bzw. nach (n) dem mittleren Pixel gespeichert
  end;
  p,pt: ^PixArray;  //einmal für das Ausgangsbitmap und einmal das neue
  w,h: Integer;
begin
  Bit := Self.Picture.Bitmap;
  Pict:= TBitmap.Create; // das neue Bitmap
  Pict.Assign(Bit);   // sieht erstmal aus wie das alte...
  for h:=0 to Bit.Height-1 do
  begin
    p:= Bit.ScanLine[h];
    pt:= Pict.ScanLine[h];
    for w:=0 to Bit.Width-3 do
    begin
      Inc(pt);
      temp.v1:= p^[1];
      temp.v2:= p^[2];
      temp.v3:= p^[3];
      inc(p,2);
      temp.n1:= p^[1];
      temp.n2:= p^[2];
      temp.n3:= p^[3];
      dec(p);
      //...bekommt im Gegensatz zum alten
      pt^[1]:= (temp.v1+temp.n1+p^[1]) div 3;
      // neue Werte zugewiesen. Das alte
      pt^[2]:= (temp.v2+temp.n2+p^[2]) div 3;
      // dient als 'read-only', damit
      pt^[3]:= (temp.v3+temp.n3+p^[3]) div 3;
      //  kein Wert ein zweites Mal mit einem anderen gemittelt wird.
    end;
  end;
  // Nun noch alt gegen neu tauschen, und fertig mit Teil1.
  Bit.Assign(Pict);
  Pict.Free;
  Self.Picture.Bitmap := Bit;
end;

end.


Und dann kommt halt die Meldung!
:confused:


jaenicke - Sa 22.07.06 19:58

Eben, du schreibst deine Prozedur nicht in deine Komponente sondern nur in die Unit!
So musst du es machen:
(So ist deine Methode nach außen nicht sichtbar, sondern nur intern in der Komponentenunit zu benutzen, wenn jeder die benutzen können soll, musst du die unter public in deiner Komponente hinschreiben...)

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:
type  
  TNImage = class(TImage)  
  private  
    { Private-Deklarationen }  
    procedure SmoothH;
  protected  
    { Protected-Deklarationen }  
  public  
    { Public-Deklarationen }  
  published  
    { Published-Deklarationen }  
  end;
 
procedure Register;  
 
implementation  

procedure Register;  
begin  
  RegisterComponents('Beispiele', [TNImage]);  
end;  

procedure TNImage.SmoothH;
...


n-regen - So 23.07.06 08:03

Danke, jetzt funktioniert die ganze Unit!

:dance2: :think: :dance2:


n-regen - So 23.07.06 09:06

Nun denn, die Unit ist vorerst fertig, jetzt weiss ich aber nicht, ob ich die hergeben darf, da die Funktionen von einem DSDT-Tutorial abgekupfert sind:
http://www.dsdt.info/tutorials/bitmap/
Bitmap-Tutorial von Mathias Leonhardt
Und jetzt ist das Problem, das ich seine Mail-Adresse nicht weiss, weil sie nicht dabei steht.
Ausserdem suche ich jetzt weitere Ideen, was für Funktionen TNImage noch brauchen könnte.
Derzeit gibt es nur Horizontal/Vertikal glätten und Einfärben.