?
Nicht dass ich lästern wollte, aber das
#define IDXFROMCOL(colidx) (((DWORD) (colidx & 0x00FFFFFF)))
ist glatt gelogen, denn es extrahiert die Farbe, nicht den Index. Es sei denn, man versteht den Makronamen andersherum, als "Index entfernen und Farbe zurückgeben" statt "Index aus kombiniertem Wert extrahieren". Dann sollte man diese merkwürdige Denkweise allerdings als Kommentar dazuschreiben ...
#define COLANDIDX((idx),(col)) ((DWORD)col | ((DWORD)((BYTE)idx) << 24))
In einem 32bit System mag die Originalversion funktionieren, aber in einem 16bit System ist ein int auch nur 16bit breit und nach 24bit Schieben bleibt nichts mehr davon übrig. Also sollte man sicherheitshalber vor dem Schieben aus dem int auch ein DWORD machen. Und weil sowieso nur 8bit davon übrigbleiben, sollte man den Wert vorher auch auf 8bit ausgebremst haben.
Bei Macro-Parametern sollte man sich übrigens zur Angewohnheit machen, alle Parameter grundsätzlich einzeln zu klammern. In diesem Fall ist's wurscht, aber bei berechneten Parametern, die im Macro wohlmöglich mehrfach verwendet werden, geht's sonst garantiert in die Hose. Wenn man immer klammert, kann man's nicht vergessen.
#define IDXFROMCOL(colidx) (int)((colidx >> 24) & 0x000000FFUL)
#define COLFROMIDX(colidx) (colidx & 00FFFFFFUL)
Wenn der Index schon als int reingesteckt wird, sollte er auch als int wieder rauskommen, um nicht unnötige Compiler-Warnungen zu provozieren. colidx auf DWORD zu casten, kann man sich dagegen getrost sparen. Wenn hier kein DWORD oder long reingesteckt wird, funktioniert sowieso nichts. Mit der Markierung der Bitmaske als unsigned long (nichts Anderes als DWORD) erspart man sich ggf. eine weitere Compiler-Warnung wegen signed/unsigned mismatch. OK, warning level 4 mag nicht jeder, aber auch der hat seine Existenzberechtigung. Schützt den Codierer vor der eigenen Schlamperei ...