imagelist:

- extend imagelist interface to draw image with more states
- win32: implement drawing of gray state

git-svn-id: trunk@12765 -
This commit is contained in:
paul 2007-11-07 10:14:05 +00:00
parent 5814f58500
commit 859fbcbdf6
5 changed files with 155 additions and 26 deletions

View File

@ -110,6 +110,13 @@ type
TDrawingStyle = (dsFocus, dsSelected, dsNormal, dsTransparent);
TImageType = (itImage, itMask);
TImageListDrawEffect =
(
ideNormal, // no effect
ideDisabled, // grayed image
ideHighlighted, // a bit highlighted image
ideShadowed // a bit shadowed image
);
TCustomImageList = class(TLCLHandleComponent)
private
@ -193,7 +200,8 @@ type
{.$endif}
procedure Delete(AIndex: Integer);
destructor Destroy; override;
procedure Draw(ACanvas: TCanvas; AX, AY, AIndex: Integer; AEnabled: Boolean = True);
procedure Draw(ACanvas: TCanvas; AX, AY, AIndex: Integer; AEnabled: Boolean = True); overload;
procedure Draw(ACanvas: TCanvas; AX, AY, AIndex: Integer; ADrawEffect: TImageListDrawEffect); overload;
procedure FillDescription(out ADesc: TRawImageDescription);
procedure GetBitmap(Index: Integer; Image: TBitmap);
{$ifdef IMGLIST_KEEP_EXTRA}
@ -239,15 +247,6 @@ type
property ImageType: TImageType read FImageType write FImageType default itImage;
end;
{ TImageList }
{ TImageList = class(TCustomImageList)
published
Property Height;
Property Width;
end;
}
implementation
uses

View File

@ -546,6 +546,18 @@ end;
------------------------------------------------------------------------------}
procedure TCustomImageList.Draw(ACanvas: TCanvas; AX, AY, AIndex: Integer;
AEnabled: Boolean);
const
EffectMap: array[Boolean] of TImageListDrawEffect =
(
ideDisabled,
ideNormal
);
begin
Draw(ACanvas, AX, AY, AIndex, EffectMap[AEnabled]);
end;
procedure TCustomImageList.Draw(ACanvas: TCanvas; AX, AY, AIndex: Integer;
ADrawEffect: TImageListDrawEffect);
{$ifdef IMGLIST_OLDSTYLE}
var
aBitmap: TBitmap;
@ -555,11 +567,11 @@ begin
{$ifdef IMGLIST_OLDSTYLE}
aBitmap := TBitmap(FImageList[AIndex]);
ACanvas.Draw(AX,AY,aBitmap);
ACanvas.Draw(AX, AY, aBitmap);
{$else}
HandleNeeded;
TWSCustomImageListClass(WidgetSetClass).Draw(Self, AIndex, ACanvas, Rect(AX, AY, FWidth, FHeight),
BkColor, BlendColor, AEnabled, DrawingStyle, ImageType);
BkColor, BlendColor, ADrawEffect, DrawingStyle, ImageType);
{$endif}
end;

View File

@ -70,6 +70,28 @@ type
end;
TComboboxInfo = tagCOMBOBOXINFO;
PComboboxInfo = ^TComboboxInfo;
tagIMAGELISTDRAWPARAMS = record
cbSize: DWORD;
himlL: HIMAGELIST;
i: integer;
hdcDst: HDC;
x: integer;
y: integer;
cx: integer;
cy: integer;
xBitmap: integer;
yBitmap: integer;
rgbBk: COLORREF;
rgbFg: COLORREF;
fStyle: UINT;
dwRop: DWORD;
fState: DWORD;
Frame: DWORD;
crEffect: DWORD;
end;
TImageListDrawParams = tagIMAGELISTDRAWPARAMS;
PImageListDrawParams = ^TImageListDrawParams;
{ Win32 API constants not included in windows.pp }
const
@ -307,11 +329,20 @@ function ListView_SetHoverTime(hwndLV: HWND; dwHoverTimeMs: DWORD): DWORD;
// missing imagelist macros and constants
const
// image list copy flags
ILCF_MOVE = $00000000;
ILCF_SWAP = $00000001;
// image list states
ILS_NORMAL = $00000000;
ILS_GLOW = $00000001;
ILS_SHADOW = $00000002;
ILS_SATURATE = $00000004;
ILS_ALPHA = $00000008;
function ImageList_Copy(himlDst: HIMAGELIST; iDst: longint; himlSrc: HIMAGELIST; Src: longint; uFlags: UINT): BOOL; stdcall; external 'comctl32';
// only with IExplorer 3.0 or later
function ImageList_DrawIndirect(pimldp: PIMAGELISTDRAWPARAMS): BOOL; stdcall; external 'comctl32';
{ Win32 API functions not included in windows.pp }
{ Get the ancestor at level Flag of window HWnd }
@ -820,7 +851,7 @@ end;
const
msimg32lib = 'msimg32.dll';
user32lib = 'user32.dll';
var
msimg32handle: THandle = 0;
user32handle: THandle = 0;

View File

@ -53,7 +53,7 @@ type
class procedure Delete(AList: TCustomImageList; AIndex: Integer); override;
class procedure DestroyHandle(AComponent: TComponent); override;
class procedure Draw(AList: TCustomImageList; AIndex: Integer; ACanvas: TCanvas;
ABounds: TRect; ABkColor, ABlendColor: TColor; AEnabled: Boolean; AStyle: TDrawingStyle; AImageType: TImageType); override;
ABounds: TRect; ABkColor, ABlendColor: TColor; ADrawEffect: TImageListDrawEffect; AStyle: TDrawingStyle; AImageType: TImageType); override;
class procedure Insert(AList: TCustomImageList; AIndex: Integer; AData: PRGBAQuad); override;
class procedure Move(AList: TCustomImageList; ACurIndex, ANewIndex: Integer); override;
class procedure Replace(AList: TCustomImageList; AIndex: Integer; AData: PRGBAQuad); override;
@ -77,7 +77,9 @@ const
{ itImage } ILD_NORMAL,
{ itMask } ILD_MASK
);
var
GreyColorMap: array[0..255] of Cardinal;
function ColorToImagelistColor(AColor: TColor): DWord;
begin
case AColor of
@ -264,14 +266,91 @@ begin
end;
class procedure TWin32WSCustomImageList.Draw(AList: TCustomImageList; AIndex: Integer;
ACanvas: TCanvas; ABounds: TRect; ABkColor, ABlendColor: TColor; AEnabled: Boolean; AStyle: TDrawingStyle; AImageType: TImageType);
ACanvas: TCanvas; ABounds: TRect; ABkColor, ABlendColor: TColor; ADrawEffect: TImageListDrawEffect; AStyle: TDrawingStyle; AImageType: TImageType);
var
hdcGrey, hdcBW: HDC;
hbmOld1, hbmGrey, hbmOld2, hbmBW: HBitmap;
InfoGrey: record
Header: TBitmapInfoHeader;
Colors: array[0..255] of Cardinal;
end;
BitsGrey: PChar;
DrawParams: TImageListDrawParams;
begin
if not WSCheckHandleAllocated(AList, 'Draw')
then Exit;
ImageList_DrawEx(HImageList(AList.Handle), AIndex, ACanvas.Handle, ABounds.Left,
ABounds.Top, ABounds.Right, ABounds.Bottom, ColorToImagelistColor(ABkColor),
ColorToImagelistColor(ABlendColor), DRAWINGSTYLEMAP[AStyle] or IMAGETPYEMAP[AImageType]);
if ADrawEffect <> ideDisabled then
begin
ImageList_DrawEx(HImageList(AList.Handle), AIndex, ACanvas.Handle, ABounds.Left,
ABounds.Top, ABounds.Right, ABounds.Bottom, ColorToImagelistColor(ABkColor),
ColorToImagelistColor(ABlendColor), DRAWINGSTYLEMAP[AStyle] or IMAGETPYEMAP[AImageType])
end
else
begin
// at moment only Disabled state is implemented
if (Win32WidgetSet.CommonControlsVersion >= ComCtlVersionIE6) then
begin
FillChar(DrawParams, SizeOf(DrawParams), 0);
DrawParams.cbSize := SizeOf(DrawParams);
DrawParams.himlL := HImageList(AList.Handle);
DrawParams.i := AIndex;
DrawParams.hdcDst := ACanvas.Handle;
DrawParams.x := ABounds.Left;
DrawParams.y := ABounds.Top;
DrawParams.cx := ABounds.Right;
DrawParams.cy := ABounds.Bottom;
DrawParams.rgbBk := ColorToImagelistColor(ABkColor);
DrawParams.rgbFg := ColorToImagelistColor(ABlendColor);
DrawParams.fStyle := DRAWINGSTYLEMAP[AStyle] or IMAGETPYEMAP[AImageType];
DrawParams.fState := ILS_SATURATE; // draw greyed
ImageList_DrawIndirect(@DrawParams);
end else
begin
hdcGrey := CreateCompatibleDC(ACanvas.Handle);
hdcBW := CreateCompatibleDC(ACanvas.Handle);
// create grey bitmap
FillChar(InfoGrey, sizeof(InfoGrey), 0);
InfoGrey.Header.biSize := sizeof(InfoGrey.Header);
InfoGrey.Header.biWidth := AList.Width;
InfoGrey.Header.biHeight := AList.Height;
InfoGrey.Header.biPlanes := 1;
InfoGrey.Header.biBitCount := 8;
InfoGrey.Header.biCompression := BI_RGB;
// fill color table
System.Move(GreyColorMap, InfoGrey.Colors, 256 * SizeOf(Cardinal));
hbmGrey := CreateDIBSection(hdcGrey, Windows.PBitmapInfo(@InfoGrey)^, DIB_RGB_COLORS, BitsGrey, 0, 0);
hbmBW := CreateBitmap(AList.Width, AList.Height, 1, 0, nil);
hbmOld1 := SelectObject(hdcGrey, hbmGrey);
hbmOld2 := SelectObject(hdcBW, hbmBW);
// draw to greyDC
ImageList_DrawEx(HImageList(AList.Handle), AIndex, hdcGrey, 0,
0, ABounds.Right, ABounds.Bottom, ColorToImagelistColor(ABkColor),
ColorToImagelistColor(ABlendColor), ILD_NORMAL);
// draw to bwDC
ImageList_DrawEx(HImageList(AList.Handle), AIndex, hdcBW, 0,
0, ABounds.Right, ABounds.Bottom, clBlack,
clWhite, ILD_MASK);
// draw grey
BitBlt(ACanvas.Handle, ABounds.Left, ABounds.Top, ABounds.Right,
ABounds.Bottom, hdcGrey, 0, 0, SRCCOPY);
// mask
BitBlt(ACanvas.Handle, ABounds.Left, ABounds.Top, ABounds.Right,
ABounds.Bottom, hdcBW, 0, 0, SRCINVERT);
DeleteObject(SelectObject(hdcBW, hbmOld2));
DeleteDC(hdcBW);
DeleteObject(SelectObject(hdcGrey, hbmOld1));
DeleteDC(hdcGrey);
end;
end;
end;
class procedure TWin32WSCustomImageList.Insert(AList: TCustomImageList;
@ -334,8 +413,16 @@ begin
then AddData(ImageList, 1, AIndex, AList.Width, AList.Height, AData);
end;
initialization
procedure InitGreyColormap;
var
i: Cardinal;
begin
for i := 0 to 255 do
GreyColorMap[i] := $FF000000 or (i shl 16) or (i shl 8) or i;
end;
initialization
InitGreyColormap;
////////////////////////////////////////////////////
// I M P O R T A N T
////////////////////////////////////////////////////

View File

@ -54,7 +54,7 @@ type
class procedure Delete(AList: TCustomImageList; AIndex: Integer); virtual;
class procedure DestroyHandle(AComponent: TComponent); override;
class procedure Draw(AList: TCustomImageList; AIndex: Integer; ACanvas: TCanvas;
ABounds: TRect; ABkColor, ABlendColor: TColor; AEnabled: Boolean; AStyle: TDrawingStyle; AImageType: TImageType); virtual;
ABounds: TRect; ABkColor, ABlendColor: TColor; ADrawEffect: TImageListDrawEffect; AStyle: TDrawingStyle; AImageType: TImageType); virtual;
class procedure Insert(AList: TCustomImageList; AIndex: Integer; AData: PRGBAQuad); virtual;
@ -76,7 +76,7 @@ type
FHeight: Integer;
public
constructor Create(AWidth, AHeight: Integer); reintroduce;
procedure Draw(AIndex: Integer; ACanvas: TCanvas; ABounds: TRect; AEnabled: Boolean; AStyle: TDrawingStyle);
procedure Draw(AIndex: Integer; ACanvas: TCanvas; ABounds: TRect; ADrawEffect: TImageListDrawEffect; AStyle: TDrawingStyle);
end;
{ TDefaultImageListImplementor }
@ -89,7 +89,7 @@ begin
end;
procedure TDefaultImageListImplementor.Draw(AIndex: Integer; ACanvas: TCanvas;
ABounds: TRect; AEnabled: Boolean; AStyle: TDrawingStyle);
ABounds: TRect; ADrawEffect: TImageListDrawEffect; AStyle: TDrawingStyle);
var
Bitmap: TBitmap;
begin
@ -158,12 +158,12 @@ begin
end;
class procedure TWSCustomImageList.Draw(AList: TCustomImageList; AIndex: Integer;
ACanvas: TCanvas; ABounds: TRect; ABkColor, ABlendColor: TColor; AEnabled: Boolean; AStyle: TDrawingStyle; AImageType: TImageType);
ACanvas: TCanvas; ABounds: TRect; ABkColor, ABlendColor: TColor; ADrawEffect: TImageListDrawEffect; AStyle: TDrawingStyle; AImageType: TImageType);
begin
if not WSCheckHandleAllocated(AList, 'Draw')
then Exit;
TDefaultImageListImplementor(AList.Handle).Draw(AIndex, ACanvas, ABounds, AEnabled, AStyle);
TDefaultImageListImplementor(AList.Handle).Draw(AIndex, ACanvas, ABounds, ADrawEffect, AStyle);
end;
class procedure TWSCustomImageList.Insert(AList: TCustomImageList;