Форум: "Прочее";
Текущий архив: 2007.08.05;
Скачать: [xml.tar.bz2];
ВнизString -> TControl Найти похожие ветки
← →
VirEx © (2007-07-02 17:35) [0]как реализовать такую штуку:
var
str:String;
begin
str:="TPanel";
AddControl(Form1,str);
end;
где procedure AddControl( Parent:TControl; ChildComponent:String );
← →
MBo © (2007-07-02 17:37) [1]RegisterClass + GetClass/FindClass
← →
VirEx © (2007-07-02 17:40) [2]о. щас попробую
← →
VirEx © (2007-07-02 19:25) [3]не канает. FindClass также как и FindGlobalComponent нифига не может найти екземпляр класса
← →
Юрий Зотов © (2007-07-02 19:33) [4]String в Delphi - не класс. Икать нечего.
← →
Юрий Зотов © (2007-07-02 19:34) [5]Искать.
:о)
← →
VirEx © (2007-07-02 19:39) [6]да я знаю, я имею ввиду что эти функции не могут найти ни TPersistentClass не TComponent с помощью которых я бы динамически создал любой объект с именем содержащимся в строке.
а как хотябы перечислить все возможные зарегестрированные классы?
← →
StriderMan © (2007-07-02 19:43) [7]
> FindClass также как и FindGlobalComponent нифига не может
> найти екземпляр класса
FindClass экземпляр не ищет
> RegisterClass
это сделал?
← →
AlexWlad © (2007-07-02 19:45) [8]Ну найдешь ты ВСЕ названия классов... А заполнять два мешка пропертей для каждого (то, что среда разработки делает) - Пушкин будет?
← →
VirEx © (2007-07-02 19:50) [9]
> [8] AlexWlad © (02.07.07 19:45)
> Ну найдешь ты ВСЕ названия классов... А заполнять два мешка
> пропертей для каждого (то, что среда разработки делает)
> - Пушкин будет?
да свойства то я заполню, мне бы главное сделать любой компонент
> RegisterClass
> > это сделал?
procedure RegisterClass(AClass: TPersistentClass);
так а откуда я возьму аргумент AClass? если у меня исходные данные только строка?
← →
Юрий Зотов © (2007-07-02 20:01) [10]> так а откуда я возьму аргумент
Регистируйте, например, в секции initialization того же модуля, где этот класс и определен.
← →
VirEx © (2007-07-02 20:24) [11]вы шутите наверно?)
мне надо сделать функцию которая будет возвращать по имени класса компонента объект.
например захотелось мне динамически загрузить из файла различные компоненты (которые перечисленны в виде текста, например: name="Panel1", classname="TPanel", caption="asdasd", ...) и код динамически создает объект с нужным классом.
ведь так не сделаешь, а очень хотелось бы:
var
o:TObject;
begin
o:=TObject.create;
o.ClassName:="TPanel";
TPanel(o).Caption:="asdasdasd";
← →
Yanis © (2007-07-02 20:39) [12]
> var
> o:TObject;
> begin
> o:=TObject.create;
> o.ClassName:="TPanel";
> TPanel(o).Caption:="asdasdasd";
жесть.
← →
VirEx © (2007-07-02 20:42) [13]
> [12] Yanis © (02.07.07 20:39)
>
> > var
> > o:TObject;
> > begin
> > o:=TObject.create;
> > o.ClassName:="TPanel";
> > TPanel(o).Caption:="asdasdasd";
>
> жесть.
> ведь так не сделаешь, а очень хотелось бы
← →
Yanis © (2007-07-02 20:44) [14]
> > ведь так не сделаешь, а очень хотелось бы
Читал :) Меня размах воображения поражает.
← →
Юрий Зотов © (2007-07-02 21:25) [15]> VirEx © (02.07.07 20:24) [11]
> вы шутите наверно?)
Нисколько. Регистрируйте класс - и все получится.
> ведь так не сделаешь
А что, по-Вашему, происходит при загрузке формы? Это самое и происходит.
← →
Loginov Dmitry © (2007-07-02 21:29) [16]
type
TControlClass = class of TControl;
var
C: TControlClass;
begin
C := FindClass("TButton"); {Или свой вариант}
with C.Create(Self) do
begin
Caption := "blablabla";
.............
end;
вот так вот это приблизительно делается
← →
VirEx © (2007-07-02 21:41) [17]
> [16] Loginov Dmitry © (02.07.07 21:29)
>
> type
> TControlClass = class of TControl;
> var
> C: TControlClass;
> begin
> C := FindClass("TButton"); {Или свой вариант}
> with C.Create(Self) do
> begin
> Caption := "blablabla";
> .............
> end;
>
>
> вот так вот это приблизительно делается
procedure TForm1.Button1Click(Sender: TObject);
type
TControlClass = class of TControl;
var
C: TControlClass;
begin
registerclass(TButton);
C := TControlClass(FindClass("TButton"));//просто приравнять невозможно изза разных типов
with C.Create(Self) do
begin
Caption := "blablabla";
left:=10;
top:=10;
visible:=true;
end;
end;
только после этого меняется заголовок окна)
← →
VirEx © (2007-07-02 21:42) [18]хотя если добавить еще parent:=form1 то появится кнопка, но заголовок окна по прежнему изменится)
← →
atruhin © (2007-07-02 21:47) [19]> хотя если добавить еще parent:=form1 то появится кнопка,
> но заголовок окна по прежнему изменится)
А дальше читай о RTTI статей и примеров в сети море.
← →
VirEx © (2007-07-02 21:50) [20]вся проблема в том что эта функция в отдельном модуле
но в ней я указываю главный компонент RootControl из которого зарегестрированные классы перерегистрирую в этом модуле
← →
atruhin © (2007-07-02 22:09) [21]> вся проблема в том что эта функция в отдельном модуле
> но в ней я указываю главный компонент RootControl из которого
> зарегестрированные классы перерегистрирую в этом модуле
Ни чего не понял в этой фразе, но в каком модуле проводить регистрацию/создание -
значения не имеет.
← →
VirEx © (2007-07-02 22:19) [22]есс, я это сделал!
function LoadObject(Parent_:TWinControl; FileName, Section: string):TControl;
Parent_ - контрол на котором должен быть размещен загруженный контрол
FileName, Section - для указания настроек ini файла
позже выложу более красивый код, если кому надо конечно, или не надо?)
← →
Loginov Dmitry © (2007-07-02 22:21) [23]> только после этого меняется заголовок окна)
Ну не TControl укажи а че-нибудь другое. Или используй тулзы модуля TypInfo.
← →
VirEx © (2007-07-02 22:23) [24]
> [23] Loginov Dmitry © (02.07.07 22:21)
> > только после этого меняется заголовок окна)
>
>
> Ну не TControl укажи а че-нибудь другое. Или используй тулзы
> модуля TypInfo.
да не в том дело, просто заголовок менялся потомучто Caption было от формы
а в своем модуле для установки свойств конечно без тип инфо не обойтись)
← →
Loginov Dmitry © (2007-07-02 22:26) [25]> менялся потомучто Caption было от формы
Наверно попому, что у TControl такого св-ва нету
← →
Loginov Dmitry © (2007-07-02 22:28) [26]попому = потому ))
← →
VirEx © (2007-07-02 22:37) [27]..............
unit IniAPI;
interface
uses
Windows;
var
INIFileName:string;
SelectSection:string;
function WriteString(Ident, Value: string):boolean;
function ReadString(Ident:string): String;
function ReadInteger(Ident:string): Integer;
function ReadBoolean(Ident:string): Boolean;
implementation
uses SysUtils;
function ReadBoolean(Ident:string): Boolean;
begin
result:=false;
try
result:=Boolean(ReadInteger(Ident));
except
exit;
end;
end;
function ReadInteger(Ident:string): Integer;
begin
result:=0;
try
result:=StrToInt(ReadString(Ident));
except
exit;
end;
end;
function ReadString(Ident:string): String;
var
Buffer: array[0..2047] of Char;
res:string;
begin
SetString(res, Buffer, GetPrivateProfileString(PChar(SelectSection),
PChar(Ident), PChar(nil), Buffer, SizeOf(Buffer), PChar(INIFileName)));
result:=Buffer;
end;
function WriteString(Ident, Value: string):boolean;
begin
result:= WritePrivateProfileString(PChar(SelectSection), PChar(Ident),PChar(Value), PChar(INIFileName));
end;
end.
..............
function GetToken(aString, SepChar: String; TokenNum: integer):String;
{
параметры: aString : полная строка
SepChar : строка служащая разделителем между словами (подстроками)
TokenNum: номер требуемого слова (подстроки))
result : искомое слово или пустая строка, если количество слов меньше значения "TokenNum"
}
var
Token : String;
StrLen : integer;
TNum : integer;
TEnd : integer;
begin
StrLen := Length(aString);
TNum := 1;
TEnd := StrLen;
while ((TNum <= TokenNum) and (TEnd <> 0)) do
begin
TEnd := Pos(SepChar,aString);
if TEnd <> 0 then
begin
if TokenNum>1 then begin
Token := Copy(aString,Length(SepChar),TEnd-1);
Delete(aString,1,Length(SepChar)+TEnd-1);
Inc(TNum);
end else begin
Token := Copy(aString,1,TEnd-1);
Delete(aString,1,TEnd);
Inc(TNum);
end;
end
else
begin
Token := aString;
end;
end;
if TNum >= TokenNum then
begin
result := Token;
end
else
begin
result := "";
end;
end;
...........
uses
TypInfo;
..........
function LoadObject_(Parent_:TWinControl; FileName, Section: string):TControl;
procedure StrToFont(font:TFont;Value:String);
var
s:string;
begin
font.Name:=GetToken(Value,"|",1);
font.Size:=StrToInt(GetToken(Value,"|",2));
s:=GetToken(Value,"|",3);
font.Color:=StringToColor(GetToken(Value,"|",4));
if length(s) >2 then
SetOrdProp(font,"Style",StringToSet(GetPropInfo(font,"Style"),s));
end;
type
TControlClass = class of TControl;
var
i:integer;
ClassName,Name,Value:String;
Obj_: TControlClass;
tmpObj:TObject;
Obj: TControl;
propNames:TStrings;
pp : PPropList;
pt : PTypeData;
begin
IniAPI.INIFileName:=FileName;
IniAPI.SelectSection:=Section;
ClassName:=IniAPI.ReadString("ClassName");
Name:=IniAPI.ReadString("Name");
if (ClassName="") or (Name="") then exit;
Obj_:=TControlClass(GetClass(ClassName));
Obj:=Obj_.Create(nil);
Obj.Parent:=Parent_;
Obj.Visible:=true;
result:=Obj;
propNames:=TStringList.Create;
//получаем все возможные Public свойства
pt:=GetTypeData(Obj.ClassInfo);
GetMem (pp, pt^.PropCount*SizeOf(Pointer));
try
GetPropInfos(Obj.ClassInfo, pp);
for i :=0 to pt^.PropCount-1 do propNames.Add(pp^[i].Name);
finally
FreeMem(pp);
end;
for i:=0 to propNames.Count-1 do begin
Value:=IniAPI.ReadString(propNames[i]);
if Value<>"" then begin //если этого свойства нет в файле
//предохраняемся)
try
case typinfo.PropType(Obj, propNames[i]) of
tkString, tkLString: SetStrProp(Obj,propNames[i],Value);
tkInteger:
if GetPropInfo(Obj.ClassType, propNames[i])^.PropType^^.Name = "TColor"
then
SetOrdProp(Obj,propNames[i],StringToColor(Value))
else
SetOrdProp(Obj,propNames[i],StrToInt(Value));
tkClass: begin
tmpObj:=TPersistent(GetOrdProp(Obj, propNames[i]));
if tmpObj is TFont then StrToFont(TFont(tmpObj),Value)
else
if tmpObj is TStrings then begin
TStrings(tmpObj).Clear;
Value:=ReplaceSub(Value,"|",#13#10);
TStrings(tmpObj).Text:=Value;
end;
end;
tkEnumeration: SetEnumProp(Obj,propNames[i],Value);
end;
except end;
end;
end;
propNames.Free;
end;
← →
VirEx © (2007-07-02 22:39) [28]вот из такого примерно файла грузит контролы и устанавливает им свойства:
[Component0]
ClassName=TButton
Name=Button1
Caption=Button1
Top=168
Left=48
Font=MS Sans Serif|8||clWindowText
Width=75
Height=25
[Component1]
ClassName=TRadioButton
Name=RadioButton1
Caption=RadioButton1
Color=clBtnFace
Top=104
Left=72
Font=MS Sans Serif|8||clWindowText
Width=113
Height=17
[Component2]
ClassName=TCheckBox
Name=CheckBox1
Caption=CheckBox1
Color=clBtnFace
Top=80
Left=64
Font=MS Sans Serif|8||clWindowText
Width=97
Height=17
[Component3]
ClassName=TPanel
Name=Panel1
Caption=Panel1
Color=clBtnFace
Top=224
Left=64
Font=MS Sans Serif|8||clWindowText
Width=185
Height=41
например загрузить радиобокс можно так:
LoadObject_(Form1, "c:\1.ini" , "Component1" )
← →
VirEx © (2007-07-02 22:41) [29]но! в каком либо модуле в проекте необходимо зарегить контролы:
procedure TfrmMain.FormCreate(Sender: TObject);
begin
registerclass(TButton);
registerclass(TRadioButton);
registerclass(TCheckBox);
registerclass(TPanel);
.......
← →
Loginov Dmitry © (2007-07-02 22:44) [30]Какая разница? Главное, до выполнения основного кода
← →
Loginov Dmitry © (2007-07-02 22:45) [31]сорри, посчитал утверждение за вопрос
← →
VirEx © (2007-07-02 22:45) [32]ну ясный перец)
оффтоп.
всё, на сегодня всё. я бы сегодня не справился если бы не треки UT2004.
спать.
← →
Игорь Шевченко © (2007-07-03 10:40) [33]VirEx © (02.07.07 22:37) [27]
И нафига, спрашивается, в Борланде classes.pas писали, если индейцы их не читают ?
← →
Inco (2007-07-03 12:21) [34]А если проще поступить:
function AddObj(ACompName: string): Object
begin
if ACompName = "TPanel" then Result := TPanel.Create()
else ACompName = "TButton" then Result := TButton.Create()
else ACompName = "TMemo" then Result := TMemo.Create()
...
end;
← →
Skier © (2007-07-03 13:16) [35]есть же классы TReader и TWriter. Зачем велосипед изобретать?
← →
Loginov Dmitry © (2007-07-03 13:17) [36]Чем же это проще? Классов много, соответственно условий таких может быть уйма. А использование RTTI дает очень компактный код.
← →
VirEx © (2007-07-03 18:34) [37]
> [34] Inco (03.07.07 12:21)
сУщий, шУтишь да?
> [35] Skier © (03.07.07 13:16)
> есть же классы TReader и TWriter. Зачем велосипед изобретать?
тогда покажи мне велосипед, с помощью которого можно загрузить ini файл динамически создавая любые объекты и забивая их свойствами из этого же файла. (WriteComponent мне не подходит)
> [33] Игорь Шевченко © (03.07.07 10:40)
> VirEx © (02.07.07 22:37) [27]
>
> И нафига, спрашивается, в Борланде classes.pas писали, если
> индейцы их не читают ?
цель была: загрузить из ini файла объект, с определенными свойствами, любой объект
теперь вопрос: а вы о чем собственно?
← →
VirEx © (2007-07-03 19:42) [38]
> [37] VirEx © (03.07.07 18:34)
WriteComponent/ReadComponent
← →
Игорь Шевченко © (2007-07-04 09:45) [39]VirEx © (03.07.07 18:34) [37]
> цель была: загрузить из ini файла объект, с определенными
> свойствами, любой объект
> теперь вопрос: а вы о чем собственно?
Я о том, что велосипед с квадратными колесами не поедет.
← →
Kolan © (2007-07-04 09:50) [40]> а вы о чем собственно?
Думаю о сериализации:
http://rsdn.ru/article/delphi/serialization.xml
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2007.08.05;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.057 c