Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

зАКЛАДКА вОЗМОЖНОСТИ иСПОЛЬЗОВАНИЯ пЛАГИНОВ в пРОГУ

1.3K
17 марта 2004 года
zja
119 / / 25.11.2003
надо мне сделать программу, для ускорения заполнения стандартных документов. Вроде все просто: делаешь форму с нужными полями и какой-то минимальный набор методов для этой формы (печать, просмотр, сохранить, etc.) Проблема: форм много, они все разные, вплоть до разных форматов бумаги(есть и на нескольких листах А4 и чуть ли не для марок). Хочется что-то вроде оболочки в которую в дальнейшем можно будет добавлять новые формы. Короче нужно отделить шаблоны форм от самой программы. Как бы это сделать, поделитесь идеями.
RE: может просто сделать голую форму кот. будет искать в папке plugins в корневом относительно себя каталоге другие формы и все какие найдет - подключать? хотя как-то замороченно получается, но согласитесь тоже вариант.
RE2: тогда встречный вопрос, это вообще сильно сложно, чтобы одна форма подключала другую просто найдя ее файл, хм, ведь с таким успехом можно вообще неизвестно что "наподключать", если это свалено в соотвт. папку.
10
17 марта 2004 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by zja
Как бы это сделать, поделитесь идеями


Можно сделать как угодно, лишь бы задачу решало и клиент был доволен.
Мы, например, на работе используем потомков TFrame для экспорта из плагинов.

1.3K
17 марта 2004 года
zja
119 / / 25.11.2003
Цитата:
Originally posted by smartsoft

Можно сделать как угодно, лишь бы задачу решало и клиент был доволен.
Мы, например, на работе используем потомков TFrame для экспорта из плагинов.


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

860
18 марта 2004 года
Abell2000
138 / / 15.01.2003
Цитата:
Originally posted by zja

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


А кто сказал, что туда нужно, что-то включать, так бы ни один плагин никогда не заработал. Определяешь хэндл окна и все.

1.3K
18 марта 2004 года
zja
119 / / 25.11.2003
Цитата:
Originally posted by Abell2000

А кто сказал, что туда нужно, что-то включать, так бы ни один плагин никогда не заработал. Определяешь хэндл окна и все.


тоже вариант... тут кстати поступило вне этого форума такое предложение: наштопать из потенциальных форм дллек и складировать их в одну папку например plug-ins, но с окнами тоже можно, короче на самом деле вариантов достаточно, интересно какой из них проще, впрочем проработать попробую все, хотя бы для самообразования

10
18 марта 2004 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by zja
Почитаю что-нибудь на эту тему. Проблема с формами, например, в том, что для того чтобы головная форма знала ту которую будет вызывать, нужно включить заголовочный файл включаемой формы в заголовочный файл вызывающей формы на этапе разработки, а если это новая форма...? кстати с фреймами наверное что-то похожее тоже есть, как вы такую проблему обошли?


У нас фрейм имеет виртуальные методы, определенные в предке как абстрактные, и реализованные в потомках. И потом, не надо забывать тот факт, что компоненты имеют виртуальный конструктор, и могут быть созданы через RTTI. Наши плагины как раз используют данный метод. Они экпортируют фукнцию, возвращающую класс плагина, а в памяти создает его уже вызывающая программа.
И потом, наши плагины, и сама программа работают в единой среде выполнения, обеспечиваемой BPL-ами. Если не использовать BPL-ы, ИМХО, работать не будет. Будут возникать глупые ошибки, вроде "Cannont assign TFont to TFont".

358
18 марта 2004 года
moonmike
423 / / 18.10.2002
Через dll это все решается. В моей проге за каждый пункт меню отвечает одна dll(вернее за каждый выделенный бизнес-процесс). А в хост программе есть только администрирование:
Добавление пользователей, добавление новых пунктов меню, указание папки для LiveUpdate, указание папки в которой хранятся плугины.
В каждой dll помимо функций реализующих непосредственно БП есть две функции о которых знает хост-программа. ВОт через них то она их и вызывает.
1.3K
18 марта 2004 года
zja
119 / / 25.11.2003
2moonmike: 2smartsoft: можно примеры? если конечно не ком.тайна, реально удобно вызвать в exe (имеется ввиду головная форма приложения) файле класс, именно класс, а не ф-цию, из дллки НЕЛЬЗЯ. Если кто не согласен прошу приводить действующие примеры. У кого нет своих примеров - можете почитать rxlib.ru/progi/forum_poisk.php?spoisk=typedef там правда не сначала, но зато очень по теме.
358
18 марта 2004 года
moonmike
423 / / 18.10.2002
Окей, вот пример:
Меню в хост грузим из БД. У всех пунктов меню назначаем один и тот же обработчик:
void __fastcall TfrmMain::DllMenuClick(TObject * Sender)
{
AnsiString A,S = ((TMenuItem*)Sender)->Name;
typedef AnsiString (__import *Prop)();
typedef HWND (__import *Sh)(AnsiString &Capt, void *Conn);
Prop MyProp;
Sh ShowMy;
HINSTANCE Dll;
for (int i = 0; i < Dlls->Count; i++)
{
Dll = LoadLibrary(Dlls->Strings.c_str());
if(Dll != NULL)
{
MyProp = (Prop)GetProcAddress(Dll,"_ReturnProperty");
A = MyProp();
}
if (S != A)
{
FreeLibrary(Dll);
}
else
{
ShowMy = (Sh)GetProcAddress(Dll,"_ShowDllForm");
AnsiString B = ((TMenuItem*)Sender)->Caption;
HWND in;
ShowMy(B,MTODm->ADOConnection1);
break;
}
}
}
В каждой dll соответсвенно есть функции:
ReturnProperty
и
ShowDllForm
для примера:
//---------------------------------------------------------------------------
//"zavspecfunc.cpp"
#include <vcl.h>
#pragma hdrstop

#include "zavspecfunc.h"
#include "ZavodSpec.h"
//---------------------------------------------------------------------------
AnsiString ReturnProperty()
{
return Name;
}
//---------------------------------------------------------------------------
HWND ShowDllForm(AnsiString &Capt, void *AC)
{
if(Application->MainForm->Menu->Items->Find("Окна")->Find(Capt))
{
ShowWindow(FindWindow("TfrmZavodSpec",Capt.c_str()),SW_SHOW);
SetForegroundWindow(FindWindow("TfrmZavodSpec",Capt.c_str()));
return 0;
}
else{
TfrmZavodSpec *frmZavodSpec = new TfrmZavodSpec(Application, AC, Capt);
frmZavodSpec->Show();
return frmZavodSpec->Handle;
}
}
#pragma package(smart_init)
А это хидер
//---------------------------------------------------------------------------
//"zavspecfunc.h"
#ifndef zavspecfuncH
#define zavspecfuncH
//---------------------------------------------------------------------------
AnsiString Name = "ZavodSpec";
extern "C" __declspec(dllexport) AnsiString ReturnProperty();
extern "C" __declspec(dllexport) HWND ShowDllForm(AnsiString &Capt, void *AC);
#endif

В БД сохраняется не только Caption пункта меню но и его Name. А Name назначается равным AnsiString Name = "ZavodSpec";
1.3K
18 марта 2004 года
zja
119 / / 25.11.2003
Внутри TfrmZavodSpec должна быть работа с переданным соединением, например получение каких-нибудь параметров формы. Я правильно понимаю?
RE:
Цитата:
В БД сохраняется не только Caption пункта меню но и его Name. А Name назначается равным AnsiString Name = "ZavodSpec";

Можно пояснить, для особо тупых типа меня?

358
18 марта 2004 года
moonmike
423 / / 18.10.2002
Цитата:
Originally posted by zja
Внутри TfrmZavodSpec должна быть работа с переданным соединением, например получение каких-нибудь параметров формы. Я правильно понимаю?
RE:
Можно пояснить, для особо тупых типа меня?


Таблица из которой грузится меню имеет следующую структуру:

 
Код:
CREATE TABLE [dbo].[Menu] (
    [menu_id] [int] IDENTITY (1, 1) NOT NULL ,
    [Naim] [char] (30) COLLATE Cyrillic_General_CS_AS NOT NULL ,
    [Owner] [int] NULL ,
    [Caption] [varchar] (100) COLLATE Cyrillic_General_CS_AS NOT NULL ,
    [OnClick] [varchar] (100) COLLATE Cyrillic_General_CS_AS NULL
) ON [PRIMARY]

Где Naim - название пункта меню, совпадающее с переменной Name в dll отвечающей за обработку клика по данному пункту меню.
Для примера если в БД Naim = MyDll, то и в выше приведенном листинге было бы не AnsiString Name = "ZavodSpec" , а AnsiString Name = "MyDll";
Owner - указывает на пункт меню подпунктом которого является текущий пункт.
Caption - соответсвенно Caption пункта меню.
OnClick - название обработчика.
В dll, как нетрудно заметить из листинга:
ShowMy(B,MTODm->ADOConnection1);
Я передаю указатель на соединение с БД, и название пункта меню.Работа с хостом из dll спокойно осуществляется через Application->MainForm.
860
19 марта 2004 года
Abell2000
138 / / 15.01.2003
Вот еще пример (добавляем закладки. Таким макаром можно всю форму как из кирпичиков соорудить):
main poga---------->
typedef TForm* (__stdcall *GETNEWTAB)(TWinControl*);
typedef char* (__stdcall *GETNAME)();
...
void __fastcall TForm1::FormCreate(TObject *Sender)
{
LoadedPluginsCount=0;
PlugList=new TList();
AnsiString names[]={"Project_11.dll","Project_11b.dll","Project_11c.dll"};

for(int i=0;i<sizeof(names)/sizeof(names[0]);i++){
PlugObj PlugIn=new PlugInfo;
PlugIn->lib=LoadLibrary(names.c_str());
if(PlugIn->lib)
try{
GETNEWTAB GetNewTab=(GETNEWTAB)GetProcAddress(PlugIn->lib,"_GetNewTab");
GETNAME GetName=(GETNAME)GetProcAddress(PlugIn->lib,"_GetName");
if(GetNewTab&&GetName){
TTabSheet *newTab=new TTabSheet(this);
newTab->PageControl=MainPC;
newTab->Caption=AnsiString(GetName());
PlugIn->TabForm=GetNewTab(newTab);
PlugIn->newTab=newTab;
}
LoadedPluginsCount++;
PlugList->Add(PlugIn);
}catch(...){ FreeLibrary(PlugIn->lib);}
}
}
//-----------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
for(int i=0;i<LoadedPluginsCount;i++){
PlugObj PlugIn=(PlugObj)PlugList->Items;
if(PlugIn->lib!=NULL){
delete PlugIn->TabForm;
delete PlugIn->newTab;
FreeLibrary(PlugIn->lib);
}
delete PlugIn;
}
delete PlugList;
}
//-----------------------------------------------
header--->
TPageControl *MainPC;
....
TList *PlugList;
typedef struct PlugInfo{
HINSTANCE lib;
TForm *TabForm;
TTabSheet *newTab;
} *PlugObj;
int LoadedPluginsCount;
... ---------------------------------------------
ну и собсно в dll----------->
#include "Unit_121.h"// в Unit_121.срр наш класс для новой закладки
extern "C" __declspec(dllexport) TForm* GetNewTab(TWinControl* owner);
extern "C" __declspec(dllexport) char* GetName();
...
TForm* GetNewTab(TWinControl* owner)
{
TForm1 * form=new TForm1(owner);
form->Parent=owner;
form->Left=0;
form->Top=0;
form->Visible=true;
return form;
}
...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог