![]() |
TCommonDialog nachfahre: Eigene Komponente erstellen
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):
Delphi-Quellcode:
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'.
Result := TDialogFunc(DialogFunc)(DialogData);
TDialogFunc ist folgend deklariert:
Delphi-Quellcode:
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?
TDialogFunc = function(var DialogData): Bool stdcall;
Auch die Dekleration von TaskModalDialog ist etwas komisch:
Delphi-Quellcode:
irgendwie fehlt mir hier der Datentyp von DialogData. Oder gibs einen Default Datentyp wie in VB Variant?
function TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool; virtual;
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
Delphi-Quellcode:
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?
Success := TaskModalDialog(@ShowInsertDlg, InsertDlgParams);
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. |
Re: TCommonDialog nachfahre: Eigene Komponente erstellen
ok das problem ist weniger komplex wie gedacht.
die fehlermeldung bezieht sich einzig und allein auf @ShowInsertDlg. ich kann lediglich nicht die adresse der funktion auslesen:
Delphi-Quellcode:
also @ShowInsertDlg funktioniert nicht, obwohls in der vcl genauso gemacht wird.
Success := TaskModalDialog(@ShowInsertDlg, InsertDlgParams);
hat den keiner ne ahnung? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:36 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz