Форум: "Начинающим";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];
ВнизСвойство Parent Найти похожие ветки
← →
CodeMaster © (2009-01-30 21:52) [0]Всем привет! У меня есть вопрос.
Есть DLL-ка в которой хранятся компоненты, и есть конфигурационный файл - содержащий данные о компонентах.
[Main]
POGiButtons=1
POGiButton1=POGiButton1
[POGiButton1]
X=0
Y=0
FrameCount=4
Image=PlayPauseBtn_skin.bmp
Name=Play
Parent=Form1
Вопрос: Как мне вывести компонент на форму которая не принадлежит DLL?
P.S Использовал Parent:= TForm(FindWindow(PCHAR("TForm1"),nil)) не помогло
← →
palva © (2009-01-30 22:07) [1]dll хранит откомпилированные процедуры и функции. Можно приспособить ее, чтобы она хранила некоторые статические данные. Расскажите сначала, как вы храните в библиотеке компоненты и что вы подразумеваете под компонентами.
← →
CodeMaster © (2009-01-30 22:24) [2]Визуальные компоненты храню, это различные кнопочки меню и.т.д. т.е DLL-ка это скиновый движок для программы. Только вот незнаю как мне через DLL вывести на форму компонент при условии что я заранее не знаю куда будет выводится он. Т.е пользователь сам задаёт на какую форму кидать компонент.
P.S Всего в программе 10 Форм.
← →
CodeMaster © (2009-01-30 22:25) [3]Вот пример того что хранится в DLL:
library ScriptEngine;
uses
SysUtils,
Classes,
IniFiles,
Windows, Dialogs,
pogi_button in "pogi_button.pas";
{$R *.res}
var
POGiButtons: array of TPOGiButton;
function POGi_ScriptEngineInit(ConfFileName: String): Boolean; stdcall; export;
var
hRet: Boolean;
Ini: TIniFile;
i,Count: Integer;
POGiInfButton: TPOGiButtonIni;
begin
Result:= False;
if not FileExists(ConfFileName) then Exit;
Ini:= TIniFile.Create(ConfFileName);
try
Count:= Ini.ReadInteger("Main","POGiButtons",Count);
if Count < 1 then Exit;
SetLength(POGiButtons,Length(POGiButtons) + 1);
for i:= 1 to Count do begin
SetLength(POGiButtons,Length(POGiButtons) + 1);
ZeroMemory(@POGiInfButton,SizeOf(POGiInfButton));
with POGiInfButton do begin
X:= Ini.ReadInteger("POGiButton" + IntToStr(i),"X",X);
Y:= Ini.ReadInteger("POGiButton" + IntToStr(i),"Y",Y);
Name:= Ini.ReadString("POGiButton" + IntToStr(i),"Name",Name);
Image:= Ini.ReadString("POGiButton" + IntToStr(i),"Image",Image);
FrameCount:= Ini.ReadInteger("POGiButton" + IntToStr(i),"FrameCount",FrameCount);
Parent:= Ini.ReadString("POGiButton" + IntToStr(i),"Parent",Parent);
ShowMessage("243");
if not FileExists(Image) then Exit;
POGiButtons[i]:= TPOGiButton.Create(Name,Image);
POGiButtons[i].Left:= X;
POGiButtons[i].Top:= Y;
POGiButtons[i].Name:= Name;
POGiButtons[i].FRameCount:= FrameCount;
end;
end;
finally
Ini.Free;
end;
Result:= True;
end;
exports POGi_ScriptEngineInit;
begin
end.
← →
CodeMaster © (2009-01-30 22:28) [4]ShowMessage("234"); это лишнее, это я проверял функция вызывается ли
← →
CodeMaster © (2009-01-30 22:31) [5]заметил ошибку в этой строке:
POGiButtons[i]:= TPOGiButton.Create(Name,Image);
--------------------------------------------------
POGiButtons[i]:= TPOGiButton.Create(Parent,Image);
Но никакого эффекта
← →
palva © (2009-01-30 23:03) [6]
> CodeMaster © (30.01.09 22:25) [3]
Подождите, вы же сказали, что храните в dll компоненту. У вас же хранится код функции. Как же вы собираетесь читать из библиотеки компоненту?
← →
palva © (2009-01-30 23:09) [7]
> POGiButtons[i]:= TPOGiButton.Create(Name,Image);
Разберитесь, как устроен конструктор. Где-то здесь надо надо передавать ссылку на текущую форму. Также нужно присваивать текущую форму в качестве владельца. Но это надо знать, как устроен POGiButton
← →
Германн © (2009-01-31 00:52) [8]
> CodeMaster © (30.01.09 22:24) [2]
>
> Визуальные компоненты храню, это различные кнопочки меню
> и.т.д. т.е DLL-ка это скиновый движок для программы. Только
> вот незнаю как мне через DLL вывести на форму компонент
> при условии что я заранее не знаю куда будет выводится он.
> Т.е пользователь сам задаёт на какую форму кидать компонент.
>
> P.S Всего в программе 10 Форм.
Бред!
Давно не ругался грязно. Но не могу сдержаться!
Если и программа и скин-библиотека написаны на Дельфи, то зачем использовать dll, которая исходно не предназначена для таких извращений? Почему её не заменить на родную для Дельфи bpl?
← →
CodeMaster © (2009-01-31 04:47) [9]Вот такой конструктор имеет TPOGiButton
constructor TPOGiButton.Create(FormWnd: String; FileName: String);
begin
inherited Create(nil);
Parent:= TForm(FindWindow("T" + FormWnd,nil));
Parent.DoubleBuffered:= True;
ControlStyle:=ControlStyle + [csOpaque];
FThread_timer:=TThread_timer.Create;
FThread_timer.OnTimer:=OnDraw_out;
FThread_timer.Interval:=15;
if not FileExists(FileName) then Exit;
BackBitmap:= TBitmap.Create;
BackBitmap.Handle:= LoadImage(0,PChar(FileName),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
end;
Разберитесь, как устроен конструктор. Где-то здесь надо надо передавать ссылку на текущую форму
Вот вот где мне взять вот эту ссылку, с помощью string я пока ничего не добился
← →
CodeMaster © (2009-01-31 04:49) [10]Сам TPOGiButton наследник класса TImage
← →
KSergey © (2009-01-31 06:37) [11]По-моему, автору стоит прочитать для начала вот это
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=342
Про создание "кнопочек" (и не только) в run-time, а так же свойство парент там написано хорошо и подробно.
← →
CodeMaster © (2009-01-31 07:20) [12]Отказался я от поиска формы на которую можно кнопку кинуть, но столкнулся с другой проблемой - форму куда кидать кнопку я знаю, но при создании вылетает вот это сообщение: Cannot Assign a TFont to a TFont.
Код выглядит следующий образом:
constructor TPOGiButton.Create(PForm: TComponent; FileName: String);
begin
inherited Create(PForm);
Parent:= TWinControl(PForm);
Parent.DoubleBuffered:= true;
ControlStyle:= ControlStyle + [csOpaque];
FThread_timer:=TThread_timer.Create;
FThread_timer.OnTimer:=OnDraw_out;
FThread_timer.Interval:=15;
if not FileExists(FileName) then Exit;
BackBitmap:= TBitmap.Create;
BackBitmap.Handle:= LoadImage(0,PChar(FileName),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
end;
Я уже голову сломал, не знаю чё делать
← →
KSergey © (2009-01-31 08:34) [13]На какой конкретно строке ошибка?
А вот эта строчка коды выглядит очень наглой:
Parent:= TWinControl(PForm);
С какой такой радости приводите без проверки? Может тогда уж параметр на TWinControl заменить правильнее (а то и вовсе TForm)? Иначе не понятно как жить и кто будет крайним, если в функцию будет передан - как и прошено - TComponent.
К стати, есть у меян смутное воспоминание, что не все операции по изменению свойств WinControl (а кнопка - ВинКонтрол) допустимы в конструкторе, чего-то тама еще вроде недосоздано, но могу врать.
← →
CodeMaster © (2009-01-31 08:52) [14]да ккая разница что с if PForm is TForm, что без всё равно не работает.
К стати, есть у меян смутное воспоминание, что не все операции по изменению свойств WinControl (а кнопка - ВинКонтрол) допустимы в конструкторе, чего-то тама еще вроде недосоздано, но могу врать.
Без Dll всё работает ок.
← →
CodeMaster © (2009-01-31 08:53) [15]Вот именно на вот этой строчке Parent:= TWinControl(PForm); выходит ошибка
← →
KSergey © (2009-01-31 09:24) [16]А что,
constructor TPOGiButton.Create(PForm: TComponent; FileName: String);
находится в DLL, а вызывают его из основной проги? (ну или наоборот) Верно мне мой телепотор подсказывает? (к стати, если верно, то if PForm is TForm длжно давать false, так что стоит проверить)
← →
CodeMaster © (2009-01-31 09:42) [17]А что,
constructor TPOGiButton.Create(PForm: TComponent; FileName: String);
находится в DLL, а вызывают его из основной проги? (ну или наоборот)
Вызов идёт из DLL
к стати, если верно, то if PForm is TForm длжно давать false, так что стоит проверить
Да верно ты говоришь она даёт false потому что PForm имеет класс совсем другой. В моём случае TForm1.
← →
KSergey © (2009-01-31 09:50) [18]> CodeMaster © (31.01.09 09:42) [17]
> Да верно ты говоришь она даёт false потому что PForm имеет класс совсем другой. В моём случае TForm1.
Гы :))) сорри, не удержался.
Ну проверь на TForm1. Скажешь нет тут TForm1 (гд епроверка)?
Хорошо, тогда там где оно есть (я уж запутался dll это или exe) проверь является ли оно при этом TForm. (без 1!!!) Ты будешь немало поражен выяснив, что что объект типа TForm1 является так же и TForm. Но только в пределах одной dll или exe.
А вот дальше - самое интересное, впрочем про это уже говорилось в [8].
PS
Это, буквари надо все ж почитать, а то это бесполезняк полный.
← →
KSergey © (2009-01-31 10:01) [19]коротко говоря - много раз писалось, что не надо в dll выносить визуальные элементы на дельфи (имеется ввиду использование VCL). Максимум - внутри dll создавать целиком форму. Это максимум что достаточно легко и надежно можно сделать. А перемешивать кнопки, созданные в dll с формой, созданной в exe (или другой dll) - нереально. (Не, ну может и возможно, но это какой-то совершенно бессмысленный геморой получится.)
Для этого придуманы bpl.
Если они почему-то не устраивают (например, предполагается смешивать языки программирования для разных модулей) - то надо строить логику взаимодействия так, чтобы вся визуальная часть и конструирование визуальных элементов было либо где-то в одном месте (и лучше в exe), либо в отдельных модулях программы создавать целиком формы (например, диалоги настроек). Все. Более смешиватьне надо, это бессмысленно сложно.
← →
Anatoly Podgoretsky © (2009-01-31 10:23) [20]> Германн (31.01.2009 0:52:08) [8]
Любитель извращенец.
← →
CodeMaster © (2009-01-31 10:36) [21]Всё понятно, можно закрывать тему.
← →
CodeMaster © (2009-01-31 11:16) [22]решил проблему вот так:
> library POGi_SkinEngine;
>
>
> uses
> islib,SysUtils,
>
> Classes,
> IniFiles,
> Windows;
>
>
> {$R *.res}
> const
> MesInfo = 3231;
> type
> TPOGiButtonIni = record
> Image: String;
> X,Y: Integer;
> Name: String;
> Parent: String;
> FrameCount: Integer;
>
> end;
> type
> PPOGi_EngineLib = ^TPOGi_EngineLib;
> TPOGi_EngineLib = record
> POGi_GetData: function: TPOGiButtonIni; stdcall;
> POGi_EngineInit: function(ConfFileName: String): Boolean;
> stdcall;
>
> end;
> TEngineProc = function: PPOGi_EngineLib; stdcall;
> var
> POGiInfButton: TPOGiButtonIni;
> POGi_EngineProc: TPOGi_EngineLib;
>
> function POGi_GetData: TPOGiButtonIni; stdcall;
> begin
> Result:= POGiInfButton;
> end;
> function POGi_EngineInit(ConfFileName: String): Boolean;
> stdcall;
> var
> hRet: Boolean;
> Ini: TIniFile;
> i: Integer;
> Count: Integer;
>
> Temp,Temp1: String;
> begin
> Count:= 0;
> Result:= False;
>
> if not FileExists(ConfFileName) then Exit;
>
> Ini:= TIniFile.Create(ConfFileName);
> try
> Count:= Ini.ReadInteger("Main","POGiButtons",Count);
>
> if Count < 1 then Exit;
> for i:= 1 to Count do begin
> Temp:= Ini.ReadString("Main","POGiButton" + IntToStr(i),
> Temp);
>
>
>
>
> ZeroMemory(@POGiInfButton,SizeOf(POGiInfButton));
>
>
>
> POGiInfButton.X:= Ini.ReadInteger(Temp,"X",POGiInfButton.
> X);
> POGiInfButton.Y:= Ini.ReadInteger(Temp,"Y",POGiInfButton.
> Y);
> POGiInfButton.Name:= Ini.ReadString(Temp,"Name",Temp1);
>
> POGiInfButton.Image:= Ini.ReadString(Temp,"Image",Temp1);
>
> POGiInfButton.FrameCount:= Ini.ReadInteger(Temp,"FrameCount",
> POGiInfButton.FrameCount);
> POGiInfButton.Parent:= Ini.ReadString(Temp,"Parent",
> Temp1);
>
>
>
>
> if not FileExists(POGiInfButton.Image) then Exit;
> SendMessage(FindWindow(PChar("T" + POGiInfButton.Parent),
> nil),MesInfo,0,0);
>
> end;
>
>
> finally
> Ini.Free;
> end;
> Result:= True;
> end;
> function POGi_EProc: PPOGi_EngineLib; stdcall;
> begin
> Result := @POGi_EngineProc;
> end;
>
> exports POGi_EProc;
>
> begin
> POGi_EngineProc.POGi_GetData:= @POGi_GetData;
> POGi_EngineProc.POGi_EngineInit:= @POGi_EngineInit;
> end.
Окну отправляется сообщение. Если это то окно которое нам нужно, этим окном импортируются данные о кнопке из DLL.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.051 c