Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Umkehrfunktion von Ord(x)


Jakob Schöttl - Do 08.02.07 23:49
Titel: Umkehrfunktion von Ord(x)
Guten Abend,
wahrscheinlich ist es ganz einfach: Ich suche die "Umkehrfunktion" von Ord(x), aber nicht chr!

Ich nutze Ord, um einen Typ der ungefähr so deklariert ist als integer zu speichern: type TDockOrientation = (doScreen,doWorkArea,doDesktop);
Wenn ich den integer dann wieder aus der INI lade, muss ich natürlich einer Variable den entsprechenden Wert zuweisen:


Delphi-Quelltext
1:
2:
INI.WriteInteger('DockOptions','Orientation',ord(DockOptions.Orientation)); //speichern
DockOptions.Orientation := ord^-1(INI.ReadInteger('DockOptions','Orientation',ord(doWorkArea))); //laden


... weil sonst ja die Compiler-Fehlermeldung Inkompatible Typen 'TDockOrientation' und 'integer' kommt.


BenBE - Do 08.02.07 23:58

Kommt auf den Datentyp an ...

Für Char heißt die Funktion Chr.

Für die meisten anderen Datentypen musst Du explizit auf den Datentyp casten.


jaenicke - Fr 09.02.07 00:00


Delphi-Quelltext
1:
2:
INI.WriteInteger('DockOptions''Orientation', Ord(DockOptions.Orientation)); //speichern
DockOptions.Orientation := TDockOrientation(INI.ReadInteger('DockOptions''Orientation', Ord(doWorkArea))); //laden


Jakob Schöttl - Fr 09.02.07 00:08

user profile iconBenBE hat folgendes geschrieben:
Kommt auf den Datentyp an ...

Für Char heißt die Funktion Chr.

Für die meisten anderen Datentypen musst Du explizit auf den Datentyp casten.


ja, die hab ich ja oben schon erwähnt (nur falsch geschrieben) ;)



user profile iconjaenicke hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
INI.WriteInteger('DockOptions''Orientation', Ord(DockOptions.Orientation)); //speichern
DockOptions.Orientation := TDockOrientation(INI.ReadInteger('DockOptions''Orientation', Ord(doWorkArea))); //laden


das geht leider nicht! da kommt genau die gleiche fehlermeldung Inkompatible Typen 'TDockOrientation' und 'integer'


BenBE - Fr 09.02.07 00:15

Bei Set-Typen (oder Enums???) gab's beim direkten Casten meist Probleme ...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Procedure Solve;
var
    DO: TDockOrientation;
    DOSolve : Integer absolute DO;
Begin
    DOSolve := INI.ReadInteger({...});
    Form.DockOrientation := DO;
end;


Wobei die Größe des Typs TDockOrientation zu beachten ist. Für 2 Byte muss DOSolver Word und 1 Byte Byte respektive sein ...


Jakob Schöttl - Fr 09.02.07 08:05

user profile iconBenBE hat folgendes geschrieben:
Bei Set-Typen (oder Enums???) gab's beim direkten Casten meist Probleme ...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Procedure Solve;
var
    DO: TDockOrientation;
    DOSolve : Integer absolute DO;
Begin
    DOSolve := INI.ReadInteger({...});
    Form.DockOrientation := DO;
end;


Wobei die Größe des Typs TDockOrientation zu beachten ist. Für 2 Byte muss DOSolver Word und 1 Byte Byte respektive sein ...


Ahh! Ist doch nicht so leicht, wie ich erst dachte - und ich kann mich entsinnen, ich hab schon mal von absolute gelesen. Das ist ja echt praktisch!

absolute gefällt mir sehr :D

Und bei Settypen und Enums geht das beides dann eigentlich auf die gleiche Weise?

Aber bei Records kann ichs wohl leider nicht gleich einbauen

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
type
  TDockOptions = record
    CanDock: Boolean;
    DockingBand: integer;
    Orientation: TDockOrientation;
    iOrientation: Byte absolute Orientation;
  end;

da kommt leider ein Compiler-Fehler, dass er den Bezeichner 'absolute' nicht akzeptiert.


IngoD7 - Fr 09.02.07 09:37

Äähm ... Leute, mir ist kein Fall bewusst, wo ein solcher Typecast Schwierigkeiten macht (jedenfalls nicht unter D7). Und ich glaube nicht, dass dieses hier der erste Fall sein wird, den ich sehe. :wink:


user profile iconJakob Schöttl hat folgendes geschrieben:


user profile iconjaenicke hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
INI.WriteInteger('DockOptions''Orientation', Ord(DockOptions.Orientation)); //speichern
DockOptions.Orientation := TDockOrientation(INI.ReadInteger('DockOptions''Orientation', Ord(doWorkArea))); //laden


das geht leider nicht! da kommt genau die gleiche fehlermeldung Inkompatible Typen 'TDockOrientation' und 'integer'


Weil mit ziemlicher Sicherheit dein DockOptions.Orientation vom Typ Integer und nicht vom Typ TDockOrientation ist, stimmt's? 8)

Wenn DockOptions.Orientation vom Typ TDockOrientation ist, dann funktioniert das auch.


Jakob Schöttl - Fr 09.02.07 15:14

user profile iconIngoD7 hat folgendes geschrieben:
Weil mit ziemlicher Sicherheit dein DockOptions.Orientation vom Typ Integer und nicht vom Typ TDockOrientation ist, stimmt's? 8)

Wenn DockOptions.Orientation vom Typ TDockOrientation ist, dann funktioniert das auch.


Oje, du hast recht! DockOptions.Orientation ist zwar ein TDockOrientation, aber der Fehler kam, als ich den Ausdruck Combobox1.ItemIndex zugewiesen habe, also wirklich einem Integer.

Das habe ich wohl übersehen.

Danke trotzdem an user profile iconBenBE, die Möglichkeit finde ich wie gesagt super und universell...
Und danke dir user profile iconIngoD7!


BenBE - Fr 09.02.07 15:52

Ach ja und für sowas:
user profile iconJakob Schöttl hat folgendes geschrieben:
Aber bei Records kann ichs wohl leider nicht gleich einbauen

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
type
  TDockOptions = record
    CanDock: Boolean;
    DockingBand: integer;
    Orientation: TDockOrientation;
    iOrientation: Byte absolute Orientation;
  end;

da kommt leider ein Compiler-Fehler, dass er den Bezeichner 'absolute' nicht akzeptiert.


Gibt's variante Records:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
type
  TDockOptions = record
    CanDock: Boolean;
    DockingBand: integer;
    Orientation: record case Boolean of
      False: (TDO: TDockOrientation;);
      True: (B: Byte;);
    end;
  end;


Man kann das Case auch direkt schreiben, dann muss Orientation aber das letzte Feld sein. Verschachtelt man einen Record, kann man das auch in der Mitte machen ...


Jakob Schöttl - Fr 09.02.07 16:17

Variante Records verstehe ich leider immer noch fast nicht.
Wenn ich Orientation True setze, dann gibt es zusätzlich das Feld TDO, wenn Orientation False ist, dann gibt es statt TDO B?

Aber in meinem Fall hab ich nichts davon glaube ich, weil ich ja gern hätte, dass man das eine Feld zuweist, und das andere dadurch auch geändert wird - so wie bei absolut eben.


BenBE - Fr 09.02.07 16:51

Bei Varianten Records wird das mit dem True\False nur gemacht, damit Delphi mehrere eindeutige Teilbereiche kennt ...

Geht genauso auch mit Integern. Die Werte, die im Case vor dem Doppelpunkt stehen, sind dabei im Speicher nirgends vorhanden. Du kannst einfach auf TDO oder B zugreifen - nur Delphi brauch diese Unterscheidung.
Intern liegen TDO und B am gleichen Offset - so wie bei Absolute auch ... Siehe ggf. auf die Object Pascal Reference in der Delphi-Hilfe ... Dort steht das noch etwas genauer ...