Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Доступ к вложенным полям Record через RTTI

Подскажите как можно получить доступ (записать) в вложенное значение перечисления (Record) с использованием RTTI?
если смотреть ниже приведённый пример то надо записать в переменную "X" поля с указанным именем.
PrintConf.[имя поля].x
Uses system.Rtti;
.......
type rPole=record
  str:WideString;
  x:integer;
  y:integer;
  h:integer;
  leng:integer;
end;
type
RPrintPosition =record
  p1,s1,modelname:rPole;
end;
....
var PrintConf:PrintPosition;
....
Procedure SetPrintConf(FieldName:String;x,y,h:Integer;);
var rttiContext: TRttiContext;
begin
try
 rttiContext:=TRttiContext.Create;
 rttiContext.GetType(TypeInfo(RPrintPositionConf)).GetField('FieldName');
finally
 rttiContext.Free;
end;
end;
....
....

rttiContext.GetType(TypeInfo(RPrintPositionConf)).GetField('FieldName')- вот это обращение к полю (переменная) еслибы она была простого типа к примеру string то всё ясно:
rttiContext.GetType(TypeInfo(RPrintPositionConf)).GetField('FieldName').SetValue(@PrintConf,'тест'),
но вот с перечислением не могу въехать как обратиться к вложеному? подскажите если кто знает
Ответ: И опять у меня невпопад, ага, вот:
+
procedure SetPrintConf(const FieldName:string;const X,Y,H:Integer);
var
Rtti   : TRttiContext;
T1, T2 : TRttiType;
F1, F2 : TArray<TRttiField>;
i,  j  : Integer;
V      : TValue;
begin
Rtti := TRttiContext.Create;
with Rtti do
try
  T1 := Rtti.GetType(TypeInfo(RPrintPosition));
  F1 := T1.GetFields;
  for I := 0 to High(F1) do
    if (F1[I].FieldType is TRttiRecordType) and (F1[I].Name = FieldName) then
    begin
      T2 := Rtti.GetType(F1[I].FieldType.Handle);
      if T2.IsRecord then
      begin
        F2 := T2.GetFields;
        for J := 0 to High(F2) do
        begin
          if F2[J].Name = 'x' then
            V := X else
          if F2[J].Name = 'y' then
            V := Y else
          if F2[J].Name = 'h' then
            V := H else
            Continue;
          if (PTypeInfo(F2[J].FieldType.Handle)^.Kind = tkInteger) and             //integer
             (PTypeInfo(F2[J].FieldType.Handle)^.TypeData^.OrdType = otSLong) then //signed
          begin
            F2[J].SetValue(Pointer( NativeUInt(@PrintConf)+F1[I].Offset ), V);
          end;
        end;
      end;
    end;
finally
  Free;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
SetPrintConf('s1',123,456,789);
SetPrintConf('p1',-123,-456,-789);
SetPrintConf('modelname',999,888,777);
ShowMessage(Format('p1: %d %d %d',[PrintConf.p1.x,PrintConf.p1.y,PrintConf.p1.h])+#13#10+
            Format('s1: %d %d %d',[PrintConf.s1.x,PrintConf.s1.y,PrintConf.s1.h])+#13#10+
            Format('modelname: %d %d %d',[PrintConf.modelname.x,PrintConf.modelname.y,PrintConf.modelname.h]));
end;
Вопрос: Получить поля класса через RTTI

Доброго времени суток.
Пытаюсь получить поля класса средствами RTTI. Поля получает без проблем, но .... все (по всей иерархии класса). Как получить только поля самого верхнего уровня класса, без полей родительских классов? Спасибо.
Ответ: Что-то пропустил TRTTIField.Parent. Все оказывается просто.
P.S. Пообщаешься с умными людьми и сразу умные мысли приходят.
Спасибо.
Вопрос: Закрыть доступ к php файлу через адресную строку, но так, чтобы он инклудился другим скриптом и работал

Здравствуйте,подскажите можно ли закрыть доступ к php файлу через адресную строку,но так что бы он инклудирвался другим скриптом и работал.
Ответ:
Сообщение от Александр8867
Здравствуйте,подскажите можно ли закрыть доступ к php файлу через адресную строку,но так что бы он инклудирвался другим скриптом и работал.
.htaccess (положить в ту же папку, где и скрипт):
Код Code
1
2
3
4
<Files myscript.php>
order deny,allow
deny from all
</Files>
Вопрос: Как через RTTI получить тип массива в record

В общем задача такая хочу получить все имена и типы элементов record-а
пишу такой код:

+

type
 TMyRecord = packed record
     byteArr     : array[0..99] of byte;
     MyInteger  : integer;
     MyDouble  : Double;
     MyColour   : array of TColor;
 end;

procedure TForm1.Button1Click(Sender: TObject);
var
  rttiContext : TRttiContext;
  fld         : TRttiField;
begin

  for fld in rttiContext.GetType(TypeInfo(TMyRecord)).GetFields do
   begin
     Memo1.Lines.Add('Name: ' + fld.Name +' Type: ' + fld.FieldType.ToString);
   end;

end;



Получаю AV. На простых типах не массивах все работает
пробовал еще так:

+

 if (fld.FieldType is TRttiArrayType) or (fld.FieldType is TRttiDynamicArrayType) then
    Memo1.Lines.Add('Name: ' + TRttiArrayType(fld).Name + ' Type: ' + TRttiArrayType(fld).ElementType.Name);


Тоже получаю AV. Может кто сталкивался как можно это решить.
Ответ: Сдаётся мне без определения типов никакой RTTI и не генерится для полей. RTTI вообще в сторону классов направлено, её наличие у record'ов на мой взгляд излишне.
Вопрос: Как получить значение свойства типа record, в RTTI

Копаюсь с классом основы которого вот тут

хочу добавить чтоб сохранять данные не только в тэгах, а и в атрибутах тоже.

Смотрю вот этот фрагмент
  procedure WriteProperty(PropInfo: PPropInfo); 
  var 
    sValue: string; 
    LObject: TObject; 
    TempNode: IXMLNode; 
  begin 
    case PropInfo^.PropType^.Kind of 
      tkEnumeration: 
        if GetTypeData(PropInfo^.PropType^)^.BaseType^ = TypeInfo(Boolean) 
          then sValue := BoolToStr(Boolean(GetOrdProp(oObject, PropInfo)), true) 
          else sValue := IntToStr(GetOrdProp(oObject, PropInfo)); 
      tkInteger, tkChar, tkWChar, tkSet: 
        sValue := IntToStr(GetOrdProp(oObject, PropInfo)); 
      tkFloat: 
        sValue := FloatToStr(GetFloatProp(oObject, PropInfo)); 
      tkString, tkLString, tkWString: 
 
        sValue := GetWideStrProp(oObject, PropInfo); 
      tkClass: 
        if Assigned(PropInfo^.GetProc) and Assigned(PropInfo^.SetProc) then 
        begin 
          LObject := GetObjectProp(oObject, PropInfo); 
          if LObject <> nil then 
          begin 
            TempNode := Node.AddChild(PropInfo^.Name); 
 
            SaveClass(LObject, TempNode); 
          end; 
        end; 
    end; 
 
    // тут мы создаем новую ветку в корне документа 
    // и записываем в него значение свойства 
    if PropInfo^.PropType^.Kind <> tkClass then 
      with Node.AddChild(PropInfo^.Name) do 
        Text := sValue; 
  end; 


тут обрабатываются
tkInteger, tkChar, tkWChar, tkSet, tkEnumeration, tkFloat , tkString, tkLString, tkWString, tkClass

Хочу добавить обработку типа tkRecord
как при этом получить значение каждого поля в этом типе, чет никак не получается....
Подскажите.
Ответ: Не понятно, зачем переделывать уже работающий "Точечный" метод сериализации принятый в Delphi на новый формат XML

Чем 1 лучше чем 2
<Main>
	<HistoryDepth>40</HistoryDepth> 
</Main>
<LookAndFeel>
	<WindowWidth>200</WindowWidth> 
	<AlwaysOnTop>True</AlwaysOnTop> 
	<AlphaBlending>False</AlphaBlending> 
	<AlphaBlendValue>245</AlphaBlendValue> 
	<AnimateWithAlpha>False</AnimateWithAlpha>


Main.HistoryDepth=40
LookAndFeel.WindowWidth=200
LookAndFeel.AlwaysOnTop=True
LookAndFeel.AlphaBlending=False
LookAndFeel.AlphaBlendValue=245
LookAndFeel.AnimateWithAlpha=False
Вопрос: Гражданин 1 марта открыл счет в банке, вложив 1000 руб. Через каждый месяц размер вклада увеличивается на 2% о

Гражданин 1 марта открыл счет в банке, вложив 1000 руб. Через каждый месяц размер вклада увеличивается на 2% от имеющейся суммы. Определить через сколько месяцев размер вклада превысит 1200 руб.
Ответ:
Delphi
1
2
3
4
5
6
7
8
9
10
11
var a:real;
    m:integer;
begin
  m := 0;
  a := 1000;
  while a <= 1200 do begin
    a := a*1.02;
    inc(m);
  end;
  ShowMessage('Через ' + IntToStr(m) + ' месяцев');
end;
Вопрос: Дружественный метод. Ошибка доступа к полям

Доброго времени суток, реализовываю паттерн состояние. Для доступа к полям класса контекста( в моем случае Foo) я реализую дружественный методы ( их штуки 5, я привел 2, как пример).
Есть класс
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Foo{
/*
 Тут методы какие- то
*/
 
protected:
    friend void AbstractState::setLocId( const Foo&, const unsigned long int );
    friend unsigned long int AbstractState::getLocId( const Foo& );
protected:
    unsigned long int iLocId_;
 
};
 
/* Интерфейс абстрактного состояния*/
class AbstractState{
 
protected:
        void setLocId( const Foo& M, const unsigned long int iNewLoc ) { M.iLocId_ = iNewLoc; }
    unsigned long int getLocId( const Foo& M ) { return M.iLocId_; }
};



Я хочу в потомках AbstractState унаследовать данные члены-функции класса и использовать. Сам же класс - абстрактный.
Вопрос вот в чем. При компиляции, да и при вводе кода среда разработки выдает, что iLocId_ - недоступен, мол он инкапсулирован и т.п.
C++
1
2
M.iLocId_ = iNewLoc;  /// Вот тут ругается!!! 
 return M.iLocId_;     /// Вот тут ругается!!!
Почему? ведь дружественный метод должен иметь доступ к полям класса Foo.

Второй вопрос. Наследуется ли дружественный метод. Могут ли потомки класса AbstractState его унаследовать?
Ответ:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//g++  5.4.0
 
#include <iostream>
 
//foo.h
class AbstractState;
 
class Foo{
/*
 Тут методы какие- то
*/
 
    friend class AbstractState;
protected:
    unsigned long int iLocId_;
 
};
 
//abstractstate.h
/* Интерфейс абстрактного состояния*/
class AbstractState{
 
public:
    void setLocId( Foo& M, const unsigned long int iNewLoc ) { M.iLocId_ = iNewLoc; }
    unsigned long int getLocId( Foo& M ) { return M.iLocId_; }
};
 
int main()
{
    Foo f;
    AbstractState s;
    s.setLocId(f, 1);
    std::cout << "Hello, world!\n";
}
Вопрос: Класс - друг. Доступ к полям и методам

Есть два класса: MainWindow и LBM_computation, в одном из них происходят вычисления. Класс MainWindow - для визуализации. Надо сделать так, чтобы все переменные и методы класса LBM_computation были доступны в классе MainWindow.

Я делаю так:

C++ (QT)
1
2
3
4
5
6
7
8
9
10
11
class LBM_computation
{
public:
    LBM_computation();
 
friend class MainWindow;
    double rho;                   // fluid density
    double u0[2];                 // initial fluid velocity
    double uf[2];                 // final fluid velocity
    double tau;                   // relaxation time
//и т.д.
C++ (QT)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
 
public:
    friend class LBM_computation;
private:
    Ui::MainWindow *ui;
    QPushButton *calculate;
    QLabel *hello;
    QLabel *velocity_X_in_the_begining;
// и т.д.
Затем мне надо в переменную u0[1] передать то, что пользователь введет в окошке программы, я делаю это в классе MainWindow так:

C++ (QT)
1
2
3
4
5
6
void MainWindow::set_Data_to_compute()
{
//передаю данные в класс lbm_computation, они там считаются
     u0[1]= velocity_X_in_the_begining_->text().toDouble();
    
}
Говорит, что u0[1] не задекларирован..

Доступ надо получать не через объект, а именно так.

Как быть?
Ответ:
Сообщение от Blitzor DDD
а так не получится?
Получится. Но это же от тебя зависит. Если тебя устроит, что объект класса вычислений будет создаваться и уничтожаться от вызова к вызову.
Вопрос: Как заполнить поля бд через блокнот?

Такой вопрос: есть бд,но надо заполнить поля таблицы через блокнот. Как это сделать?
Ответ: Если разово выгрузить можно с помощью exportizer проги
Если тупо считать и записать то записываем в поток loadfromfile ("...") а из потока в значение. Нэ?
Вопрос: Как записывать в файл несколько полей RichEdit через SaveToFile? заранее спасибо

Как записывать в файл текст из нескольких полей RichEdit через SaveToFile? заранее спасибо
Ответ: Для примера вот код

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <vcl.h>
#include <memory>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(!RichEdit1->Text.IsEmpty())
{
 std::auto_ptr<TStringList>L(new TStringList);
 L->Clear();
 switch(StrToInt(RichEdit1->Text))
 {
     case 0:
     L->Add("0");
     break;
     case 1:
     L->Add("1");
     break;
 }
 FILE *logFile =  fopen("C:\\log.txt", "a+");
 fprintf(logFile,AnsiString(L->Text).c_str());
 fclose(logFile);
 RichEdit1->Clear();
}
 RichEdit1->SetFocus();
 
}
//---------------------------------------------------------------------------
По вводи 0 и 1 и файл будет дописываться