Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.07.26;
Скачать: [xml.tar.bz2];

Вниз

TMenuItem.Click -> any.dll procedure   Найти похожие ветки 

 
Dennis I. Komarov ©   (2009-05-22 10:38) [0]

Вопрос - не вопрос но:

Есть: некое приложение, интерфейс которого грузим из некой БД согласно правам пользователя, который запустил это приложение. В частности, возьмем ситуацию с TMainMenu. Согласно правам загрузилось дерево меню и подменюшек. Есть некая "ссылка" (int) на то, что должно выполнится при вызове соответствующего пункта. Процедура сего действия, а так же все интерфейсы и т.п. вынесены в библиотеку (dll).

Вопрос такой: Какая (а точнее, кто придумает лучшую) логика должна быть, чтобы связать конечный пункт менюшки с соответствующей процедурой в библиотеке, при том чтобы выполнялось условие: в приложении описана только логика а конкретные данные вынесены из него, т.е. при добавлении нового пункта (в БД) не изменялось само приложение, а только библиотека (или добавлялась новая)


 
Сергей М. ©   (2009-05-22 10:48) [1]

Не оч понятно ..

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

так ?


 
Palladin ©   (2009-05-22 10:51) [2]


> чтобы связать конечный пункт менюшки с соответствующей процедурой
> в библиотеке

TMenuItem.Tag
можно хранить там адрес, полученный GetProcAddress


 
Сергей М. ©   (2009-05-22 10:52) [3]

И опять напрашивается уже изрядно поднадоевший контрвопрос - почему dll, а не bpl ? Чем в дан.случае оправдан выбор ?


 
Dennis I. Komarov ©   (2009-05-22 11:22) [4]


> Сергей М. ©   (22.05.09 10:48) [1]

Не совсем. Сделать в рантайм пункт, выполнить по нему процедуру из вне это не проблема. Вопрос в самой логике которая прописана в exe, и которая не зависит от конечных пунктров и прицедур. Она одна и не меняется от изменения интерфейса...


> Palladin ©   (22.05.09 10:51) [2]

да не суть где хранить, в tag, или брать из вне.
GetProcAddress сохранили. Далее как вызвать процедуру, не зная что это за процедура? Не должно о ней ничего знать приложение...


> Сергей М. ©   (22.05.09 10:52) [3]

Чтобы абстрагироваться от борланд. Ну не будем об этом. Я знаю что есть bpl и с ним все намного проще...


 
Palladin ©   (2009-05-22 11:25) [5]


> Далее как вызвать процедуру, не зная что это за процедура?
>  

Ты интересный, а как ты собрался параметры передавать не зная ничего о процедуре?


 
Dennis I. Komarov ©   (2009-05-22 11:34) [6]

Ну, собственно это вот и надо выдумать :)
Ну к примеру некий базовый тип одинаковый для всех вызываемых таким образом процедур. Или передавать только указатель памяти, а там уже извращаться и читать какие-то входящие параметры


 
Сергей М. ©   (2009-05-22 11:42) [7]


> Чтобы абстрагироваться от борланд


Чтобы исключить зависимость от особенностей и требований конкретных сред разработки и исполнения и обеспечить универсальность интерпроцессного/интермодульного взаимодействия, мелкомягкими придуман COM/OLE-механизм.
Предлагаю обратить на него свой взор)


> как вызвать процедуру, не зная что это за процедура?


См. выше.


 
Dennis I. Komarov ©   (2009-05-22 12:06) [8]


> Чтобы исключить зависимость от особенностей и требований
> конкретных сред разработки и исполнения и обеспечить универсальность
> интерпроцессного/интермодульного взаимодействия, мелкомягкими
> придуман COM/OLE-механизм.
> Предлагаю обратить на него свой взор)

Ну что-то я не сильно тут COM/OLE представляю :) Тупо возьмем пункт "пользователи" и все что в нем цепляем к ???users.dll в которой формочки типа добавить, удалить, права, группы и прочая ерунда касаемая юзверей.


> См. выше.

нету bpl, так сегодня в гороскопе написано :)

З.Ы. Пишем "некое универсальное ядро" с администрировалкой


 
clickmaker ©   (2009-05-22 12:16) [9]

> Далее как вызвать процедуру, не зная что это за процедура?
> Не должно о ней ничего знать приложение

а это не противоречит тому, что "в приложении описана только логика"?


 
Сергей М. ©   (2009-05-22 12:20) [10]


> > См. выше.
>
> нету bpl,


Выше - это я про COM/OLE


> что-то я не сильно тут COM/OLE представляю


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


 
Dennis I. Komarov ©   (2009-05-22 12:24) [11]


> а это не противоречит тому, что "в приложении описана только
> логика"?

Ну а собственно, в каком месте противоречие?


 
Dennis I. Komarov ©   (2009-05-22 12:35) [12]


> Библиотеки типов, поддерживаемые этой технологией, дают
> возможность...

Пугает меня такая реализация... Примеры можно?


 
clickmaker ©   (2009-05-22 12:55) [13]

> в каком месте противоречие?

если логика жестко зашита в приложении, и появилась новая DLL с новой функциональностью. Как приложение узнает, какие данные туда передавать и откуда их брать?

Если же это плагинная архитектура и dll строго унифицированы, то какая проблема? Параметры заранее известны, имена экпортируемых функций тоже...


 
Сергей М. ©   (2009-05-22 13:05) [14]

http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_23920412.html


 
Dennis I. Komarov ©   (2009-05-22 13:10) [15]


> если логика жестко зашита в приложении, и появилась новая
> DLL с новой функциональностью. Как приложение узнает, какие
> данные туда передавать и откуда их брать?
>
> Если же это плагинная архитектура и dll строго унифицированы,
>  то какая проблема? Параметры заранее известны, имена экпортируемых
> функций тоже...

нет, не плагины. параметры не известны, имена передать можно. Как одно из решений, именно, стандартизация процедур, т.е. все процедуры имеют одинаковые входные параметры. Еще com/ole предлагают. Может еще кто чего придумает...


 
clickmaker ©   (2009-05-22 13:13) [16]

> нет, не плагины. параметры не известны,

вот о чем я и говорю. "Как приложение узнает, какие данные туда передавать и откуда их брать?"


 
Dennis I. Komarov ©   (2009-05-22 13:16) [17]


> Сергей М. ©   (22.05.09 13:05) [14]

плохой пример :) предлагает зарегится на 30 дней аля триал


 
Dennis I. Komarov ©   (2009-05-22 13:21) [18]


> clickmaker ©   (22.05.09 13:13) [16]
> вот о чем я и говорю.


Не, это я спрашиваю, как сие обойти можно :)


 
Сергей М. ©   (2009-05-22 13:34) [19]


> как сие обойти можно


см. TComServer.TypeLib


 
clickmaker ©   (2009-05-22 13:35) [20]

> как сие обойти можно

приложение является некоей консолью и содержит только базовую функциональность, независимую от DLL.
А также предоставляет пункты меню для вызова функций из DLL.
Разумеется, имена функций, параметры и значения должны быть известны приложению.

Я писал что-то подобное. MDI приложение, которое обеспечивает коннект к серверу, определение прав пользователя и загрузку DLL-оснасток соответственно этим правам. Готовый коннект и другая служебная инфа передается в DLL. А DLL экспортируют фрэймы, которые располагаются на mdi-чайлдах. Вся функциональность и UI - только в DLL.
Примерно по такому принципу работает и виндозная MMC.


 
Dennis I. Komarov_   (2009-05-22 19:37) [21]


> Сергей М. ©   (22.05.09 13:34) [19]

Не кажется ли что из пушки по вообьм?


> clickmaker ©   (22.05.09 13:35) [20]
> приложение является некоей консолью
> и содержит только базовую функциональность, независимую
> от DLL.А также предоставляет пункты меню для вызова функций
> из DLL.Разумеется, имена функций, параметры и значения должны
> быть известны приложению.

Ну вот придется все загнать в жесткие рамки и передавать только определенные парметры, но на все случии жизни :)


> Я писал что-то подобное. MDI приложение,
>  которое обеспечивает коннект к серверу, определение прав
> пользователя и загрузку DLL-оснасток соответственно этим
> правам. Готовый коннект и другая служебная инфа передается
> в DLL. А DLL экспортируют фрэймы, которые располагаются
> на mdi-чайлдах. Вся функциональность и UI - только в DLL.
> Примерно по такому принципу работает и виндозная MMC.


Тогда пара вопросов:
1. Как передать коннект к серверу БД библиотеке, или лучше пус каждая сама инициирует соединение?
2. Как передать родителя фрейму?

З.Ы. Вот так вот, был и-нет и вдруг его нету...


 
clickmaker ©   (2009-05-22 20:03) [22]

> Тогда пара вопросов:

1. Ну в моем случае это был не коннект к БД, а ссылка на интерфейс сервера-приложений (IAppServer). Передавать готовый коннект или коннекшн стринг - зависит от используемой технологии и того, на чем предполагается писать DLL. АДО, например, для каждого потока должна юзать свой коннект. Т.е. если в DLL возможны отдельные потоки, надо это учитывать.
2. Функция из DLL возвращает TFrame. В приложении просто делаем Frame.Parent := SomeForm;

При этом и DLL и exe должны быть собраны с "build with runtime packages", иначе будет косяк с типами.


 
Slym ©   (2009-05-24 13:24) [23]

clickmaker ©   (22.05.09 20:03) [22]
1. Ну в моем случае это был не коннект к БД, а ссылка на интерфейс сервера-приложений (IAppServer). Передавать готовый коннект или коннекшн стринг - зависит от используемой технологии и того, на чем предполагается писать DLL. АДО, например, для каждого потока должна юзать свой коннект. Т.е. если в DLL возможны отдельные потоки, надо это учитывать

+100

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


 
Dennis I. Komarov_   (2009-05-24 18:58) [24]

DLL пишутся на чем угодно, вернее должна быть такая возможность, чтобы любой разработчик (не зависимо от языка) мог добавить свою библиотеку...

Ну да, СУБД скажем неопределенная. На данный момент через ADO к MS SQL, но это не факт, что так и останется. Должна быть универсальная реализация. Возможно, трехзвенка в данном случае - это лучшее решение.

Исходя из вышесказанного несовсем понятно как быть TFrame, т.е. мы привязываемся к "build with runtime packages", что противоречит "кроссплатформенности" DLL. Мои попытки такие:

TFunc = function(AHandle...): Boolean;
...
var
 AnyF: TFun;
...

[DLL]
funtion AnyF(AHandle): Boolean;
begin
 Application.Handle:=AHandle;
 with TAnyFrame.Create(Application) do begin
   Parent:=Application.MainForm.ActiveChildForm;
 end;
end;
 
Получаю AV. Пока не понял на чем, т.е. чего не создано...


 
Сергей М. ©   (2009-05-24 19:16) [25]


> не понял на чем, т.е. чего не создано


MainForm =  nil


 
Dennis I. Komarov_   (2009-05-24 19:22) [26]


> Сергей М. ©   (24.05.09 19:16) [25]
MainForm =  nil


Ну, пусть... Да и не сильно болшая разница чего нехватает. Хотя почему-то Create(Application) не "прокатывает". Вероятно там только хендл и юзается. Ну да бог с ними...
Варианты реализации кто предложит?


 
Dennis I. Komarov_   (2009-05-24 19:30) [27]


> Сергей М. ©   (24.05.09 19:16) [25]

А вот и нет, прекрасно ловим AV и без строки

Parent:=Application.MainForm.ActiveChildForm;


 
Сергей М. ©   (2009-05-24 20:40) [28]


> Dennis I. Komarov_   (24.05.09 19:30) [27]


Ты мне загадки решил тут загадывать ?)
Возьми дебагер да оттрассируй пошагово, чтобы понять источник AV ..

И зачем, кстати, в кач-ве владельца фрейма тебе потребовался именно компонент Application ?


 
Dennis I. Komarov_   (2009-05-24 21:07) [29]


> Сергей М. ©   (24.05.09 20:40) [28]
> > Dennis I. Komarov_   (24.05.09 19:30) [27]Ты мне загадки
> решил тут загадывать ?)Возьми дебагер да оттрассируй пошагово,
>  чтобы понять источник AV ..

:) Да ну ее к лешему эту AV. Вот правой пяткой чую, что от того что я найду виновника - не ни тепло, ни холодно не будет...

> И зачем, кстати, в кач-ве владельца
> фрейма тебе потребовался именно компонент Application ?

А через него я до Parent-a хотел добраться...А что тут крименального? Вообщто, да. Не совсем правильно. Надо самоу следить за его ничтожением, а не сваливать это на чужой Application


 
Dennis I. Komarov ©   (2009-05-25 10:43) [30]

Так, ну вот и вернулся привычный инет...

Я так понимаю, придется виндовые окна экспортировать? :(

Ну у кого какие мысли еще есть?

Как экспортировать как виндовое окно, в лице TFrame?


 
clickmaker ©   (2009-05-25 11:20) [31]

> Как экспортировать как виндовое окно, в лице TFrame?

Frame.Handle
насчет кроссплатформенности
CreateParented - VCL
CreateWindow - API


 
Slym ©   (2009-05-25 11:46) [32]

Slym ©   (24.05.09 13:24) [23]
решается и кросплатформенность: напеши фрейворк, определи типы контролов, и типы евентов... аля 1С получица


 
Dennis I. Komarov ©   (2009-05-25 11:54) [33]


> clickmaker ©   (25.05.09 11:20) [31]

Ну и я про то, что о VCL придется забыть...

Мануал - пример можно?

Ну создали мы некий TAnyFrame - он как окно должен быть со своим хендлом.
передали хендл приложению, дальше что?


 
Dennis I. Komarov ©   (2009-05-25 11:56) [34]


> решается и кросплатформенность: напеши фрейворк, определи
> типы контролов, и типы евентов... аля 1С получица


ну сейчас еще с окнами повожуся и приступлю к написанию "2С" :)


 
clickmaker ©   (2009-05-25 11:57) [35]

> передали хендл приложению, дальше что?

а тут всего 2 варианта. Либо в DLL передаем хэндл родителя и там либо CreateWindow либо CreateParented, либо возвращаем хэндл из DLL и делаем SetParent


 
Dennis I. Komarov ©   (2009-05-25 12:34) [36]


> в DLL передаем хэндл родителя и там либо CreateWindow либо
> CreateParented

не совсем понял, у нас же в длл есть созданный TFrame, по сути тот же Window

> либо возвращаем хэндл из DLL и делаем SetParent

т.е.
[DLL]
TAnyFrame.Create(nil);
Result:=TAnyFrame.Handle;

[EXE]
if SetParent(HandleFromDll, ActiveChildForm) = nil then ...


 
clickmaker ©   (2009-05-25 12:42) [37]

> не совсем понял, у нас же в длл есть созданный TFrame, по
> сути тот же Window

ну, наверно все-таки правильней так
[DLL]
function CreateFrame(AParent: HWND): TFrame;
begin
 Frame := TAnyFrame.CreateParented(AParent);
 Result := Frame.Handle;
end;


 
clickmaker ©   (2009-05-25 12:50) [38]

т.е. function CreateFrame(AParent: HWND): HWND, конечно же

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


 
Dennis I. Komarov ©   (2009-05-25 13:39) [39]

Все хорошо, но где-то не хорошо :(

[DLL]
...
type
 TFrameUsers = class(TFrame)
   ListViewUsers: TListView;
   Splitter1: TSplitter;
   PageControl1: TPageControl;
   StatusBar1: TStatusBar;
   TabSheet1: TTabSheet;
   TabSheet2: TTabSheet;
   ToolBar1: TToolBar;
   ImageList1: TImageList;
   ToolButton1: TToolButton;
 private
   { Private declarations }
 public
   { Public declarations }
 end;

function CreateIUsers(AParent: HWND): HWND; stdcall;

implementation

{$R *.dfm}

function CreateIUsers;
begin
 with TFrameUsers.CreateParented(AParent) do begin
   Result:=Handle;
 end;
end;


Ловим "control "Frame" has no parent window
Хэндл в функцию передается
...


 
clickmaker ©   (2009-05-25 13:44) [40]

> Ловим "control "Frame" has no parent window

в какой момент?



Страницы: 1 2 3 4 вся ветка

Форум: "Начинающим";
Текущий архив: 2009.07.26;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.008 c
15-1243068393
dr_creigan
2009-05-23 12:46
2009.07.26
USB-порт


2-1243667222
Иван
2009-05-30 11:07
2009.07.26
Многострочный текст в константах


15-1243110603
Юрий
2009-05-24 00:30
2009.07.26
С днем рождения ! 24 мая 2009 воскресенье


2-1244023953
andzav
2009-06-03 14:12
2009.07.26
Из DataTimePicker вставляется в поле не только дата, но и время


2-1243871211
Максим
2009-06-01 19:46
2009.07.26
TPopUpMenu + WM_COMMAND





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский