= <його caption> А потім завантажити всі назад. Типу багатомовність" />

Як отримати все caption и контролів на формі

Як отримати ВСЕ Caption "и контролів на формі?

Мені необхідно зберегти їх у файлі у вигляді
<имя контрола>=<его caption>

А потім завантажити всі назад.

Типу багатомовність виходить.

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

> 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
Не потрібно. protected члени класу, оголошеного в тому ж модулі, доступні і так.

Спасибі, звичайно, але наявність 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 я начебто не знайшов.

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

По суті:
використовуй RTTI

var CompCaption: string;

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

Це спрацює, навіть якщо у якійсь кнопки св-во Caption має тип Integer :)))

Те, що загнув - повністю оголосив :-)

Ну і як отримати / встановити написи на елементах меню на ім'я компонента?

Так адже TMenuItem - нащадок TComponent, а не TControl,
і природно, що його в Controls [] немає.
Зате він є в 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 чогось з такими ж властивостями)

> Наявність Caption у контрола зовсім не обов'язково


> Ну і як отримати / встановити написи на елементах меню за
> Імені компонента?

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

-)))
Зовсім гальмую вже. Пора відпочивати, відпочивати, відпочивати.
Я просто намагався знайти TMenuItem в Controls [], а не в Components [].
І використовуючи ComponentCount ритися в Controls [].

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

З.И. Моя особиста АААААААААААфігенное спасибі розробникам TNT-компонентів.

Наводжу реалізацію 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.

Тільки навпаки: $ FE - вирт. ф-я, $ FF - поле.
І це справедливо для D5, для D6 перевір сам.
(І подивися в typinfo - може, в D6 вже є більш
зручний доступ до WideString св-вам).

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

Ф-я доступу до 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;

Пам'ять: 0.76 MB
Час: 0.04 c

Схожі статті