Witam,
Piszę programik, w którym pobieram formę z biblioteki dll (napisałem ja sam) i tu nie wiem jak wymieniać dane pomiędzy programem a uruchomiona formą z dll.
np. mam w programie zmienna:string i chciałbym aby ta zmienna była odczytana przez formę uruchomioną z dll.
Proszę o pomoc.
Nie zadziała zrobienie funkcji która zwróci co ma zwrócić??
A skąd mamy wiedzieć w jaki sposób wywołujesz formularz z DLL czy masz np. eksportujesz funkcję zwracającą instancje klasy np:
function CreateFormDLL(AOwner: TComponent): TFormDLL;
begin
result:= TFormDLL.Create(AOwner);
end;
exports
CreateFormDLL;
czy jakoś inaczej?
Formuklarz z DLL exportuję:
procedure logowanie; stdcall;
var
Form1:TForm1;
begin
Form1 := TForm1.Create(Application); // utworzenieformularza
Form1.ShowModal; // wyświetlenie
Form1.Free; // zwolnienie
end;
exports
{ eksport procedury }
logowanie name 'logowanie';
begin
end.
a z programu wywołuję ją tak:
var
DLL : THandle;
login : procedure;
begin
// wczytanie biblioteki logowania
DLL := LoadLibrary('log.dll'); // załadowanie pliku
try
@login := GetProcAddress(DLL, 'logowanie'); // pobranie wskaźnika do procedury
if @login = nil then raise Exception.Create('Nie można załadować procedury logowania.');
login; // wykonanie procedury
finally
FreeLibrary(DLL);
end;
end;
nie wiem jak pobrać informacje z programu a konkretnie mam utworzoną formę data1:TData a na niej komponenty connect i query.
uruchamiając program uruchamiam formę z dll i tu chcę pobrać dane z programu czyli data1.connect ... a jak to zrobić nie wiem.
Mam nadzieję, że nie namieszałem.
Oj można by się bawić w jakieś komunikaty, pamięć współdzieloną itd. jednak ja bym tu forsował rozwiązanie które proponuję:
Tworzysz sobie wspólny moduł dla DLL i aplikacji w przykładzie:
unit uXDLLForm;
interface
uses
Vcl.Forms;
type
TXForm = class(TForm)
private
public
procedure SetCaptionText(ACaptionText: string); virtual; abstract;
end;
implementation
end.
Tutaj mamy deklarację przykładowej procedury SetCaptionText
(Ty możesz w ten sam sposób przekazać cokolwiek)
teraz moduł formularza w DLL:
unit uDLLForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, uXDLLForm;
type
TFormDLL = class(TXForm) // WAŻNE zmiana klasy po której dziedziczy na TXForm musisz też zmodyfikować plik DFM
private
{ Private declarations }
public
{ Public declarations }
procedure SetCaptionText(ACaptionText: string); override;
end;
implementation
{$R *.dfm}
procedure TFormDLL.SetCaptionText(ACaptionText: string); //implementacja przykladowej procedury
begin
Caption:= ACaptionText; //taki prosty przykład ustawia Caption na zadany
end;
end.
i główny plik projektu DLL:
library DataDLL;
uses
System.SysUtils,
System.Classes,
uXDLLForm,
uDLLForm in 'uDLLForm.pas' {Form1};
{$R *.res}
function CreateFormDLL(AOwner: TComponent): TFormDLL;
begin
result:= TFormDLL.Create(AOwner);
end;
exports
CreateFormDLL;
begin
end.
A przykładowo w aplikacji:
unit uMain;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, uXDLLForm, Vcl.StdCtrls;
type
TfrmMain = class(TForm)
btnShowFormDLL: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnShowFormDLLClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
DLLForm: TXForm;
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
function CreateFormDLL(AOwner: TComponent): TXForm; external 'DataDLL.dll';
implementation
{$R *.dfm}
procedure TfrmMain.btnShowFormDLLClick(Sender: TObject);
begin
DLLForm.SetCaptionText('test'); //testujemy przykladowa procedure
DLLForm.ShowModal; //mamy oczywiscie dostęp do publicznych standardowych metod fomularza
end;
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
DLLForm.Free;
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
DLLForm:= CreateFormDLL(Self);
end;
end.
Jak widać mamy dostęp do metod standardowych metod formularza w DLL a także możemy dodawać swoje (jak SetCaptionText
) choć jej implementacja znajduje się w DLL. Wydaje się więcej zabawy ale to proste i działające rozwiązanie.
grafo napisał(a):
np. mam w programie zmienna:string i chciałbym aby ta zmienna była odczytana przez formę uruchomioną z dll.
Wystarczy ją przekazać w parametrze byle jakiej funkcji czy procedury, zawartej w bibliotece. W tej procedurze możesz wykorzystać ciąg z parametru do dowolnych operacji związanych z wewnętrznym formularzem.
W razie chęci użycia stringów czy dynamicznych macierzy, należy skorzystać z modułu ShareMem
.