Форум: "Начинающим";
Текущий архив: 2005.12.04;
Скачать: [xml.tar.bz2];
ВнизИз DLL не в DLL Найти похожие ветки
← →
Moningstar (2005-11-01 14:26) [0]Приветствую, мастера! Вот такая ситуация: в приложении три фомы: Form1 (главная), Form2 и Form3. Form3 вызывается из DLL, динамически. На ней расположен ComboBox. При ComboBoxChange текст выбранного пункта должен отобразиться в Label1, расположенном на Form2. Вопрос, как вы уже догадались, как это сделать?
Код Dll проекта.
library Project1;
uses
ShareMem, SysUtils, Classes, Forms,
Unit3 in "Unit3.pas" {Form3};
{$R *.res}
function ShowForm3: Integer; stdcall;
begin
Form3 := TForm3.Create(Application);
Result := Form3.ShowModal;
Form3.Free;
end;
exports
ShowForm3;
begin
end.
Код простого проекта.
type
TShowForm3 = function: Integer;
TForm2 = class(TForm)
procedure Button1Click(Sender: TObject);
Button1: TButton;
Label1: TLabel;
...
procedure TForm2.Button1Click(Sender: TObject);
var ShowForm3: TShowForm3;
DLLShowForm3Handle: THandle;
begin
try
DLLShowForm3Handle := loadLibrary ( "Project1.dll" );
if DLLShowForm3Handle <> 0 then
begin
@ShowForm3 := getProcAddress ( DLLShowForm3Handle, "ShowForm3" );
if addr ( ShowForm3 ) <> nil then
ShowForm3 else
showMessage ( "Function not exists..." );
end;
finally
FreeLibrary(DLLShowForm3Handle);
end;
end;
Ну а из Form1 вызывается Form2 простым Show.
← →
wal © (2005-11-01 14:38) [1]
library Project1;
uses
ShareMem, SysUtils, Classes, Forms,
Unit3 in "Unit3.pas" {Form3};
{$R *.res}
function ShowForm3(var S: string): Integer; stdcall;
begin
Form3 := TForm3.Create(Application);
Result := Form3.ShowModal;
S := ComboBox.Text;
Form3.Free;
end;
exports
ShowForm3;
begin
end.
← →
AbrosimovA (2005-11-01 14:41) [2]Попробуй создать в длл-ке функцию чтения текста из ComboBox, а в основной программе циклический вызов этой функции. Только учесть надо, что передаваемое этой функцией значение не должно быть типа string.
← →
evvcom © (2005-11-01 14:55) [3]
> функцию чтения текста из ComboBox, а в основной программе
> циклический вызов этой функции
Не надо так делать.
> function ShowForm3(var S: string): Integer; stdcall;
Здесь stdcall лишнее. Все равно эта функция может быть вызвана только из программ написанных в Delphi, поэтому здесь это не нужно. Ну и естественно в проекте exe тоже не упоминать об stdcall
← →
Moningstar (2005-11-02 13:20) [4]>wal
Я не понял, как таким образом при событии ComboBox1Change из Form3 результат будет отображаться в Form2. У меня возникает ошибка Access violation. А делаю вот что (не судите строго, я начал изучать DLL буквально неделю назад):
procedure TForm3.ComboBox1Change(Sender: TObject);
begin
Form2.Label1.Caption:=ComboBox1.Text;
end;
Как применить переменную S, не могу понять.
← →
evvcom © (2005-11-02 14:23) [5]В [1] результат будет отображаться в Form2 не при событии ComboBox1Change, а после закрытия модальной формы 3. Из основного модуля:
ShowForm3(NewCaption);
Form2.Label1.Caption:=NewCaption;
и все
← →
Moningstar (2005-11-02 15:08) [6]>evvcom
А чтобы работало без закрытия, так можно?
← →
wal © (2005-11-03 09:46) [7]
> А чтобы работало без закрытия, так можно?
Не уверен, но попробовать можно.Library ...
...
function ShowForm3(const OnChange: TNotifyEvent): Integer;
begin
Form3 := TForm3.Create(Application);
Form3.ComboBox.OnChange := OnChange;
Result := Form3.ShowModal;
Form3.Free;
end;
...type
TShowForm3 = function(const OnChange: TNotyfyEvent): Integer;
TForm2 = class(TForm)
procedure Button1Click(Sender: TObject);
procedure OnChange(Sender: TObject);
Button1: TButton;
Label1: TLabel;
...
procedure TForm2.Button1Click(Sender: TObject);
var ShowForm3: TShowForm3;
DLLShowForm3Handle: THandle;
begin
try
DLLShowForm3Handle := loadLibrary ( "Project1.dll" );
if DLLShowForm3Handle <> 0 then
begin
@ShowForm3 := getProcAddress ( DLLShowForm3Handle, "ShowForm3" );
if addr ( ShowForm3 ) <> nil then
ShowForm3(OnChange) else
showMessage ( "Function not exists..." );
end;
finally
FreeLibrary(DLLShowForm3Handle);
end;
procedure TForm2.OnChange(Sender: TObject);
begin
if (Sender is TComboBox) then
with (Sender as TComboBox) do
Label1.Caption := Text
end;
end;
Только вот зачем такие извраты - непонимаю.
← →
Moningstar (2005-11-03 12:40) [8]>wal
Это мне для развития, так сказать. Однако код не хочет работать (надеюсь, я всё сделал правильно). Ну, зато теперь хоть ошибок не возникает.
← →
Moningstar (2005-11-10 06:54) [9]Вроде разобрался, всё работает. Но хотелось бы кое-что уточнить.
При OnChange Label"у на Form2 присваивается только одно значение ComboBox"а - которое было изначально, при создании формы Form3. Т.е. если я делаю выбор итемов, то выбранный мною итем не отображается на Label"е формы Form2. Это можно исправить, сохранив при этом освобождение памяти? Надеюсь, изложил понятно.
← →
GrayFace © (2005-11-10 08:10) [10]А при чем тут освобождение памяти? Делай, например, так:
Dll:type
TSetTextEvent=procedure(text:PChar) of object;
var ChangeEvent:TSetTextEvent;
function ShowForm3(AEvent:TSetTextEvent): Integer;
begin
ChangeEvent:=AEvent;
Form3 := TForm3.Create(Application);
Result := Form3.ShowModal;
Form3.Free; - вместо этого лучше On
end;
procedure ComboBox1Change(sender...)
begin
ChangeEvent(pointer(ComboBox1.Text));
end;
В приложении, соответственноprocedure TForm1.Form3ComboChange(text:PChar);
begin
Label1.Text:=text;
end;
Вообще, форм в dll лучше избегать.
← →
Moningstar (2005-11-10 13:11) [11]>Form3.Free; - вместо этого лучше On Что за On?
← →
GrayFace © (2005-11-15 18:53) [12]Недописал. OnClose Action:=caFree;
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2005.12.04;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.032 c