Einzelnen Beitrag anzeigen

RuX

Registriert seit: 21. Jul 2004
Ort: Nürnberg
115 Beiträge
 
Delphi 7 Architect
 
#1

TCommonDialog nachfahre: Eigene Komponente erstellen

  Alt 18. Aug 2004, 17:14
Mal Vorweg: Hier bezieht sich alles auf Delphi 3
Ich bin gerade dabei mir einen eigenen Eingabe Dialog zu bauen. Der Dialog ist wie die anderen VCL Dialoge ein Nachfahre von TCommonDialog. Befindet sich alles in Dialogs
Bei den Dialogen ist die Funktion Execute dafür zuständig das eigentliche Fenster aufzurufen.
Diese Methode ist in TCommonDialog virtual abstract deklariert und muss ja in den Nachfahren dementsprechend implementiert werden. Die vererbten Execute Methoden der Dialoge rufen wiederum alle die Methode TaskModalDialog auf. Die stammt auch aus TCommonDialog. In dieser Methode wird dann wiederrum zum schließendlichen das Formular aufgerufen (mehr oder weniger):
Result := TDialogFunc(DialogFunc)(DialogData); Er castet also von einem Zeiger auf TDialogFunc. Der Zeiger enthält eine Adresse einer Funktion die wohl den entsprechenden Dialog aufruft oder noch mehr verschachtelt Die FUnktionen @DialogFunc befinden sich in der dll 'comdlg32.dll'.
TDialogFunc ist folgend deklariert:
TDialogFunc = function(var DialogData): Bool stdcall; Wenn ich das richtig verstehe macht er bei diesem aufruf einmal das casten und übergibt dann gleich DialogData. Oder heißt das etwas ganz anderes?

Auch die Dekleration von TaskModalDialog ist etwas komisch:
function TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool; virtual; irgendwie fehlt mir hier der Datentyp von DialogData. Oder gibs einen Default Datentyp wie in VB Variant?

Ich habe das soweit nachvollzogen und wollte jetzt probieren meinen Eigenen Dialog nach diesem Vorbild zu bauen, bloß dass bei mir der Dialog nicht aus einer DLL kommt, sondern direkt in der Komponente implementiert ist. Aber der Aufruf von
Success := TaskModalDialog(@ShowInsertDlg, InsertDlgParams); schlägt bei mir leider fehl: "Variable erforderlich". Mit nil anstatt von @ShowInsertDlg gehts. Ich steh grad aufm Schlauch, weiß jemand woran das liegen könnte?
Hier der bisherige Programmcode (natrürlich lang noch nich fertig ):
Delphi-Quellcode:
unit InsertDlg;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  stdctrls;

type
  TInsertDlgParams = packed record
    lpCaption: PAnsiChar;
    lpText: PAnsiChar;
    lpDescription: PAnsiChar;
  end;

  TInsertDlg = class(TCommonDialog)
  private
    //Felder
    FCaption: String;
    FText: String;
    FDescription: String;

    //Get, Set Methoden der Felder
    function GetText: String;
    procedure SetText(ANewText: String);

    function GetDescription: String;
    procedure SetDescription(ANewDescription: String);

    function GetCaption: String;
    procedure SetCaption(ANewCaption: String);

    //zum InsertDialog öffnen
    function ShowInsertDlg(var InsertDlgParams: TInsertDlgParams): bool; stdcall;
  protected
    //function DoExecute(Func: Pointer): Bool;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function Execute: String;
  published
    property Text: String Read GetText Write SetText;
    property Description: String Read GetDescription Write SetDescription;
    property Caption: String Read GetCaption Write SetCaption;
  end;

procedure Register;

implementation

constructor TInsertDlg.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  //Initialisierung
  Text := '';
  Description := 'Bitte geben Sie den Wert ein:';
  Caption := 'Werte-Eingabe';

end;

//Get Methoden
//------------------------------------------------------------------------------
function TInsertDlg.GetText: String;
begin
  result := FText;
end;

function TInsertDlg.GetDescription: String;
begin
  result := FDescription;
end;


function TInsertDlg.GetCaption: String;
begin
  result := FCaption;
end;

//Set Methoden
//------------------------------------------------------------------------------
procedure TInsertDlg.SetText(ANewText: String);
begin
  FText := Trim(ANewText);
end;

procedure TInsertDlg.SetDescription(ANewDescription: String);
begin
  FDescription := Trim(ANewDescription);
end;

procedure TInsertDlg.SetCaption(ANewCaption: String);
begin
  FCaption := Trim(ANewCaption);
end;


//Aufruf des Eingabedialogs
//------------------------------------------------------------------------------
function TInsertDlg.Execute: String;
var InsertDlgParams: TInsertDlgParams;
    Success: Boolean;
begin
  //Result := DoExecute(@ShowInsertDlg);
  Success := False;
  with InsertDlgParams do
  begin
    lpCaption := PChar(Caption);
    lpText := PChar(Text);
    lpDescription := PChar(Description);
    Success := TaskModalDialog(@ShowInsertDlg, InsertDlgParams);
    //Success := TaskModalDialog(nil, InsertDlgParams); //geht
  end;

  if Success then
    result := String(InsertDlgParams.lpText)
  else
    result := '';
end;


destructor TInsertDlg.Destroy;
begin
  Inherited Destroy;
end;


(*
function TInsertDlg.DoExecute(Func: Pointer): Bool;
begin
  Result := TaskModalDialog(Func, );
end;
*)


function TInsertDlg.ShowInsertDlg(var InsertDlgParams: TInsertDlgParams): bool; stdcall;
begin
  //Todo: Formular erstellen mit Daten aus InsertDlgParams
  ShowMessage('Formular erstellen');
  result := False;
end;

//Komponente Registrieren
//------------------------------------------------------------------------------
procedure Register;
begin
  RegisterComponents('Dialoge', [TInsertDlg]);
end;


end.
  Mit Zitat antworten Zitat