now(CDColor)!!

/* Set up the CHOOSECOLOR and custom colors structures. */
Private init(self | val)
{ ccStruct := build(CStruct, #CHOOSECOLOR);
  ccStruct[#lStructSize] := size(ccStruct);
  custColorStruct := new(Struct, 64); /* 16 32-bit values */
  cdFlags := 0x1;                     /* CC_RGBINIT */
  do(over(0, 16),                     /* Initialize the custom colors */
  {using(count)
  val := count*16;
  putLong(custColorStruct, asRGB(val, val, val), count*4);
  });
}!!

/* Return the custColorStruct as an OrderedCollection of COLORREF's. */
Def custColorStruct(self | col)
{ col := new(OrderedCollection, 16);
  do(over(0, 16),
  {using(count)
  add(col, asLong(longAt(custColorStruct, count*4)));
  });
  ^col;
}

now(Int)!!

/* Duplicate the RGB macro by providing an Int method which can turn
  the Red ColorRef value (receiver) and the Green and Blue values
  (args) into a Long. */
Def asRGB(self, green, blue)
{ ^asLong(self) + (green * 0x100) + (blue * 0x10000L);
}!!

now(Long)!!

/* Mask off the current blue value and 'or' the new value in. */
Def putBlue(self, blueVal | newCR)
{ newCR := (self bitAnd 0xFF00FFFFL) bitOr (blueVal * 0x10000L);
  swap(self, newCR);
}!!

/* Mask off the current green value and 'or' the new value in. */
Def putGreen(self, greenVal | newCR)
{ newCR := (self bitAnd 0xFFFF00FFL) bitOr (greenVal * 0x100L);
  swap(self, newCR);
}!!

/* Mask off the current red value and 'or' the new value in. */
Def putRed(self, redVal | newCR)
{ newCR := (self bitAnd 0xFFFFFF00L) bitOr asLong(redVal);
  swap(self, newCR);
}!!

/* Mask for the requested color and return an Int. */
Def blue(self)
{ ^asInt((self bitAnd 0x00FF0000L) / 0x10000L);
}!!

/* Mask for the requested color and return an Int. */
Def green(self)
{ ^asInt((self bitAnd 0x0000FF00L) / 0x100L);
}!!

/* Mask for the requested color and return an Int. */
Def red(self)
{ ^asInt(self bitAnd 0x000000FFL);
}!!



