unit ICONS;
{************************  Interface    ***********************}
interface
uses WinTypes, WinProcs, WinDos, Strings, WObjects;
type
PIcon = ^TIcon;
TIcon = object(TRadioButton)
  HBmp :HBitmap;
  State:Integer;
  constructor  Init(AParent:PWindowsObject; AnID:Integer;ATitle:PChar;
     X,Y,W,H:Integer;AGroup:PGroupBox;BMP:PChar);
  destructor  Done;virtual;
  procedure  DrawItem(var Msg:TMessage);virtual;
end;

PIconGroup = ^TIconGroup;
TIconGroup = object(TGroupBox)
  OldIcon:PIcon;
  OldIconID:Integer;
  constructor Init(AParent:PWindowsObject;AnID:Integer;AText:PChar;
    X,Y,W,H:Integer);
  procedure SelectionChanged(NewIconID:Integer);virtual;
end;

{************************  Implementation      **********************}
implementation
const
  sr_Depressed = 1;
  sr_Raised   = 0;
{************************  DrawHiLites   ****************************}
function DrawHilites(PaintDC:hDC;X1,Y1,X2,Y2,LW,State:Integer):Boolean;
var
  LPts,RPts:Array[0..2] of TPoint;
  Pen1,Pen2,OldPen:HPen;
  Ofs,W,H:Integer;
  OldBrush:HBrush ;
begin
  Pen1 := CreatePen(ps_Solid,1,$00000000);  {Draw a surrounding blk frame}
  OldPen := SelectObject(PaintDC,Pen1);
  OldBrush := SelectObject(PaintDC,GetStockObject(null_Brush));
  Rectangle(PaintDC,X1,Y1,X2,Y2);
  SelectObject(PaintDC,OldPen);
  SelectObject(PaintDC,OldBrush);
  DeleteObject(Pen1);
  Ofs := Byte(State = sr_Depressed) * lw;
  
  LPts[0].x := X1+Ofs;   LPts[0].y := Y2-Ofs;
  LPts[1].x := X1+Ofs;   LPts[1].y := Y1+Ofs;
  LPts[2].x := X2-Ofs;   LPts[2].y := Y1+Ofs;
  RPts[0].x := X1+Ofs;   RPts[0].y := Y2-Ofs;
  RPts[1].x := X2-Ofs;   RPts[1].y := Y2-Ofs;
  RPts[2].x := X2-Ofs;   RPts[2].y := Y1+Ofs;
  if State = sr_Raised then
    begin
    Pen1 := CreatePen(ps_Solid,LW,$00FFFFFF);
    Pen2 := CreatePen(ps_Solid,LW,$00000000);
    end
  else
    begin
    Pen1 := CreatePen(ps_Solid,LW,$00000000);
    Pen2 := CreatePen(ps_Solid,LW,$00FFFFFF);
    end;

  OldPen := SelectObject(PaintDC,Pen1);   {Draw the highlights}
  PolyLine(PaintDC,LPts,3);
  SelectObject(PaintDC,Pen2);
  DeleteObject(Pen1);
  PolyLine(PaintDC,RPts,3);
  SelectObject(PaintDC,OldPen);
  DeleteObject(Pen2);
end;

{********************* TIcon  *****************************}
constructor  TIcon.Init(AParent:PWindowsObject; AnID:Integer;ATitle:PChar;
     X,Y,W,H:Integer;AGroup:PGroupBox;BMP:PChar);
begin
  TRadioButton.Init(AParent,AnID,ATitle,X,Y,W,H,AGroup);
  Attr.Style := Attr.Style or bs_OwnerDraw;
  HBmp := LoadBitmap(HInstance,BMP);
  State := sr_Raised;
end;

destructor  TIcon.Done;
begin
  DeleteObject(HBmp);
  TRadioButton.Done;
end;

procedure  TIcon.DrawItem(var Msg:TMessage);
var
  TheDC,MemDC:HDc;
  OldBitMap:HBitMap;
  Offset:Integer;
  PDIS :^TDrawItemStruct;
  X,Y,W,H:Integer;
  DBU:LongRec;
  GKS:Integer;
begin
  LongInt(DBU) := GetDialogBaseUnits;
  PDIS := Pointer(Msg.lParam);
  GKS := GetKeyState(vk_LButton);
  If IsIconic(hWindow) then Exit;
  if (PDIS^.itemAction = oda_DrawEntire) 	then
     State := State
  else if (PDIS^.itemAction = oda_Select) and
  (PDIS^.ItemState = ods_Selected + ods_Focus)
    then State := sr_Depressed
  else if (PDIS^.itemAction = 2) and
  (PDIS^.ItemState = ods_Focus) and (GKS < 0)
    then State := sr_Raised
  else Exit;
  X := PDIS^.rcItem.left;    Y := PDIS^.rcItem.top;
  W := PDIS^.rcItem.right-PDIS^.rcItem.left;
  H := PDIS^.rcItem.bottom-PDIS^.rcItem.top;
  OffSet := Round((H) / (DBU.lo * 4));
  MemDC := CreateCompatibleDC(PDIS^.HDC);
  OldBitMap := SelectObject(MemDC,HBMP);
  if State = 0 then BitBlt(PDIS^.HDC,X,Y,W,H, MemDC,0,0,SrcCopy)
    else BitBlt(PDIS^.HDC,X+OffSet,Y+OffSet,W,H, MemDC,0,0,SrcCopy);
  SelectObject(MemDC,OldBitMap);
  DeleteDC(MemDC);
  DrawHiLites(PDIS^.hDC,X,Y,PDIS^.rcItem.Right,PDIS^.rcitem.Bottom,OffSet,State)
end;
{******************  TIconGroup   ******************************}
constructor TIconGroup.Init(AParent:PWindowsObject;AnID:Integer;AText:PChar;
   X,Y,W,H:Integer);
begin
  TGroupBox.Init(AParent,AnId,AText,X,Y,W,H);
  Attr.Style := Attr.Style and not ws_Visible;
  OldIcon := nil;
  OldIconID := 0;
end;

procedure TIconGroup.SelectionChanged(NewIconID:Integer);
begin
  TGroupBox.SelectionChanged(NewIconID);
  if NewIconID = OldIconID then
    Exit;
  If OldIcon = nil then
    begin
    OldIcon := PIcon(Parent^.ChildWithID(NewIconID));
    OldIconID := NewIconID;
    end
  else
    begin
    OldIcon^.State := sr_Raised;
    InvalidateRect(OldIcon^.HWindow,nil,True);
    OldIcon := PIcon(Parent^.ChildWithID(NewIconID));
    OldIconID := NewIconID;
    end;
end;

end.
