unit umain; interface uses Windows, Messages, SysUtils, {$IfNDef VER130} Variants, {$EndIf} Classes, Graphics, Controls, Forms, Dialogs, ieview, iemview, StdCtrls, FileCtrl, hyieutils, ExtCtrls, iexBitmaps, hyiedefs, iesettings, iexLayers, iexRulers; type TMainForm = class(TForm) GroupBox1: TPanel; DriveComboBox1: TDriveComboBox; DirectoryListBox1: TDirectoryListBox; ImageEnMView1: TImageEnMView; chkCustomDraw: TCheckBox; Label1: TLabel; procedure chkCustomDrawClick(Sender: TObject); procedure DirectoryListBox1Change(Sender: TObject); procedure ImageEnMView1ImageDraw2(Sender: TObject; idx, Left, Top: Integer; ImageRect: TRect; Canvas: TCanvas); procedure ImageEnMView1ImageAtPos(Sender: TObject; var idx: Integer; x, y: Integer); procedure ImageEnMView1CreateImage(Sender: TObject; idx: Integer); procedure ImageEnMView1DestroyImage(Sender: TObject; idx: Integer); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure ImageEnMView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } m_checkboxes : TList; FCheckBitmap : TBitmap; FNoCheckBitmap : TBitmap; end; var MainForm: TMainForm; implementation {$ifNdef VER130}{$ifNdef VER140} // From Delphi 7 uses uxTheme; {$EndIf}{$EndIf} {$R *.DFM} {$R WindowsTheme.res} // specify the checkbox relative position and size const CHECK_LEFT = 4; CHECK_TOP = 4; CHECK_WIDTH = 16; CHECK_HEIGHT = 16; procedure DrawCheckBoxToBitmap(DestBitmap: TBitmap; bChecked: Boolean); var {$ifNdef VER130}{$ifNdef VER140} // From Delphi 7 h: HTHEME; {$EndIf}{$EndIf} r: TRect; s: TSize; begin {$ifNdef VER130}{$ifNdef VER140} // From Delphi 7 if UseThemes then begin h := OpenThemeData(MainForm.Handle, 'BUTTON'); if h <> 0 then try GetThemePartSize(h, DestBitmap.Canvas.Handle, BP_CHECKBOX, CBS_CHECKEDNORMAL, nil, TS_DRAW, s); DestBitmap.Width := s.cx; DestBitmap.Height := s.cy; r := Rect(0, 0, s.cx, s.cy); if bChecked then DrawThemeBackground(h, DestBitmap.Canvas.Handle, BP_CHECKBOX, CBS_CHECKEDNORMAL, r, nil) else DrawThemeBackground(h, DestBitmap.Canvas.Handle, BP_CHECKBOX, CBS_UNCHECKEDNORMAL, r, nil); finally CloseThemeData(h); end; end else {$EndIf}{$EndIf} begin s.cx := GetSystemMetrics(SM_CXMENUCHECK); s.cy := GetSystemMetrics(SM_CYMENUCHECK); DestBitmap.Width := s.cx; DestBitmap.Height := s.cy; r := Rect(0, 0, s.cx, s.cy); if bChecked then DrawFrameControl(DestBitmap.Canvas.Handle, r, DFC_BUTTON, DFCS_CHECKED) else DrawFrameControl(DestBitmap.Canvas.Handle, r, DFC_BUTTON, DFCS_BUTTONCHECK); end; end; procedure TMainForm.chkCustomDrawClick(Sender: TObject); begin ImageEnMView1.Invalidate; end; procedure TMainForm.FormCreate(Sender: TObject); begin // m_checkboxes just contains "booleans". You could create a more complex object m_checkboxes := TList.Create; FCheckBitmap := TBitmap.Create; FNoCheckBitmap := TBitmap.Create; DrawCheckBoxToBitmap(FNoCheckBitmap, False); DrawCheckBoxToBitmap(FCheckBitmap, True); // load current directory DirectoryListBox1Change(self); end; procedure TMainForm.FormDestroy(Sender: TObject); begin // remember to destroy also objects (if any) FreeAndNil(m_checkboxes); FCheckBitmap.free; FNoCheckBitmap.free; end; // load all images in the directory procedure TMainForm.DirectoryListBox1Change(Sender: TObject); begin ImageEnMView1.Clear; ImageEnMView1.FillFromDirectory(DirectoryListBox1.Directory); ImageEnMView1.SelectedImage := 0; end; // draws the checkbox procedure TMainForm.ImageEnMView1ImageDraw2(Sender: TObject; idx, Left, Top: Integer; ImageRect: TRect; Canvas: TCanvas); var x1, y1, x2, y2:integer; begin x1 := Left + CHECK_LEFT; y1 := Top + CHECK_TOP; x2 := Left + CHECK_LEFT + CHECK_WIDTH; y2 := Top + CHECK_TOP + CHECK_HEIGHT; if chkCustomDraw.checked then begin Canvas.Pen.Color := clBlack; Canvas.Pen.Width := 2; Canvas.Brush.Color := clLime; if boolean(m_checkboxes[idx]) then begin Canvas.Brush.Style := bsSolid; Canvas.Rectangle(x1, y1, x2+1, y2+1); Canvas.MoveTo(x1, y1); Canvas.LineTo(x2, y2); Canvas.MoveTo(x2, y1); Canvas.LineTo(x1, y2); end else begin Canvas.Brush.Style := bsClear; Canvas.Rectangle(x1, y1, x2, y2); end; end else begin if boolean(m_checkboxes[idx]) then Canvas.Draw(x1, y1, FCheckBitmap) else Canvas.Draw(x1, y1, FNoCheckBitmap); end end; // check if inside the checkbox, avoid to select using the checkbox procedure TMainForm.ImageEnMView1ImageAtPos(Sender: TObject; var idx: Integer; x, y: Integer); begin if idx > -1 then begin // get relative mouse position (relative to the thumbnail) x := x + ImageEnMView1.ViewX - ImageEnMView1.ImageX[idx]; y := y + ImageEnMView1.ViewY - ImageEnMView1.ImageY[idx]; // is the point inside the checkbox? if IEPointInRect(x, y, CHECK_LEFT, CHECK_TOP, CHECK_LEFT + CHECK_WIDTH, CHECK_TOP + CHECK_HEIGHT) then idx := -1; // no image is selected here end; end; // handle check/uncheck checkbox procedure TMainForm.ImageEnMView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var idx:integer; bClickedCheck: Boolean; begin // which thumbnail is there at X,Y? idx := ImageEnMView1.ImageAtPos(X, Y); if idx > -1 then begin // get relative mouse position (relative to the thumbnail) x := x + ImageEnMView1.ViewX - ImageEnMView1.ImageX[idx]; y := y + ImageEnMView1.ViewY - ImageEnMView1.ImageY[idx]; // is the point inside the checkbox? if chkCustomDraw.checked then bClickedCheck := IEPointInRect(x, y, CHECK_LEFT, CHECK_TOP, CHECK_LEFT + CHECK_WIDTH, CHECK_TOP + CHECK_HEIGHT) else bClickedCheck := IEPointInRect(x, y, CHECK_LEFT, CHECK_TOP, CHECK_LEFT + FCheckBitmap.Width, CHECK_TOP + FCheckBitmap.Height); if bClickedCheck then begin // yes, check/uncheck it m_checkboxes[idx] := pointer( not boolean(m_checkboxes[idx]) ); // redraw the image (hence the method ImageEnMView1ImageDraw2 is called) ImageEnMView1.UpdateImage(idx); end; end; end; // a new image is inserted procedure TMainForm.ImageEnMView1CreateImage(Sender: TObject; idx: Integer); begin m_checkboxes.Insert(idx, pointer(false)); end; // an image is removed procedure TMainForm.ImageEnMView1DestroyImage(Sender: TObject; idx: Integer); begin if assigned(m_checkboxes) then m_checkboxes.Delete(idx); end; end.