AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Ungültige Zeigeroperation Plugin mit interface
Thema durchsuchen
Ansicht
Themen-Optionen

Ungültige Zeigeroperation Plugin mit interface

Ein Thema von geskill · begonnen am 6. Jul 2009 · letzter Beitrag vom 8. Jul 2009
Antwort Antwort
Benutzerbild von geskill
geskill

Registriert seit: 17. Feb 2007
Ort: NRW
420 Beiträge
 
Delphi 2010 Professional
 
#1

Ungültige Zeigeroperation Plugin mit interface

  Alt 6. Jul 2009, 22:22
Hallo,
ich habe ein bischen von diesem Beispiel abgekupfert, leider funktioniert es nicht ganz.

Hier im Code wo Error steht, wird versucht auf eine Komponente zuzugreifen. Es wird versucht die Eingabe zu ändern (Value), jedoch funktioniert das nicht. Die Visuelle Komponente wird unsichtbar, beim schließen des Programms gibt es den Fehler: "Ungültige Zeigeroperation". Seltsamerweise steht in der Messagebox aber die richtige Eingabe.

Ich habe es schon mir ShareMem versucht, das bringt auch nichts.

Könnte der fehler darin liegen das ich dem Edit control als Text property einen widestring gebe ?

Delphi-Quellcode:
procedure Tblabla.Exec(const ComponentManager: IComponentManager);
var s:WideString;
begin
  ShowMessage(ComponentManager.Control[0].Value + #13 +
              IntToStr(ComponentManager.ControlCount)); // Error

  s := 'hans';

  ComponentManager.Control[0].Value := s;
end;
Delphi-Quellcode:
  IComponentManager = interface
    ['{E9432D30-D4CA-4045-BEA3-55C02E56243A}']
      function GetControl(Index:Integer):IBasic;
      procedure SetControl(Index: Integer; AControl: IBasic);
      property Control[Index:Integer]:IBasic read GetControl write SetControl;
      function ControlCount:Integer;
  end;

  IBasic = interface
    ['{DE8F253F-D695-41D4-A350-3CF191644466}']
      function GetIComponent:TIComponent;
      procedure SetIComponent(IComponent: TIComponent);
      function GetName:WideString;
      procedure SetName(AName:WideString);
      function GetTitle:WideString;
      procedure SetTitle(ATitle: WideString);
      function GetHint:WideString;
      procedure SetHint(AHint: WideString);
      function GetValue:WideString;
      procedure SetValue(AValue:WideString);
      
      property IComponent:TIComponent read GetIComponent write SetIComponent;
      property Name:WideString read GetName write SetName;
      property Title:WideString read GetTitle write SetTitle;
      property Hint:WideString read GetHint write SetHint;
      property Value:WideString read GetValue write SetValue;
  end;
Delphi-Quellcode:
  TComponentManager = class(TInterfacedObject, IComponentManager)
    private
      function GetControl(Index: Integer):IBasic;
      procedure SetControl(Index: Integer; AControl: IBasic);
    public
      property Control[Index:Integer]:IBasic read GetControl write SetControl;
      function ControlCount:Integer;

//[...]
function TComponentManager.GetControl(Index:Integer):IBasic;
begin
  result := TIBasic(FControlList[Index]);
end;

procedure TComponentManager.SetControl(Index: Integer; AControl: IBasic);
begin
  FControlList[Index] := TIBasic(AControl);
end;
Delphi-Quellcode:
  TIBasic = class(TInterfacedObject, IBasic)
    private
      function GetIComponent:TIComponent;
      procedure SetIComponent(IComponent: TIComponent);
      function GetName:WideString;
      function GetTitle:WideString;
      procedure SetTitle(ATitle: WideString);
      function GetHint:WideString;
      procedure SetHint(AHint: WideString);
    protected
      function GetValue:WideString; virtual; abstract;
      procedure SetValue(AValue:WideString); virtual; abstract;
      procedure SetName(AName:WideString);
    public
      property IComponent:TIComponent read GetIComponent write SetIComponent;
      property Name:WideString read GetName write SetName;
      property Title:WideString read GetTitle write SetTitle;
      property Hint:WideString read GetHint write SetHint;
      property Value:WideString read GetValue write SetValue;
  end;
Delphi-Quellcode:
  TIEdit = class(TIBasic)
    private
      FEdit:TEdit;
      procedure lClearClick(Sender: TObject);
    protected
      function GetValue:WideString; override;
      procedure SetValue(AValue:WideString); override;
      procedure SetName(AName:WideString);
  end;

//[...]
function TIEdit.GetValue;
begin
  result := FEdit.Text;
end;

procedure TIEdit.SetValue(AValue: WideString);
begin
  FEdit.Text := AValue;
end;
Sebastian
  Mit Zitat antworten Zitat
fajac

Registriert seit: 1. Jul 2009
60 Beiträge
 
#2

Re: Ungültige Zeigeroperation Plugin mit interface

  Alt 7. Jul 2009, 08:25
Moin,
ich vermute eher, dass es an den "virtual; abstract;"-Direktiven in der Klasse TIBasic liegt. Wenn du ein Objekt dieses Typs erzeugst, implementiert es zwar die Interface-Methoden, aber beim Aufruf derselben scheppert es dann.
Vielleicht klappt es, wenn du die Methoden nur als virtual deklarierst und als leere Methoden implementierst?
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#3

Re: Ungültige Zeigeroperation Plugin mit interface

  Alt 7. Jul 2009, 10:53
Hallo,

Du begehst den klassischen Fehler, Objekte und Klassen zu mischen. Wenn Du mit Interfaces arbeitest, solltest Du immer nur per Interface auf Deine Objekte zugreifen und diese auch als Interface in der Liste speichern (Delphi-Referenz durchsuchenTInterfaceList). Ansonsten zieht Dir nämlich die Referenzzählung das Objekt unterm Hintern weg.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Benutzerbild von geskill
geskill

Registriert seit: 17. Feb 2007
Ort: NRW
420 Beiträge
 
Delphi 2010 Professional
 
#4

Re: Ungültige Zeigeroperation Plugin mit interface

  Alt 7. Jul 2009, 21:43
Das ist ja blöd!

Ich habe mehrere eigene Controls (TIEdit, TIComboBox...) die alle von TIBasic abstammen. Das interface von IBasic kann man nun ja noch ganz einfach erstellen und die TIBasic deklaration umschreiben.

TIBasic = class(TInterfacedObject, IBasic) aber! wie sieht die von TIEdit aus?
so sieht es aktuell aus:
TIComboBox = class(TIBasic) Außerdem müsste man ja im interface die Funktion Free zum freigeben der Controls deklarieren
Hier habe ich mal einen größeren Teil des Komponenten Managers, damit versteht man es vielleicht etwas besser:
Delphi-Quellcode:
type
  TComponentManager = class
    private
      FWorkPanel:TComponent;
      FControlList:TInterfaceList;
      type
        TIBasicMeta = class of TIBasic;
      function GetControl(Index: Integer):IBasic;
      procedure SetControl(Index: Integer; AControl: IBasic);
      procedure DisposeControls;
      function GetClassType(AType: TComponentID): TIBasicMeta;
    public
      constructor Create;
      property WorkPanel:TComponent read FWorkPanel write FWorkPanel;
      procedure NewControl(AType:TComponentID;
                           AName,ATitle,AValue,AHint,AList:string;
                           ALeft,ATop,AWidth,AHeight:Integer); overload;
      procedure NewControl(AClass: TIBasicMeta; AType: TComponentID;
                           AName,ATitle,AValue,AHint,AList:string;
                           ALeft,ATop,AWidth,AHeight:Integer); overload;
      function ReadControl(const Id:Integer):TControl; overload;
      function ReadControl(const Name:String):TControl; overload;
      property Controls:TInterfaceList read FControlList;
      property Control[Index:Integer]:IBasic read GetControl write SetControl;
      function ControlCount:Integer;
      destructor Destroy; override;
  end;

implementation

uses
  // Api controls
  uIEdit,uIComboBox,uIComboBoxList,uIPicture;

procedure TComponentManager.DisposeControls;
var I:Integer;
begin
  for I := FControlList.Count -1 downto 0 do
  begin
    case IBasic(FControlList.Items[I]).IComponent of
      cEdit: TIEdit(FControlList.Items[I]).Free; // error... klar, müsste mit IEdit zugreifen
      cComboBox: TIComboBox(FControlList.Items[I]).Free;
      cComboBoxList: TIComboBoxList(FControlList.Items[I]).Free;
      cPicture: TIPicture(FControlList.Items[I]).Free;
    end;
    FControlList.Delete(I);
  end;
end;

function TComponentManager.GetClassType(AType: TComponentID): TIBasicMeta;
begin
  case AType of
    cEdit: result := TIEdit;
    cComboBox: result := TIComboBox;
    cComboBoxList: result := TIComboBoxList;
    cPicture: result := TIPicture;
  else
    raise Exception.Create('Unknown component');
  end;
end;

procedure TComponentManager.NewControl;
begin
  NewControl(GetClassType(AType),AType,AName,ATitle,AValue,AHint,AList,ALeft,ATop,AWidth,AHeight);
end;

procedure TComponentManager.NewControl;
var lBasic:IBasic;
begin
  lBasic := AClass.Create(TWinControl( FWorkPanel )); // funktioniert seltsamerweise wunderbar
  with lBasic do
  begin
    IComponent := AType;
    Name := AName;
    Title := ATitle;
    Hint := AHint;
    Left := ALeft;
    Top := ATop;
    Width := AWidth;
    Height := AHeight;
    Value := AValue; // abstract
  end;

  case AType of
    cComboBox: TIComboBox(lBasic).List := AList; // error... klar, müsste mit IComboBox zugreifen
    cComboBoxList: TIComboBoxList(lBasic).List := AList;
  end;

  FControlList.Add( lBasic );
end;
Das schreiben und lesen mit dem Plugin funktioniert jetzt.
Schön ist das ganze aber nicht vorallem gibt es die TInterfaceList wahrscheinlich nur in Delphi
Delphi-Quellcode:
procedure Tblabla.Exec(const Controls:TInterfaceList);
var s:string;
begin
  ShowMessage(IBasic(Controls.Items[0]).Value //+ #13 +
              );

  s := 'hans';

  IBasic(Controls.Items[1]).Value := s;

  //ComponentManager.Control[0].Value := s;
end;
Sebastian
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#5

Re: Ungültige Zeigeroperation Plugin mit interface

  Alt 7. Jul 2009, 23:07
Hallo,
Zitat von geskill:
aber! wie sieht die von TIEdit aus?
so sieht es aktuell aus:
TIComboBox = class(TIBasic)
ich kann Dir nicht ganz folgen. Meinst Du jetzt ein Edit oder eine Combobox? Aber eigentlich ist das ja auch egal, Du musst eben das entsprechende Interface angeben:
TIComboBox = class(TIBasic, IComboBox)
Zitat von geskill:
Außerdem müsste man ja im interface die Funktion Free zum freigeben der Controls deklarieren
Wozu? Die Referenzzählung sorgt doch dafür, dass der Destruktor automatisch aufgerufen wird.

Zitat von geskill:
Schön ist das ganze aber nicht vorallem gibt es die TInterfaceList wahrscheinlich nur in Delphi
Alles, was Du gerade machst, funktioniert so erst mal nur in Delphi. Wenn Du andere Sprachen unterstützen willst, musst Du COM verwenden. Interfaces alleine reichen da nicht aus.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Benutzerbild von geskill
geskill

Registriert seit: 17. Feb 2007
Ort: NRW
420 Beiträge
 
Delphi 2010 Professional
 
#6

Re: Ungültige Zeigeroperation Plugin mit interface

  Alt 7. Jul 2009, 23:41
Zitat von xaromz:
TIComboBox = class(TIBasic, IComboBox)
Kann man das auch so lösen, dass man die Klassen in den verschiedenen Units lässt? Bisher hatte ich das so und war dadurch mit deinem Ansatz gescheitert.
Also:

uIBasic.pas -> TIBasic = class
uIEdit.pas -> TIEdit = class
...

Aber Vielen Dank schonmal!
Sebastian
  Mit Zitat antworten Zitat
fajac

Registriert seit: 1. Jul 2009
60 Beiträge
 
#7

Re: Ungültige Zeigeroperation Plugin mit interface

  Alt 8. Jul 2009, 07:59
Falls die Referenzzählung hier das Problem ist (bzw. das automatische Freigeben), dann kann man dem abhelfen. Durch Überschreiben der Interfacemethoden _AddRef und _Release (siehe TInterfacedObject in der Unit System) durch leere Methoden wird die Referenzzählung abgeschaltet.
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#8

Re: Ungültige Zeigeroperation Plugin mit interface

  Alt 8. Jul 2009, 09:24
Hallo,
Zitat von fajac:
Falls die Referenzzählung hier das Problem ist (bzw. das automatische Freigeben), dann kann man dem abhelfen.
Dazu sollte man aber schon genau wissen, wie Interfaces funktionieren. Das scheint mir hier (noch) nicht unbedingt der Fall zu sein.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#9

Re: Ungültige Zeigeroperation Plugin mit interface

  Alt 8. Jul 2009, 09:47
Delphi-Quellcode:
procedure TComponentManager.NewControl;
var
  lBasic: IBasic;
  lComboBox: IComboBox;
begin
  lBasic := AClass.Create(TWinControl( FWorkPanel ));
  with lBasic do
  begin
    IComponent := AType;
    Name := AName;
    Title := ATitle;
    Hint := AHint;
    Left := ALeft;
    Top := ATop;
    Width := AWidth;
    Height := AHeight;
    Value := AValue;
  end;

  if lBasic.QueryInterface(IComboBox, lComboBox) = 0 then
    lComboBox.List := AList;

  FControlList.Add( lBasic );
end;
Edit, das sollte ja eigentlich bereits klar sein:
Delphi-Quellcode:
procedure TComponentManager.DisposeControls;
begin
  FControlList.Clear;
end;
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz