2007. június 12., kedd

How to fix the color and drop shadow glitches in the TActionMainMenuBar component


Problem/Question/Abstract:

The ActionMainMenuBar highlight color is always blue, even if I have the green theme selected (the highlights should be green). How do I fix this? If I turn of menu shadows in Windows, my app still shows menu shadows, so how do I use the Shadows property to detect and fix this? Under Windows XP when XP Manifest is included, the file menu shadow does not draw properly. Actually it is the right border which does not draw properly. It is missing, it is a 3 sided box. How do I fix this?

Answer:

Here is a solution I found to address all three problems I reported. Everything seems to be good now and finally I can use this component. First I created a new color map component which detects the correct colors (based on the XPColorMap component). See below for the source. This fixes the color problem and the 3-sided menu box problem. Even if the user changes themes during the application, the menus will update with the new colors!

To fix the shadow problem do this on your menu's popup event. It checks if the shadows option is enabled in Windows.

procedure TForm1.PopupActionBarEx1Popup(Sender: TObject);
var
  DisplayShadow: Boolean;
begin
  if CheckWin32Version(5, 1) and SystemParametersInfo(SPI_GETDROPSHADOW, 0,
    @DisplayShadow, 0) then
    PopupActionBarEx1.Shadows := DisplayShadow;
end;

The new color map component:

unit XPColorMapEx;

interface

uses
  Windows, SysUtils, Classes, ActnMan, Graphics, GraphUtil;

type
  TXPColorMapEx = class(TCustomActionBarColorMap)
  public
    { Public declarations }
    procedure UpdateColors; override;
  published
    { Published declarations }
    property ShadowColor;
    property Color;
    property DisabledColor;
    property DisabledFontColor;
    property DisabledFontShadow;
    property FontColor;
    property HighlightColor;
    property HotColor;
    property HotFontColor;
    property MenuColor;
    property FrameTopLeftInner;
    property FrameTopLeftOuter;
    property FrameBottomRightInner;
    property FrameBottomRightOuter;
    property BtnFrameColor;
    property BtnSelectedColor;
    property SelectedColor;
    property SelectedFontColor;
    property UnusedColor;
    property OnColorChange;
  end;

procedure Register;

implementation

{ Merge the two colors using the alpha percentage }

function BlendColors(First, Second: TColor; Alpha: Integer): TColor;
var
  fR, fG, fB, sR, sG, sB: Integer;
begin
  fR := GetRValue(First);
  fG := GetGValue(First);
  fB := GetBValue(First);
  sR := GetRValue(Second);
  sG := GetGValue(Second);
  sB := GetBValue(Second);
  Result := RGB(Round(((Alpha * fR) + ((100 - Alpha) * sR)) / 100), Round(((Alpha * fG) + ((100 - Alpha) * sG)) / 100), Round(((Alpha * fB) + ((100 - Alpha) * sB)) / 100));
end;

procedure TXPColorMapEx.UpdateColors;
begin
  inherited;
  Color := clBtnFace;
  MenuColor := clWindow;
  BtnFrameColor := GetSysColor(COLOR_HIGHLIGHT);
  BtnSelectedColor := GetSysColor(COLOR_BTNFACE);
  DisabledFontColor := clGrayText;
  DisabledFontShadow := clBtnHighlight;
  DisabledColor := clGray;
  FontColor := clWindowText;
  FrameTopLeftInner := clWhite;
  FrameTopLeftOuter := $007A868A;
  FrameBottomRightInner := clWhite;
  FrameBottomRightOuter := $007A868A;
  HighlightColor := GetHighLightColor(clBtnFace, 15);
  HotColor := clDefault;
  HotFontColor := clDefault;
  SelectedColor := BlendColors(GetSysColor(COLOR_HIGHLIGHT), clWhite, 33);
  SelectedFontColor := clBlack;
  ShadowColor := cl3DDkShadow;
  UnusedColor := GetHighLightColor(clBtnFace, 15);
end;

procedure Register;
begin
  RegisterComponents('Samples', [TXPColorMapEx]);
end;

end.

Nincsenek megjegyzések:

Megjegyzés küldése