Announcement

Collapse
No announcement yet.

Von D4 nach D5 TOwnerDrawState

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Von D4 nach D5 TOwnerDrawState

    Hallo wer kann mir sagen für was folgender Aufruf steht?

    <p>
    <b>TOwnerDrawState(WordRec(LongRec(itemState).Lo). Lo);</b>
    </p>

    In D5 ist der Type folgendermaßen deklariert, in D4 war das wohl etwas anders:

    <pre>
    TOwnerDrawState = set of (odSelected, odGrayed, odDisabled, odChecked,
    odFocused, odDefault, odHotLight, odInactive, odNoAccel, odNoFocusRect,
    odReserved1, odReserved2, odComboBoxEdit);
    </pre>
    Gruß Andreas

  • #2
    Also

    <pre>

    ItemState = type LongInt;<br>

    type
    LongRec = packed record
    Lo,Hi: Word;
    end;<br>

    WordRec = packed record
    Lo,Hi: Byte;
    end;<br>

    LongWordRec = packed record
    Lo,Hi: WordRec;
    end; <br>

    var
    ItemState: Integer; // 32 Bit = 2 * 1 Word = 4 * 1 Byte<br>
    LoLoByte: Byte;
    begin
    LoLoByte := WordRec(LongRec(ItemState).Lo).Lo;
    LoLoByte := LongWordRec(ItemState).Lo.Lo;
    LoLoByte := Byte(ItemState);
    LoLoByte := ItemState and $FF;
    end;<br>

    </pre>

    Man versucht also das niederwertigste Byte des 4 Bytes Integer in ItemState zu extrahieren da TOwnerDrawState() ein Set mit max. 8 Elementen ist. Wie Du aber oben siehst ist TOwnerDrawState aber erweitert wurden und somit reichen 8 Bits eines Bytes nicht mehr aus. Der Compiler codiert nun dieses Set in einem Word = 16 Bit also 2 Bytes. Somit müsste der 3 fache TypCast umgecodet werden in

    <pre>

    var
    State: TOwnerDrawState;
    begin
    State := TOwnerDrawState(LongRec(ItemState).Lo);
    State := TOwnerDrawState(Word(ItemState));
    end;

    </pre>

    Allerdings ist dies eine wohl schlechtere Programmierpraxis, gerade weil sich die Typdeklaration von TOwnerDrawState in neueren Delphi Versionen ändern kann und somit ein solcher TypCast unsicher wird.<br>
    Eine andere Alternative die ich immer nutze sieht so aus:

    <pre>

    var
    State: TOwnerDrawState;
    begin
    Word(State) := ItemState;
    end;<br>

    // oder !<br>

    procedure myDraw(ItemState: Word);
    var
    State: TOwnerDrawState absolute ItemState;
    begin<br>

    end;

    </pre>

    Man castet also die Linke Seite. Wird die Typdeklaration von TownerDrawState verändert wird der Compiler bei Word(State), bzw. dem var ... absolute... einen Fehler melden "Invalid Typcast" und schon weis man wonach man suchen muss.<br>
    Zudem ist der TypCast über WordRec(Longrec()) sehr unelegant da es Byte(ItemState) oder eben Word(ItemState) auch tut.<br>
    Normalerweise wird LongRec/WordRec für das casten von recordbasierten Strukturen benutzt um die Problematik Little Endianess->Big Endianess zu erschlagen. Ansonsten benutzt man Directcasts per Byte(),Word() oder "Boolsche" Operatoren wie ItemState and $FF oder (ItemState shr 16) and $FF usw.<br>

    Gruß Hage

    Comment


    • #3
      Frohes neues Jahr Hagen und Danke für deine ausführliche Antwort.
      <p>
      Die Komponente, die ich nach D5 umzusetzen versuche, hat leider noch mehr solcher Code Fragmente und will nicht so recht laufen. Zumindest konnte ich, dank deiner Hilfe, dieses eine Problem lösen. Es handelt sich dabei um einen visuellen Query-Builder der u.a. bei IBExpert Verwendung findet. </p>
      <a href=“http://www.geocities.com/SiliconValley/Way/9006/qbuilder.html“> http://www.geocities.com/SiliconValley/Way/9006/qbuilder.html</a>
      <p>Gruß Andreas</p&gt

      Comment

      Working...
      X