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

Вниз

Как получить ВСЕ Caption ы контролов на форме?   Найти похожие ветки 

 
BlackTiger   (2002-12-10 20:41) [0]

Как получить ВСЕ Caption"ы контролов на форме?

Мне необходимо сохранить их в файле в виде
<имя контрола>=<его caption>

А потом загрузить все обратно.

Типа многоязычность получается.


 
asmith   (2002-12-10 21:06) [1]

for nIndex := 0 to myForm.ControlCount - 1 do
SaveToFile(myForm.Controls[nIndex].Caption);


 
Юрий Зотов   (2002-12-10 22:49) [2]

> asmith (10.12.02 21:06)

Сами пробовали?

1. Свойство TControl.Caption - protected. Поэтому код даже не скомпилируется.
2. Контрол может лежать не на форме, а, например, на панели. Тогда в список myForm.Controls он не попадает.

Тут надо немного иначе.

type
TFriendControl = class(TControl);
...
for i := 0 to ComponentCount - 1 do
if Components[i] is TControl then
with TFriendControl(Components[i]) do
if Caption <> "" then ...


 
Kibitzer   (2002-12-10 23:00) [3]


> Юрий Зотов © (10.12.02 22:49)


> Тут надо немного иначе.

Где:
TFriendControl = class(TControl)
public
property Caption;
end;

;)


 
MBo   (2002-12-10 23:05) [4]

>Kibitzer
Не нужно. protected члены класса, объявленного в том же модуле, доступны и так.


 
Kibitzer   (2002-12-10 23:23) [5]


> MBo © (10.12.02 23:05)
> >Kibitzer
> Не нужно. protected члены класса, объявленного в том же
> модуле, доступны и так.

И правда. :))
Не думал, что так тоже считается :-/


 
Юрий Зотов   (2002-12-10 23:38) [6]

> Kibitzer
:о)


 
BlackTiger   (2002-12-11 17:11) [7]

Спасибо, конечно, но наличие Caption у контрола совсем не обязательно, а использовать try - довольно убогое решение.
Я нашел код, который проверяет наличие какого либо свойства (проверял только для Caption) в библиотеке IniLang.
Если кому надо, то вот он

function HasProperty(comp:TComponent;prop:String):boolean;
begin
result:=(getPropInfo(comp.classInfo,prop)<>nil) and comp.name<>"");
end;

Используется так

if HasProperty(Button1, "Caption") then begin
// ...
end;

Правда для TNT-компонентов приходится извращаться и определять класс компонента более точно.

var
ws: WideString;
wsl: TWideStringList;
begin
wsl := TWideStringList.Create(nil);
//...
if HasProperty(Self.Controls[i], "Caption") then begin
if Self.FindComponent(Self.Controls[i].Name) is TTntButton then
begin
with TTntButton(Self.FindComponent(Self.Controls[i].Name)) do
begin
wsl.Add(Self.Controls[i].Name+"="+Caption);
end;
end;
end;
//...
wsl.SaveUnicode := true;
wsl.SaveToFile("Captions.txt")
wsl.Free;

"is TComponent" использовать нельзя, т.к. тогда Caption читается как string, а не как WideString, и все unicode летит нафиг.

Может можно по-оптимальней? А то необходимо описывать каждый класс контролов отдельно, а класса типа TTntControl я вроде не нашел.


 
Бурундук   (2002-12-11 18:24) [8]

>Self.FindComponent(Self.Controls[i].Name)
Ну ты и загнул... Я б так не смог.

По сути:
Используй RTTI

var CompCaption: string;

if Has...
CompCaption := GetPropValue(Controls[i], "Caption") // - получение заголовка в виде AnsiString не зависимо от типа.

Это сработает, даже если у какой-нибудь кнопки св-во Caption имеет тип Integer :)))


 
BlackTiger   (2002-12-11 18:51) [9]

То, что загнул - полностью огласен :-)

НО (!!!) прикол в том, что не могу достучаться до Caption у TMenuItem (TTntMenuItem). В списке Self.Controls[] они отсутствуют, при этом Self.ComponentCount указывает на количество компонент большее, чем можно адресовать в Self.Components[].

Ну и как получить/установить надписи на элементах меню по имени компонента?


 
Бурундук   (2002-12-11 19:03) [10]

Так ведь TMenuItem - потомок TComponent, а не TControl,
и естественно, что его в Controls[] нет.
Зато он есть в Components[].

>Self.ComponentCount указывает на количество компонент большее, >чем можно адресовать в Self.Components[].

А вот это я не врубился.

Если тебе нужны TMenuItemы - то надо организовать
проход по всем компонентам (а не контролам):

for i := 0 to ComponentCount - 1 do
if GetPropInfo(Components[i], "Caption") <> nil then
ЧегоТоТам.Add(GetPropValue(Components[i], "Caption"));

PS Зачем ты везде Self таскаешь?
Это имеет смысл, только если у тебя код внутри with находится
(и не просто with, а with чего-то с такими же свойствами)



 
Юрий Зотов   (2002-12-11 19:10) [11]

> наличие Caption у контрола совсем не обязательно

Неправда. Все контролы имеют свойство Caption, только не у всех оно опубликовано.


> Ну и как получить/установить надписи на элементах меню по
> имени компонента?

uses
TypInfo;
...
S := GetStrProp(Components[i], "Caption");
...
SetStrProp(Components[i], "Caption", "Закрыть");


 
BlackTiger   (2002-12-11 19:26) [12]

:-)))
Совсем торможу уже... Пора отдыхать, отдыхать, отдыхать...
Я просто пытался найти TMenuItem в Controls[], а не в Components[].
И используя ComponentCount рыться в Controls[].

2Юрий Зотов:
GetStrProp результат какого типа возвращает? String (PChar, ShortString)?
Если да, то он мне не поможет, тк TNT-компоненты имеют Caption типа WideString и все данные потеряются, а в этом-то и вся фишка.

З.Ы.: Мое личное АААААААААААфигенное спасибо разработчикам TNT-компонентов!!!


 
Бурундук   (2002-12-11 19:38) [13]

Привожу реализацию GetStrProp

function GetStrProp(Instance: TObject; PropInfo: PPropInfo): string;
begin
case PropInfo^.PropType^.Kind of
tkString: GetShortStrPropAsLongStr(Instance, PropInfo, Result);
tkLString: GetLongStrProp(Instance, PropInfo, Result);
tkWString: GetWideStrPropAsLongStr(Instance, PropInfo, Result);
// Автоматическое преобразование из WideString в AnsiString
else
Result := "";
end;
end;

Если же тебе надо получить именно WideString, то стандартных
доступов к WideString св-вам в RTTI я не вижу,
по крайней мере в D5.

Я полагаю, получить WideString через RTTI можно только
через функцию-Getter,
причём надо учитывать след. частные случаи:
1) старший байт адреса ф-и = $FE (если память мне не изменяет)- это не ф-я,
а смещение самого поля относительно начала объекта (-$FE, соотв)
2) -"- $FF: индекс виртуальной ф-и в VMT (тоже - $FF)
3) просто статический метод.


 
Бурундук   (2002-12-11 19:56) [14]

Только наоборот: $FE - вирт. ф-я, $FF - поле.
И это справедливо для D5, для D6 проверь сам.
(И посмотри в typinfo - может, в D6 уже есть более
удобный доступ к WideString св-вам).

И если у тебя только один компонент с таким Caption"ом
и больше не предвидится -
то, может, проще явно привести и не извращаться.


 
Бурундук   (2002-12-11 20:29) [15]

Ф-я доступа к WideString св-вам для D5:

type
PVMTAsArray = ^VMTAsArray;
VMTAsArray = array[0..$FFFF]of Pointer;

function GetWStrProp(Instance: TObject; const PropName: string): WideString;
var PGetCode: Pointer;
Getter: TWStrGet;
Field: Pointer;
HiByte: Byte;
begin
PGetCode := GetPropInfo(Instance, "W")^.GetProc;
HiByte := Cardinal(PGetCode) shr 24;

TMethod(Getter).Data := Instance;
if HiByte = $FF then
begin
Cardinal(Field) := Cardinal(PGetCode)and $FFFFFF + Cardinal(Instance);
Result := WideString(Field^);
end else
if HiByte = $FE then
begin
TMethod(Getter).Code :=
PVMTAsArray(Instance.ClassType)[(Cardinal(PGetCode) and $FFFFFF) div 4];
// не индекс, а смещение - я ошибся
Result := Getter();
end
else
begin
TMethod(Getter).Code := PGetCode;
Result := Getter();
end;
end;



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

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

Наверх





Память: 0.49 MB
Время: 0.008 c
3-74622
newe
2002-12-05 14:28
2002.12.23
Delphi + Access


6-74882
Rob
2002-10-28 10:23
2002.12.23
D7 и TClient&Server Socket


1-74810
denis24
2002-12-11 16:36
2002.12.23
Stringgrid


6-74877
Romych
2002-10-24 12:26
2002.12.23
Извините что вопрос немного не в тему UDP


3-74575
kiko
2002-12-04 16:05
2002.12.23
Помогите с запросом





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский