diff --git a/lcl/imglist.pp b/lcl/imglist.pp index 842b515fd3..60a5a50d20 100644 --- a/lcl/imglist.pp +++ b/lcl/imglist.pp @@ -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 diff --git a/lcl/include/imglist.inc b/lcl/include/imglist.inc index e5ba9a4c61..16e3ececfd 100644 --- a/lcl/include/imglist.inc +++ b/lcl/include/imglist.inc @@ -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; diff --git a/lcl/interfaces/win32/win32extra.pas b/lcl/interfaces/win32/win32extra.pas index 0ba8ed3e72..d640f75a37 100644 --- a/lcl/interfaces/win32/win32extra.pas +++ b/lcl/interfaces/win32/win32extra.pas @@ -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; diff --git a/lcl/interfaces/win32/win32wsimglist.pp b/lcl/interfaces/win32/win32wsimglist.pp index 934f69908b..6bd1e23e2c 100644 --- a/lcl/interfaces/win32/win32wsimglist.pp +++ b/lcl/interfaces/win32/win32wsimglist.pp @@ -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 //////////////////////////////////////////////////// diff --git a/lcl/widgetset/wsimglist.pp b/lcl/widgetset/wsimglist.pp index 358289644d..0ee1eb3910 100644 --- a/lcl/widgetset/wsimglist.pp +++ b/lcl/widgetset/wsimglist.pp @@ -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;