С Новым годом! Форум программистов, компьютерный форум, киберфорум
Delphi
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
 Аватар для nixstill
17 / 17 / 2
Регистрация: 15.01.2009
Сообщений: 86

Показ в TPanel и (или) TTabSheet, объектов из плагинов dll

18.09.2009, 17:48. Показов 2103. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В каждом плагине у меня есть определенные типовые функции, например получения информации о dll и т.д.
Все это очень хорошо работает и мозг не выносит.
Почитав про то как можно запихнуть форму в dll, решил это сделать но получилось на половину.

Основной вопрос: как на TPanel или TTabSheet выводить необходимую форму и типичных по структуре dll? Т.е. организовать некий TPageControl на плагинах?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.09.2009, 17:48
Ответы с готовыми решениями:

Как засунуть форму из dll в TPanel главной формы приложения???
Есть следующий вариант вызова формы из dll с динамическим подключением: Код в dll: #include <vcl.h> #include...

Присвоить одинаковое событие onMouseDown или OnMouseUp нескольким компонентам TPanel или TButton
Здравствуйте! Подскажите как присвоить одинаковое событие onMouseDown или OnMouseUp нескольким компонентам TPanel или TButton. Для примера...

Отображение TImage поверх TPanel или TShape
Не удается реализовать отображение Image поверх ни Shape, ни Panel. Самое удивительное, что в дизайнере все отображается корректно, но при...

6
 Аватар для Otaka
1857 / 714 / 55
Регистрация: 11.12.2008
Сообщений: 1,019
18.09.2009, 20:04
Как сделать? Очень просто.
Создаешь форму, делаешь её BorderStyle как none, а потом просто присваиваешь Паренту данной формы необходимый TTabSheet, отображаешь форму.
Вот мой пример(только он на С билдере, но на делфи почти все так же):
На форме лежит один PageControl с двумя вкладками.
В dll лежит одна форма на которой может быть все что угодно.
Код в Длл
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
        return 1;
}
//---------------------------------------------------------------------------
TForm* __export ShowForm(TWinControl*parent)
{
Application->CreateForm(__classid(TForm2), &Form2);
Form2->Parent=parent;
Form2->Left=0;
Form2->Top=0;
Form2->Height=parent->Height;
Form2->Width=parent->Width;
Form2->Visible=true;
return Form2;
}
А вот код в приложении:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
HANDLE lib;
TForm*second;
void __fastcall TForm1::FormCreate(TObject *Sender)
{
TForm*(*ShowDllForm)(TWinControl*parent);
String path=ExtractFilePath(Application->ExeName);
path+="DllProject.dll";
lib=LoadLibrary(path.c_str());
if(lib==NULL)
        {
        ShowMessage("Не найдена библиотека");
        return;
        }
ShowDllForm=(TForm* (*)(TWinControl*parent))GetProcAddress(lib,"@ShowForm$qp20Controls@TWinControl");
if(ShowDllForm==NULL)
        {
        ShowMessage("Не найдена функция");
        return;
        }
second=ShowDllForm(TabSheet1);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
delete second;
FreeLibrary(lib);
}
//--------
В аттаче находится пример на С++(ну не знаю я делфи)
Вложения
Тип файла: rar TabPlugin.rar (486.8 Кб, 29 просмотров)
2
 Аватар для nixstill
17 / 17 / 2
Регистрация: 15.01.2009
Сообщений: 86
19.09.2009, 02:21  [ТС]
Спасибо , за проявленный интерес к моему вопросу.
Все разобрался и в сишном коде, все как и большинстве примеров по делфи.
С одним плагином и формой это прокатывает и у меня работает с одним плагином, но стоит его продублировать (простым копированием dll), как один плагин грузиться успешно, а вот другой на другой TTabSheet уже нет.
Вот в этом то и состоял вопрос, как организовать загрузку типичных по структуре плагинов с формами?
0
 Аватар для Otaka
1857 / 714 / 55
Регистрация: 11.12.2008
Сообщений: 1,019
19.09.2009, 15:09
Не знаю, чего у тебя там не выходит, но у меня все работает прекрасно.
Вот тебе доработанный вариант с созданием новой вкладки для каждого ново созданного плагина.
Я решил немного там все переделать для удобства пользования.
Тут я привожу код библиотеки. Код, связанный с формой данной длл, приводить не буду, так как там может быть все что угодно.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
 
#include "DllUnit2.h"
#pragma argsused
 
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
        return 1;
}
//---------------------------------------------------------------------------
//Почему функция называется ShowForm, а она ничего не показывает, а только загружает?
//Это осталось еще с прошлого раза. Не исправил.
TForm* __export ShowForm()
{
Application->CreateForm(__classid(TForm2), &Form2);
return Form2;
}
В приложении, которое грузит данные платины, все чуть-чуть сложнее.
Разберем по шагам.
Сначала смотрим содержимое папки, в которой находится наша программа, на наличие ДЛЛок.
Грузим каждую Длл, и в ней пытаемся загрузить функцию ShowForm(билдер для организации перегрузок функций добавляет к имени еще кучу всякого мусора, а как указать конкретное экспортируемое имя я не знаю, так как лень искать). Если функции в библиотеке нет, выгружаем её из памяти и приступаем к другой библиотеке. Если функция есть, то мы её исполняем и сохраняем указатель на созданную ей форму в какой-то переменной. Создаем на PageControl новую вкладку, и присваиваем свойству Parent нашей ново созданной формы указатель на новую вкладку (каждая вкладка это, по сути, новое окно которое может иметь своих чайлдов).
Чтобы информация об этих формах не канула в небытие, мы должны где-то сохранить указатели на формы и хендлы всех загруженных библиотек. Я, например, создал класс TPlugin.
C++
1
2
3
4
5
6
class TPlugin
{
public:
HANDLE lib;
TForm*form;
};
В нем можно будет хранить информацию об одном плагине. Набор объектов этого класса (плагинов ведь много) можно хранить в массиве, но мы заранее не знаем, сколько их там будет.
Я люблю использовать list из стандартной библиотеки STL, но я не знаю, есть ли такая в Делфи. Воспользуемся классом TList, который есть и в Делфи и в Билдере, и будем в него сохранять все объекты класса TPlugin.
Вот код программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
class TPlugin
{
public:
HANDLE lib;
TForm*form;
};
TList*pluginmanager;
 
 
TPlugin* TForm1::LoadPlugin(String path)
{
HANDLE lib=LoadLibrary(path.c_str());
if(lib==NULL)
        {
        ShowMessage("Библиотека не найдена");
        return NULL;
        }
TForm*(*ShowDllForm)();
ShowDllForm=(TForm* (*)())GetProcAddress(lib,"@ShowForm$qv");
if(ShowDllForm==NULL)
        {
        ShowMessage("Функция не найдена");
        FreeLibrary(lib);
        return NULL;
        }
TForm*form=ShowDllForm();
 
//После того как мы загрузили плагин, мы сохраняем информацию о нем в классе TPlugin
TPlugin*pl=new TPlugin();
pl->lib=lib;
pl->form=form;
return pl;
}
 
void __fastcall TForm1::FormCreate(TObject *Sender)
{
pluginmanager=new TList();
//Обходим все файлы в папке, и ищем там плагины
 
String Path=ExtractFilePath(Application->ExeName)+"*.dll";
WIN32_FIND_DATA file;
HANDLE hfind=FindFirstFile(Path.c_str(),&file);
if(hfind!=INVALID_HANDLE_VALUE)
        {
        do
                {
                TPlugin*pl=LoadPlugin(file.cFileName);
                if(pl!=NULL)
                        {//Создаем новую вкладку
                        TTabSheet*page=new TTabSheet(PageControl);
                        page->PageControl=PageControl;
                        //Запоминаем плагин в списке плагинов
                        pluginmanager->Add(pl);
                        //Устанавливаем параметры формы
                        pl->form->Parent=page;
                        pl->form->Left=0;
                        pl->form->Top=0;
                        pl->form->Width=page->Width;
                        pl->form->Height=page->Height;
                        pl->form->Anchors=pl->form->Anchors<<akRight<<akBottom;
                        //Вкладка называется так же, как и Caption на форме плагина
                        page->Caption=pl->form->Caption;
                        pl->form->Visible=true;
                        }
                }while(FindNextFile(hfind,&file));
        FindClose(hfind);
        }
}
//---------------------------------------------------------------------------
 
//Удаляем плагины из памяти
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
for(int i=0;i<pluginmanager->Count;i++)
        {
        TPlugin*pl=(TPlugin*)pluginmanager->Items[i];
        delete pl->form;
        FreeLibrary(pl->lib);
        delete pl;
        }
pluginmanager->Clear();
}
//--------------------------------------------------------------------------
Теперь плагинов может быть сколько угодно.
Вложения
Тип файла: rar TabPlugin2.rar (674.3 Кб, 38 просмотров)
1
 Аватар для nixstill
17 / 17 / 2
Регистрация: 15.01.2009
Сообщений: 86
20.09.2009, 05:52  [ТС]
Еще раз огромное спасибо, за помощь!!!
Почти полностью разобрался в билдеровском коде Пределав его в дельфийский, но честно говоря чуть не перешел на билдер. Делфи заваливал ексепшенами, долго не понимал в чем дело, потому как след в след следовал приведенному коду. Камнем преткновения явилася строчка:
C++
1
delete pl->form;
Как я понял это разрушение сознанной ранее формы плагина. Или я не прав?
Я получал ексепшены именно когда пытался разрушить созданные формы, убрав это получил стабильную программу с плагинами на делфи (по крайнее мере мне так пока кажется ).
В связи с этим вопросы:
Правильно я поступил, что так сделал?
При выгрузки dll, освободились ли ресурсы в том числе и под созданные формы?

P.S. Дополнения просто супер!
0
 Аватар для Otaka
1857 / 714 / 55
Регистрация: 11.12.2008
Сообщений: 1,019
20.09.2009, 14:31
Я не совсем знаю как работает Делфи(я всегда думал, что точно так же как и Билдер), поэтому не знаю в чем там проблема.
Может нужно вызывать вместо delete, который в делфях делает что-то другое, метод
Delphi
1
pl.form.Free();
А вообще, если уж эта проблема совсем не решается, то при выключении программы автоматически происходит выгрузка всех ресурсов, библиотек(но это нехороший тон программирования).
0
 Аватар для nixstill
17 / 17 / 2
Регистрация: 15.01.2009
Сообщений: 86
24.10.2009, 00:15  [ТС]
В предложенном варианте Otaka, все работало замечательно до момента... как по мере необходимости мне пришлось добавить TListView (я и Otaka пробовали разные контролы, но большинство чувствует на ней себя хорошо) на форму одного из созданных dll плагинов...
Во тут начался кошмар с подменой TApplication и TScreen, хендлов и перентов...
И либо ошибкой "has no parent window", либо когда выбрана одна из строк TListView'ва при завершении работы приложения сыпит эксепшеном (если ни одна строка невыбрана, то завершается корректно).

Помогите пожалуйста!

PS Делал по исходникам выше на Delphi, но принимаются варианты как на билдере так и на делфи. Если так необходимы исходники на делфи могу приаттачить.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.10.2009, 00:15
Помогаю со студенческими работами здесь

Access 2007: отключить показ даты создания/изменения объектов
Как в основном окне Access'a отключить показ даты создания/изменения объектов?

Прикрутить к TPanel TScrollBar или Сделать горизонтальную прокрутку у TScrollBox в верху
Здравствуйте. К слову и сам вопрос Как прикрутить к TPanel TScrollBar или сделать горизонтальную прокрутку у TScrollBox в верху. ...

Создать копию TTabSheet
Здравствуйте, есть 1 TTabSheet сделанный через конструктор, по ходу выполнения программы мне нужно размножить эти листы, как можно это...

Лаунчер для игры: сделать авторизацию, запуск клиента, показ скина, и показ личного счета
Доброго времени суток ! Я создаю лаунчер одной игры( Minecraft ) Можете ли вы мне помочь с этим? Мне надо сделать авторизацию, запуск...

Ищу шаблон или набор плагинов, чтобы было похоже как на этом сайте
Сайт - http://agami.ru , хочу сделать похожий и даже лучше) Ссылку скорее всего удалят, поэтому напишу то, что ищу: 1) Боковое меню...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru