Возможно ли такое создать в DLL?
Модератор: Модераторы
Возможно ли такое создать в DLL?
Возможно ли такое создать в DLL?
Например из программы вызываю dll file
Из dll вызываю функцию с параметром [путь к файлу на диске]
В dll находидится функция которая рисует диалоговое окно со всеми нужными компонентами извлекает нужные даные на экране из данного файла (к примеру нужную строку текста) и дальше функция передает эту строку главной программе.
Зачем это?
Ну например чтобы тоже самое не писать несколько раз в разных программах - а так написал один раз а используешь сколько надо для разных прог.
А если точнее подумываю например написать нужные программы а вызывать их из OO basic - таким образом программа работает самостоятельно а OO basic передает только результат функции
Например из программы вызываю dll file
Из dll вызываю функцию с параметром [путь к файлу на диске]
В dll находидится функция которая рисует диалоговое окно со всеми нужными компонентами извлекает нужные даные на экране из данного файла (к примеру нужную строку текста) и дальше функция передает эту строку главной программе.
Зачем это?
Ну например чтобы тоже самое не писать несколько раз в разных программах - а так написал один раз а используешь сколько надо для разных прог.
А если точнее подумываю например написать нужные программы а вызывать их из OO basic - таким образом программа работает самостоятельно а OO basic передает только результат функции
Программа и dll имеют разные разделы памяти, разные rtl и т.д. Засунуть LCL окно в dll не получится, а процедуры без проблем - аналогично как и в delphi. Никто не мешает создавать окно на API системы, во время работы программы.
Я бы не был столь категоричен.
Код: Выделить всё
library project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms
{ you can add units after this }, unit1;
procedure XShowForm; stdcall;
begin
Application.CreateForm(TForm1,Form1);
Form1.ShowModal;
end;
function XGetForm:TFormClass;
begin
Application.CreateForm(TForm1,Form1);
Result:=TFormClass(Form1);
end;
exports XShowForm,
XGetForm;
begin
end.
Юнит пустой. Тестировал саму возможность.
А вот код вызова.
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
type TPro=procedure; stdcall;
var hlib:TLibHandle;
proc:TPro;
begin
hlib:=LoadLibrary('/home/b4rr4/Devel/DC/test/aaas/lib.so');
if hlib<>0 then
proc:=TPro(GetProcAddress(hlib,'XShowForm'));
if proc<>nil then proc;
end;
procedure TForm1.Button2Click(Sender: TObject);
type TPro=function():TFormClass; stdcall;
var hlib:TLibHandle;
proc:TPro;
x:TFormClass;
begin
hlib:=LoadLibrary('/home/b4rr4/Devel/DC/test/aaas/lib.so');
if hlib<>0 then
proc:=TPro(GetProcAddress(hlib,'XGetForm'));
if proc<>nil then x:=proc();
TForm1(x).Show;
end;
initialization
{$I unit1.lrs}
end.
Тут два метода вызова - первый сам показывает окно, второй передает указатель на окно. Как насчет утечек памяти я не проверял.
Slavikk писал(а):Пардон, признаю свою ошибку. Но всё же в Windows, ShowModal - работает некорректно (только Show).
Я конкретно имел ввиду если в dll засунуть форму с панелью и пытаться контролы с этой панели отображать на панели в своей программе. У меня это не получилось.
А если отображать всю панель с контролами?
Вот такой простенький код (для GTK) позволяет перемещать на форму контролы из подключаемой библиотеки.
Все компоненты расположены на панели, которую и перемещаем.
Предполагаю что виндозная windows.SetParent(...), сработает также.
Примечание: gtk не любит TLabel-ы, просто не отображает их.
Все компоненты расположены на панели, которую и перемещаем.
Предполагаю что виндозная windows.SetParent(...), сработает также.
Примечание: gtk не любит TLabel-ы, просто не отображает их.
Код: Выделить всё
library lclplug;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms,gtk,gdk,glib,Unit1;
function ListLoad(ParentWin:thandle;FileToLoad:pchar;ShowFlags:integer):thandle; stdcall;
begin
Application.CreateForm(TForm1, Form1);
gtk_widget_reparent(PGtkWidget(Form1.Panel1.Handle),PGtkWidget(ParentWin));
end;
exports ListLoad;
begin
end.B4rr4cuda писал(а):Вот такой простенький код (для GTK) позволяет перемещать на форму контролы из подключаемой библиотеки.
Все компоненты расположены на панели, которую и перемещаем.
Предполагаю что виндозная windows.SetParent(...), сработает также.
Так... - инетересно... можешь по подробней обьяснить как все это работает а то не очень понял - обесняй только под линукс - так как ты тестировал
AMD
А зачем именно LCL окно. Это же так не экономно - и к длл и к проге которая его использовать будут линковаться полностью код ЛЦЛ. В итоге и длл и прога будут занимать по метру (а то и больше) места на диске.
Гораздо проще (и по мойму логичней), запихнуть в длл только парсинг файла (который ты там анализируеш) и передавать все данные в какой-нить структуре главной программе. ...Или создавать это окно в длл, но на Win или GTK API не так уж это и сложно, а выглядит солиднее.
А зачем именно LCL окно. Это же так не экономно - и к длл и к проге которая его использовать будут линковаться полностью код ЛЦЛ. В итоге и длл и прога будут занимать по метру (а то и больше) места на диске.
Гораздо проще (и по мойму логичней), запихнуть в длл только парсинг файла (который ты там анализируеш) и передавать все данные в какой-нить структуре главной программе. ...Или создавать это окно в длл, но на Win или GTK API не так уж это и сложно, а выглядит солиднее.
AMD
Ладно по пунктам:
1. Проект -> Создать проект -> Приложение
2. Кидаем на форму панель, а на неё все нужные компоненты, пишем код, тестируем - все как обычно.
3. Проект -> Просмотреть исходный код проекта
Вместо пишем
4. В uses добавляем юниты: gtk, gdk, glib
5. Пишем процедурку или функцию создающую форму и перемещающую панель с контролами на панель вызывающего приложения. Получаем что-то типа:
6. Пишем вызывающую программу:
Вот и все.
2FedeX
Не экономно - это точно, зато удобно. Лично меня от чистого интерфейсного апи тошнит (что от винапи, что от gtk, надо ещё qt попробовать). А вот смесь, позволяющая вытворять трюки и добавляющая гибкости - самое оно. Если размер не критичен, а время поджимает - такие трюки помогают.
А писать на чистом апи, чтобы выглядеть солиднее... пффф, это, простите, детство.
Насчет этого:
Ладно по пунктам:
1. Проект -> Создать проект -> Приложение
2. Кидаем на форму панель, а на неё все нужные компоненты, пишем код, тестируем - все как обычно.
3. Проект -> Просмотреть исходный код проекта
Вместо
Код: Выделить всё
program project1;Код: Выделить всё
library NameOfProject;4. В uses добавляем юниты: gtk, gdk, glib
5. Пишем процедурку или функцию создающую форму и перемещающую панель с контролами на панель вызывающего приложения. Получаем что-то типа:
Код: Выделить всё
library NameOfProject;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms,gtk,gdk,glib,Unit1;
procedure Load(ParentWin:thandle); stdcall;
begin
Application.CreateForm(TForm1, Form1);
gtk_widget_reparent(PGtkWidget(Form1.Panel1.Handle),PGtkWidget(ParentWin));
end;
exports Load;
begin
end.
6. Пишем вызывающую программу:
Код: Выделить всё
uses ... , dynlibs,gtk,glib,gdk;
...
type TPro=procedure (ParentWin:thandle); stdcall;
var Proc:TPro;
Hlib:TLibHandle;
lst:PGList;
...
Hlib:=LoadLibrary('путь к библиотеке');
if Hlib<>0 then
begin
proc:=TPro(GetProcAddress(HLib,'Load'));
if proc <> nil then
begin
{тк lcl панель - это по сути gtk_container и GBox расположенный на нем, то скрываем чайлд компонент и отображаем на его месте свою панель}
lst:=gtk_container_children(GTK_CONTAINER(PGtkwidget(pnlParent.Handle)));
if lst<>nil then
gtk_widget_hide(PGtkWidget(lst^.data));
proc(PnlParent.Handle);
end;
end;
....
Вот и все.
2FedeX
Не экономно - это точно, зато удобно. Лично меня от чистого интерфейсного апи тошнит (что от винапи, что от gtk, надо ещё qt попробовать). А вот смесь, позволяющая вытворять трюки и добавляющая гибкости - самое оно. Если размер не критичен, а время поджимает - такие трюки помогают.
А писать на чистом апи, чтобы выглядеть солиднее... пффф, это, простите, детство.
Насчет этого:
полностью согласен.Гораздо проще (и по мойму логичней), запихнуть в длл только парсинг файла (который ты там анализируеш) и передавать все данные в какой-нить структуре главной программе.
-
the_beginer
- новенький
- Сообщения: 30
- Зарегистрирован: 29.05.2008 16:51:51
FedeX писал(а):AMD
Гораздо проще (и по мойму логичней), запихнуть в длл только парсинг файла (который ты там анализируеш) и передавать все данные в какой-нить структуре главной программе. ...Или создавать это окно в длл, но на Win или GTK API не так уж это и сложно, а выглядит солиднее.
а можно пример в студию ?
интересна реализация
[quote="B4rr4cuda"]AMD
Ладно по пунктам:
1. Проект -> Создать проект -> Приложение
2. Кидаем на форму панель, а на неё все нужные компоненты, пишем код, тестируем - все как обычно.
3. Проект -> Просмотреть исходный код проекта
Вместо пишем
4. В uses добавляем юниты: gtk, gdk, glib
5. Пишем процедурку или функцию создающую форму и перемещающую панель с контролами на панель вызывающего приложения. Получаем что-то типа:
6. Пишем вызывающую программу:
Вот и все.
а как убить эту панель?
Ладно по пунктам:
1. Проект -> Создать проект -> Приложение
2. Кидаем на форму панель, а на неё все нужные компоненты, пишем код, тестируем - все как обычно.
3. Проект -> Просмотреть исходный код проекта
Вместо
Код: Выделить всё
program project1;Код: Выделить всё
library NameOfProject;4. В uses добавляем юниты: gtk, gdk, glib
5. Пишем процедурку или функцию создающую форму и перемещающую панель с контролами на панель вызывающего приложения. Получаем что-то типа:
Код: Выделить всё
library NameOfProject;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms,gtk,gdk,glib,Unit1;
procedure Load(ParentWin:thandle); stdcall;
begin
Application.CreateForm(TForm1, Form1);
gtk_widget_reparent(PGtkWidget(Form1.Panel1.Handle),PGtkWidget(ParentWin));
end;
exports Load;
begin
end.
6. Пишем вызывающую программу:
Код: Выделить всё
uses ... , dynlibs,gtk,glib,gdk;
...
type TPro=procedure (ParentWin:thandle); stdcall;
var Proc:TPro;
Hlib:TLibHandle;
lst:PGList;
...
Hlib:=LoadLibrary('путь к библиотеке');
if Hlib<>0 then
begin
proc:=TPro(GetProcAddress(HLib,'Load'));
if proc <> nil then
begin
{тк lcl панель - это по сути gtk_container и GBox расположенный на нем, то скрываем чайлд компонент и отображаем на его месте свою панель}
lst:=gtk_container_children(GTK_CONTAINER(PGtkwidget(pnlParent.Handle)));
if lst<>nil then
gtk_widget_hide(PGtkWidget(lst^.data));
proc(PnlParent.Handle);
end;
end;
....
Вот и все.
а как убить эту панель?
minoshi писал(а):а как убить эту панель?
gtk_widget_hide(хэндл панели) -чтобы скрыть средствами gtk api.
gtk_widget_destroy(хэндл панели) -чтобы убить средствами gtk api
и Form1.Panel1.free -чтобы убить средствами самого лазаря
Неужели трудно было догадаться?
-
the_beginer
- новенький
- Сообщения: 30
- Зарегистрирован: 29.05.2008 16:51:51
B4rr4cuda писал(а):minoshi писал(а):а как убить эту панель?
gtk_widget_hide(хэндл панели) -чтобы скрыть средствами gtk api.
gtk_widget_destroy(хэндл панели) -чтобы убить средствами gtk api
и Form1.Panel1.free -чтобы убить средствами самого лазаря.
Неужели трудно было догадаться?
теперь эту тему можно перенести в раздел FAQ. Это предложение админам, т.к. ресурсы в библиотеке - это может пригодиться каждому.
