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.