Autor Beitrag
freedy
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 403
Erhaltene Danke: 1

Winows 7
Delphi XE
BeitragVerfasst: Fr 30.03.07 11:04 
Hallo!

Ich habe folgenden Codeausschnitt:
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:
const
  WM_LINE_ADD = WM_USER + 1;

type  
  TLines = class(TObject)
  private
    FLines : array of TLine;
  [...]
  public
    [...]
    function Add : TLine;
    [...]
  end;


  TEditor = class(TCustomControl)
  private
    Lines : TLines;
    [...]
    procedure WMLineAdd(var Msg: TMessage); message WM_LINE_ADD;
    [...]
  end;
  
[...]

function TLines.Add : TLine;
var
  Handle: Hwnd;
begin
  Handle := Application.Handle;
  [...]
  SendMessage(Handle, WM_LINE_ADD, Integer(FLines[Length(FLines) - 1]), 0);
  Result := FLines[Length(FLines) - 1]; 
end;

[...]

procedure TEditor.WMLineAdd(var Msg: TMessage);
 var
  Line : TLine;
begin
  Line := TLine(Msg.WParam);
  if Assigned(FOnLineAdd) then
    FOnLineAdd(Self);
end;



Wie man sieht, soll, wenn die Add-Funktion aufgerufen wird, eine Message versendet werden, die von der Parent-Klasse aufgefangen wird. Leider funktioniert das nicht. Wie reserviere ich beim BS das Handle für die TEditor-Klasse, damit die Message dort ankommt? Bisher gibt es das ja noch gar nicht, oder?

Grüße
Michael
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: Fr 30.03.07 15:42 
Du musst kein Handle reservieren, sondern das Handle des Empfängers kennen. Oder das Handle des Owners, der dann diue Massage vllt. durchreicht. Aber eigentlich sollten alle visuellen Editor-Komponenten ein Handle haben.

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 30.03.07 15:56 
user profile iconHelgeLange hat folgendes geschrieben:
Aber eigentlich sollten alle visuellen Editor-Komponenten ein Handle haben.

Nein nur die von TQWinControl abgeleiteten. TLabel hat zum Beispiel kein Handle, weil es von TGraphicControl abgeleitet ist.

@freedy: Arbeite mit Ereignissen. TLines.Add löst ein Ereignis aus dem in TEditor eine Ereignisbehandlungsroutine zugeordnet ist. Mit SendMessage sendet man Nachrichten an Fenster. Eine Klasse ist nun aber mal kein Fenster und kann demnach auch keine Nachrichten empfangen.

Demo
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:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
type
  TOnAdd = procedure(Sender: TObject) of object;

  TLine = class(TObject)
  private
    FStringList: TStringList;
    FOnAdd: TOnAdd;
  public
    constructor Create;
    destructor Destroy; override;
    property OnAdd: TOnAdd read FOnAdd write FOnAdd;
    procedure Add(s: String);
  end;

  TEditor = class(TObject)
  private
    FLine: TLine;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Add(s: String);
    procedure OnAdd(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TLine }

procedure TLine.Add(s: String);
begin
  FStringList.Add(s);
  if Assigned(OnAdd) then
    OnAdd(Self);
end;

constructor TLine.Create;
begin
  FStringList := TStringList.Create;
end;

destructor TLine.Destroy;
begin
  FStringList.Free;
  inherited;
end;

{ TEditor }

procedure TEditor.Add(s: String);
begin
  FLine.Add(s);
end;

constructor TEditor.Create;
begin
  FLine := TLine.Create;
  FLine.OnAdd := OnAdd;
end;

destructor TEditor.Destroy;
begin
  FLine.Free;
  inherited;
end;

procedure TEditor.OnAdd(Sender: TObject);
begin
  ShowMessage('OnAdd');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  edit: TEditor;
begin
  edit := TEditor.Create;
  try
    edit.Add('Test');
  finally
    edit.Free;
  end;
end;
freedy Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 403
Erhaltene Danke: 1

Winows 7
Delphi XE
BeitragVerfasst: Fr 30.03.07 16:31 
user profile iconLuckie hat folgendes geschrieben:

Mit SendMessage sendet man Nachrichten an Fenster. Eine Klasse ist nun aber mal kein Fenster und kann demnach auch keine Nachrichten empfangen.


Das sehe ich etwas anders. Wenn man sich den Quellcode der VCL ansieht, findet man des öfteren "SendMessage" innerhalb der Komponenten. Ein Ereignis wollte ich nicht belegen, da auch mein TLine nach aussen sichtbar ist. Ich möchte einen späteren Programmierer nicht verwirren, wenn die Komponente nach Überschreiben des Ereignisses nicht mehr reagiert.

Inzwischen habe ich das Handle-Problem auch in den Griff bekommen. Die einzelnen untergeordneten Klassen kennen nun das Handle ihrer Vater-Instanz.

Trotzdem vielen Dank und ein schönes Wochenende.
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: Fr 30.03.07 16:33 
mmit Editor-Komponenten haben ich eigentlich die ausschliessen wollen, die sich nicht zur Laufzeit editieren lassen (zum Bsp: TLabel) ;)

Was Du machen kannst : mit Dispatch eine Nachricht senden, direkt an die Komponente. Das versteht jedes Object von Delphi

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 30.03.07 16:51 
user profile iconfreedy hat folgendes geschrieben:
user profile iconLuckie hat folgendes geschrieben:

Mit SendMessage sendet man Nachrichten an Fenster. Eine Klasse ist nun aber mal kein Fenster und kann demnach auch keine Nachrichten empfangen.


Das sehe ich etwas anders. Wenn man sich den Quellcode der VCL ansieht, findet man des öfteren "SendMessage" innerhalb der Komponenten.

Dann nenne mir doch mal das Fensterhandle einer Klasse:
ausblenden Quelltext
1:
2:
3:
4:
5:
LRESULT SendMessage(          HWND hWnd,
    UINT Msg,
    WPARAM wParam,
    LPARAM lParam
);

Zitat:
hWnd
[in] Handle to the window whose window procedure will receive the message.


Was anderes ist es, wenn du eine Klasse hast, die von TWinControl abgeleitet ist und somit ein Fensterhandle besitzt.