|
Formas grises casi indistinguibles en elementos de menú inhabilitados
Por Vladimir S. <shvetadvipa@mtu-net.ru>
Si desea ver consejos y trucos Delphi interesantes vaya con su navegador
a http://www.webmachine.ru/delphi donde encontrará el archivo KULIBA.CHM
por Valentin Ozerov que contiene más de 1.500 trucos y consejos (en
ruso). Ozerov recolectó soluciones de programadores de Rusia y de todo
el mundo, entre las que se encuentran algunas de mis soluciones también.
En una de ellas describo como superar una falla para ciertos elementos
de menú inhabilitados, que es el objeto de este artículo.
Probablemente haya notado que cuando usa imágenes en elementos de menú
y botones en barras de herramientas, éstas se ven como figuras grises
casi indistinguibles cuando dichos componentes están inhabilitados:
 |
|
 Menú y Barra de Herramientas sin el parche |
Una posible
solución a este problema es moficar el código fuente de la VCL (necesita
tener la Edición Empresarial de Delphi para esto). Antes que nada,
busque el fichero ImgList.pas, habitualmente ubicado en la carpeta
${Delphi}\Source\Vcl
donde ${Delphi} es el camino donde instaló Delphi, como por ejemplo
C:\Archivos de programa\Borland\Delphi5
Luego ubique la implementación del método TCustomImageList.DoDraw.
Coméntela (para mantener la versión original por si acaso) y copie el
siguiente código:
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;
Ahora debe compilar esta unidad. Esto normalmente se hace copiando el
archivo ImgList.pas en el mismo directorio donde reside su proyecto y luego
compilando el proyecto, produciendo así el archivo ImgList.dcu que debe
mover por ejemplo a la carpeta ${Delphi}\Lib para que aplique a todas
las aplicaciones que compile en el futuro.
Los gráficos que resultan con este parche se ven muchísimo mejor:
 |
|
 Menú y Barra de Herramientas con el parche |
| |
|