Закрыть программу из Dll

Shouldercannon

Well-Known Member
25.05.2010
128
0
29
Пенза
#1
К моему проекту привязана DLL
Код:
procedure UpdateProgram(URL, Path, UpdateProgramName, ArchiveName: PChar); stdcall; external 'MYDLL.DLL';
Эта DLL скачивает файл из Инета. После того как программа скачала архив нужно завершить работу приложения. Я работаю с DLL в первые.
Код:
procedure TFormUpdate.thrTerminate(Sender: TObject);
begin
FormUpdate.Close; // Форма, вызванная из DLL не закрывается вообще
FormMain.PMMExit.Click; // Полнейший бред
end;
...

// FormMain
procedure TFormMain.Exit1Click(Sender: TObject);
begin
Application.Terminate;
end;
Как закрыть форму, вызванную из DLL и правильно завершить работу программы всё из той же DLL?
 

sinkopa

Well-Known Member
#2
К моему проекту привязана DLL
Код:
procedure UpdateProgram(URL, Path, UpdateProgramName, ArchiveName: PChar); stdcall; external 'MYDLL.DLL';
Эта DLL скачивает файл из Инета. После того как программа скачала архив нужно завершить работу приложения. Я работаю с DLL в первые.
Код:
procedure TFormUpdate.thrTerminate(Sender: TObject);
begin
FormUpdate.Close; // Форма, вызванная из DLL не закрывается вообще
FormMain.PMMExit.Click; // Полнейший бред
end;
...

// FormMain
procedure TFormMain.Exit1Click(Sender: TObject);
begin
Application.Terminate;
end;
Как закрыть форму, вызванную из DLL и правильно завершить работу программы всё из той же DLL?
Встречные вопросы: DLL (которая "MYDLL.DLL") Вы писали?
Если да, то как создается, и отображается "неубиваемая" форма? (код в студию пожалста)
Если нет, то такие еше функции/процедуры "Выша" DLL экспортирует? Известно?

В самом тяжелом случае (если вы вообще ничего про этот "MYDLL.DLL" не знаете) замение в коде Вашей программы Статический вызов процедуры UpdateProgram на динамическую подгрузку. Это делается так:
Код:
var
UpdateProgram: procedure(URL, Path, UpdateProgramName, ArchiveName: PChar); stdcall;
DLL: HMODULE = 0;

implementation

...

procedure TFormMain.Button1Click(Sender: TObject);
var
URL: string;
Path: string;
UpdateProgramName: string;
ArchiveName: string;
begin
DLL := LoadLibrary('MYDLL.DLL'); // Если MYDLL.DLL нет в "области видимости", то надо указывать полный путь
// LoadLibrary('C:\<полный путь>\MYDLL.DLL');

if (DLL > 0) then // DLL Загрузить удалось
begin
@UpdateProgram := GetProcAddress(DLL,'UpdateProgram');

if Assigned(UpdateProgram) then // Процедура нашлась
begin
// Заполняем параметры
// URL := ...
// Path := ...
// UpdateProgramName := ...
// ArchiveName := ...

// Вызываем процедуру
UpdateProgram(PChar(URL),PChar(Path),PChar(UpdateProgramName),PChar(ArchiveName));
end;

@UpdateProgram := nil; // Освобождаем процедуру
FreeLibrary(DLL); // Выгружаем DLL;
end;

// Тут можете потушить ваш Application, если нужно
// Application.Terminate;

end;
При таком варианте использования (если никаких "чудес" внутри DLL-ки не заложено), при выгрузке DLL из памяти, дожна "помереть" и форма рожденная DLL-кой.
 

Shouldercannon

Well-Known Member
25.05.2010
128
0
29
Пенза
#3
В MYDLL.DLL было
Код:
library mydll;

uses SysUtils, Classes;

{Определяем функцию как stdcall}
function GetSimpleText(LangRus: Boolean): PChar; stdcall;
begin
{В зависимости от LangRus возвращаем русскую (True) либо английскую (False) фразу}
if LangRus then
Result := PChar('Здравствуй, мир!')
else
Result := PChar('Hello, world!');
end;

{Директива exports указывает, какие функции будут экспортированы этой DLL}
exports GetSimpleText;

begin
end.
Да это уже не важно. Я пытался из DLL послать главной форме сообщение на закрытие, но всё провалилось и я отказался от закрытия программы при помощи dll.
 

sinkopa

Well-Known Member
#4
Я пытался из DLL послать главной форме сообщение на закрытие, но всё провалилось и я отказался от закрытия программы при помощи dll.
С чего бы это? :rolleyes:
Доделываем MYDLL.DLL
Код:
library mydll;

uses SysUtils, Classes, Windows, Messages;

const
WM_KILLMAINFORM = WM_USER +102;
killmes = 'Умри достойно. Целую, mydll.dll';

{Определяем функцию как stdcall}
function GetSimpleText( FormHandle: THandle; LangRus: Boolean): PChar; stdcall;
begin
{В зависимости от LangRus возвращаем русскую (True) либо английскую (False) фразу}
if LangRus then
Result := PChar('Здравствуй, мир!')
else
Result := PChar('Hello, world!');

if (FormHandle > 0) then
PostMessage(FormHandle,WM_KILLMAINFORM, 0, Lparam(PChar(killmes)));

end;

{Директива exports указывает, какие функции будут экспортированы этой DLL}
exports GetSimpleText;

begin
end.
в программе:
Код:
//...
const
WM_KILLMAINFORM = WM_USER +102;

//...
type
TForm1 = class(TForm)
/...
private
procedure WMKillMainForm(msg: TMessage); message WM_KILLMAINFORM;
//...
public
//...
end;

implementation

//...
procedure TForm1.WMKillMainForm(msg: TMessage);
begin
ShowMessage(PChar(msg.LParam));
Self.Close;
// или Application.Terminate;
end;