Help & Manual authoring tool
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... This VCL patch fixes that problem.

Indistinguishable gray blobs in disabled menu items

Por Vladimir S. <shvetadvipa@mtu-net.ru>

InstallAWARE - MSI without rocket science

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
 
JfControls Library - for Delphi and C++ Builder
Copyright © 2000/2006 Ernesto De Spirito.   All rights reserved.