|
Indistinguishable gray blobs in disabled menu items
Por Vladimir S. <shvetadvipa@mtu-net.ru>
If you want to see more interesting Delphi tips and tricks you can go
to http://www.webmachine.ru/delphi where
you can find the file
KULIBA.CHM by Valentin Ozerov that contains more than 1,500 tips and
tricks (in Russian language). Ozerov collected solutions from Russian
and other countries' programmers. There are some of my solutions too.
In one of them I describe how to conquer a glitch for certain disabled
menu items, which is the subject of this article.
Probably you have noticed that when you use images in menu items and
toolbar buttons, they look like indistinguishable gray blobs when these
components are disabled:
 |
|
 Menu and ToolBar without the patch |
One workaround for this problem is
modifying the VCL sources (you need to have the Enterprise edition for
this). First of all, find the file ImgList.pas, usually located in the
folder
${Delphi}\Source\Vcl
where ${Delphi} is the path where you installed Delphi, like for
example
C:\Program Files\Borland\Delphi5
Then locate the implementation of the TCustomImageList.DoDraw method.
Comment it out (to keep the old version just in case) and copy the
following code:
procedure TCustomImageList.DoDraw(Index: Integer; Canvas: TCanvas;
X, Y: Integer; Style: Cardinal; Enabled: Boolean);
procedure ScrambleBitmap(var BMP: TBitmap);
const
RMask = $0000FF;
RAMask = $FFFF00;
GMask = $00FF00;
GAMask = $FF00FF;
BMask = $FF0000;
BAMask = $00FFFF;
var
R,C: integer;
Color: LongWord;
begin
with Bmp.Canvas do begin
for C:= 0 to Bmp.Height - 1 do
for R:= 0 to Bmp.Width - 1 do begin
Color:= Pixels[R,C];
if (Color = 0) or (Color = $FFFFFF) then Continue;
if (Color and RMask > $7F) and (Color and RAMask > $0) or
(Color and GMask > $7F00) and (Color and GAMask > $0) or
(Color and BMask > $7F000) and (Color and BAMask > $0)
then
Pixels[R,C]:= $FFFFFF
else
Pixels[R,C]:= 0;
end;
end;
end;
const
ROP_DSPDxax = $00E20746;
var
R: TRect;
DestDC, SrcDC: HDC;
begin
if HandleAllocated then begin
if Enabled then
ImageList_DrawEx(Handle, Index, Canvas.Handle, X, Y, 0, 0,
GetRGBColor(BkColor), GetRGBColor(BlendColor), Style)
else begin
if FMonoBitmap = nil then begin
FMonoBitmap:= TBitmap.Create;
with FMonoBitmap do begin
// Monochrome:= True; commented!!!
Width:= Self.Width;
Height:= Self.Height;
end;
end;
{ Store masked version of image temporarily in FBitmap }
FMonoBitmap.Canvas.Brush.Color:= clWhite;
FMonoBitmap.Canvas.FillRect(Rect(0, 0, Self.Width,
Self.Height));
ImageList_DrawEx(Handle, Index, FMonoBitmap.Canvas.Handle,
0, 0, 0, 0, CLR_DEFAULT, 0, ILD_NORMAL);
ScrambleBitmap(FMonoBitmap); // call patch
R:= Rect(X, Y, X+Width, Y+Height);
SrcDC:= FMonoBitmap.Canvas.Handle;
BitBlt(SrcDC, 0, 0, Width, Height, SrcDC, 0, 0,
DSTINVERT); // add!!!
{ Convert Black to clBtnHighlight }
Canvas.Brush.Color:= clBtnHighlight;
DestDC:= Canvas.Handle;
Windows.SetTextColor(DestDC, clWhite);
Windows.SetBkColor(DestDC, clBlack);
BitBlt(DestDC, X+1, Y+1, Width, Height, SrcDC, 0, 0,
ROP_DSPDxax);
{ Convert Black to clBtnShadow }
Canvas.Brush.Color:= clBtnShadow;
DestDC:= Canvas.Handle;
Windows.SetTextColor(DestDC, clWhite);
Windows.SetBkColor(DestDC, clBlack);
BitBlt(DestDC, X, Y, Width, Height, SrcDC, 0, 0, ROP_DSPDxax);
end;
end;
end;
Now you need to compile this unit. This is normally done by placing
the ImgList.pas file in the same directory where your project
resides and then compiling the project. This will produce the
file ImgList.dcu that
you have to copy for example in the ${Delphi}\Lib folder, so
that it applies to all applications that you compile in the future.
The graphics that result with this patch look a lot better:
 |
|
 Menu and ToolBar with the patch |
| |
|