⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpmenu.pas

📁 一套非常好用的delphi控件,方便程序员工作
💻 PAS
📖 第 1 页 / 共 5 页
字号:
{
XPMenu for Delphi
Author: Khaled Shagrouni
URL: http://www.shagrouni.com/english/software/xpmenu.html
e-mail: shagrouni@hotmail.com
Version 3.0 Beta 1, 19.01.2003



XPMenu is a Delphi component to mimic Office XP menu and toolbar style.
Copyright (C) 2001, 2002 Khaled Shagrouni.

This component is FREEWARE with source code. I still hold the copyright, but
you can use it for whatever you like: freeware, shareware or commercial software.
If you have any ideas for improvement or bug reports, don't hesitate to e-mail
me <khaled@shagrouni.com> (Please state the XPMenu version and OS/Delphi information).
}

{$IFDEF VER130}
{$DEFINE VER5U}
{$ENDIF}

{$IFDEF VER140}
{$DEFINE VER5U}
{$DEFINE VER6U}
{$ENDIF}

{$IFDEF VER150}
{$DEFINE VER5U}
{$DEFINE VER6U}
{$DEFINE VER7U}
{$ENDIF}



unit XPMenu;

interface

uses
  Windows, SysUtils, Classes, Graphics, Controls, ComCtrls,  Forms,
  Menus, Messages, Commctrl, ExtCtrls, StdCtrls, Buttons;

type

  TXPContainer = (xccForm, xccFrame, xccToolbar, xccCoolbar, xccControlbar, xccPanel,
                  xccScrollBox, xccGroupBox, xccTabSheet, xccPageScroller);
  TXPContainers = set of TXPContainer;

  TXPControl = (xcMainMenu, xcPopupMenu, xcToolbar, xcControlbar, xcCombo, xcListBox,
                xcEdit, xcMaskEdit, xcMemo, xcRichEdit, xcCheckBox, xcRadioButton,
                xcButton, xcBitBtn, xcSpeedButton, xcPanel, xcGroupBox);

  TXPControls = set of TXPControl;

  TXPMenu = class;

  TControlSubClass = class(TComponent)   //:   "Fabian Jakubowski" <fj@sambreville.com>
  private
    Control: TControl;
    FBuilding: boolean;
    FMouseInControl: boolean;
    FLButtonBressed: boolean;
    FBressed: boolean;
    FIsKeyDown: boolean;
    FIsFocused: boolean;
    orgWindowProc: TWndMethod;
    XPMenu: TXPMenu;
    FCtl3D: boolean;
    FBorderStyle: TBorderStyle;
    FMsg: Cardinal;
    procedure ControlSubClass(var Message: TMessage);
    procedure PaintControlXP;
    procedure PaintCombo;
    procedure PaintDBLookupCombo;
    procedure PaintEdit;
    procedure PaintRichEdit;
    procedure PaintCheckBox;
    procedure PaintRadio;
    procedure PaintButton;
    procedure PaintBitButn;
    procedure PaintUpDownButton;
    procedure PaintSpeedButton;
    procedure PaintPanel;
    procedure PaintGroupBox;
    procedure PaintListBox;

  end;

  TXPMenu = class(TComponent)
  private
    FActive: boolean;
    {Changes MMK FForm to TScrollingWinControl}
    FForm: TScrollingWinControl;
    FFont: TFont;
    FColor: TColor;
    FIconBackColor: TColor;
    FMenuBarColor: TColor;
    FCheckedColor: TColor;
    FSeparatorColor: TColor;
    FSelectBorderColor: TColor;
    FSelectColor: TColor;
    FDisabledColor: TColor;
    FSelectFontColor: TColor;
    FIconWidth: integer;
    FDrawSelect: boolean;
    FUseSystemColors: boolean;

    FFColor, FFIconBackColor, FFSelectColor, FFSelectBorderColor,
    FFSelectFontColor, FCheckedAreaColor, FCheckedAreaSelectColor,
    FFCheckedColor, FFMenuBarColor, FFDisabledColor, FFSeparatorColor,
    FMenuBorderColor, FMenuShadowColor: TColor;

    Is16Bit: boolean;
    FOverrideOwnerDraw: boolean;
    FGradient: boolean;
    FFlatMenu: boolean;
    FAutoDetect: boolean;
    FXPContainers: TXPContainers;
    FXPControls: TXPControls;
    FGrayLevel: byte;
    FDimLevel: byte;
    FDrawMenuBar: boolean;
    FUseDimColor: boolean;
    FDimParentColor, FDimParentColorSelect: integer;
   // FUseParentClor: boolean;

   // Added by Uwe Runkel, uwe@runkel.info
   // Enable XPMenu to be used globally (all windows in the application use XPMenu).
   // Hence you don't need more than one instance in an application. However it is also
   // possible to have more than one instance. This will disable subclassing of controls by
   // all other but the first XPMenu instance.
    FDisableSubclassing: boolean;
    FShutDown: boolean;
    FPendingFormsList: TList;
    FFormList: TList;
    function MainWindowHook(var Message: TMessage): boolean;
    procedure CollectForms;
    function GetIsMainXPMenu: boolean;
    procedure SetDisableSubclassing(const Value: boolean);
   // ----- end ur -----

    procedure SetActive(const Value: boolean);
    procedure SetAutoDetect(const Value: boolean);
    procedure SetForm(const Value: TScrollingWinControl);
    procedure SetFont(const Value: TFont);
    procedure SetColor(const Value: TColor);
    procedure SetIconBackColor(const Value: TColor);
    procedure SetMenuBarColor(const Value: TColor);
    procedure SetCheckedColor(const Value: TColor);
    procedure SetDisabledColor(const Value: TColor);
    procedure SetSelectColor(const Value: TColor);
    procedure SetSelectBorderColor(const Value: TColor);
    procedure SetSeparatorColor(const Value: TColor);
    procedure SetSelectFontColor(const Value: TColor);
    procedure SetIconWidth(const Value: integer);
    procedure SetDrawSelect(const Value: boolean);
    procedure SetUseSystemColors(const Value: boolean);
    procedure SetOverrideOwnerDraw(const Value: boolean);
    procedure SetGradient(const Value: boolean);
    procedure SetFlatMenu(const Value: boolean);
    procedure SetXPContainers(const Value: TXPContainers);
    procedure SetXPControls(const Value: TXPControls);
    procedure SetDrawMenuBar(const Value: boolean);
    procedure SetUseDimColor(const Value: boolean);

  protected
    procedure Loaded; override; //add by Cunha, liyang.
    procedure InitItems(wForm: TWinControl; Enable, Update: boolean);
    procedure InitItem(Comp: TComponent; Enable, Update: boolean); // Tom: "Thomas Knoblauch" <thomas@tom-the-bomb.de> 27.08
    procedure DrawItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect;
      Selected: Boolean);
    procedure MenueDrawItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect;
      Selected: Boolean);
    {$IFDEF VER5U}
    procedure ToolBarDrawButton(Sender: TToolBar;
      Button: TToolButton; State: TCustomDrawState; var DefaultDraw: Boolean);
    {$ENDIF}
    procedure ControlBarPaint(Sender: TObject; Control: TControl;
      Canvas: TCanvas; var ARect: TRect; var Options: TBandPaintOptions);


    procedure SetGlobalColor(ACanvas: TCanvas);
    procedure DrawTopMenuItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect;
      BckColor:Tcolor; IsRightToLeft: boolean);
    procedure DrawCheckedItem(FMenuItem: TMenuItem; Selected, Enabled,
     HasImgLstBitmap: boolean; ACanvas: TCanvas; CheckedRect: TRect);
    procedure DrawTheText(Sender: TObject; txt, ShortCuttext: string;
       ACanvas: TCanvas; TextRect: TRect;
       Selected, Enabled, Default, TopMenu, IsRightToLeft: boolean;
       var TxtFont: TFont; TextFormat: integer);
    procedure DrawIcon(Sender: TObject; ACanvas: TCanvas; B: TBitmap;
     IconRect: Trect; Hot, Selected, Enabled, Checked, FTopMenu,
     IsRightToLeft: boolean);

    procedure MeasureItem(Sender: TObject; ACanvas: TCanvas;
      var Width, Height: Integer);

    function GetImageExtent(MenuItem: TMenuItem): TPoint;
    function TopMenuFontColor(ACanvas: TCanvas; Color: TColor): TColor;
    procedure DrawGradient(ACanvas: TCanvas; ARect: TRect;
     IsRightToLeft: boolean);

    procedure DrawWindowBorder(hWnd: HWND; IsRightToLeft: boolean);

    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure InitComponent(Comp: TComponent); // Tom: Added for usage by the main program ."Thomas Knoblauch" <thomas@tom-the-bomb.de> 27.08
    procedure MakeMainXPMenu;
    procedure ActivateMenuItem(MenuItem: TMenuItem);
    property Form: TScrollingWinControl read FForm write SetForm;
   // Added by Uwe Runkel, uwe@runkel.info
    property IsMainXPMenu: boolean read GetIsMainXPMenu;
   // ----- end ur -----
  published
    property DimLevel: Byte read FDimLevel write FDimLevel;
    property GrayLevel: Byte read FGrayLevel write FGrayLevel;
    property Font: TFont read FFont write SetFont;
    property Color: TColor read FColor write SetColor;
    property DrawMenuBar: boolean read FDrawMenuBar write SetDrawMenuBar;
    property IconBackColor: TColor read FIconBackColor write SetIconBackColor;
    property MenuBarColor: TColor read FMenuBarColor write SetMenuBarColor;
    property SelectColor: TColor read FSelectColor write SetSelectColor;
    property SelectBorderColor: TColor read FSelectBorderColor
     write SetSelectBorderColor;
    property SelectFontColor: TColor read FSelectFontColor
     write SetSelectFontColor;
    property DisabledColor: TColor read FDisabledColor write SetDisabledColor;
    property SeparatorColor: TColor read FSeparatorColor
     write SetSeparatorColor;
    property CheckedColor: TColor read FCheckedColor write SetCheckedColor;
    property IconWidth: integer read FIconWidth write SetIconWidth;
    property DrawSelect: boolean read FDrawSelect write SetDrawSelect;
    property UseSystemColors: boolean read FUseSystemColors
     write SetUseSystemColors;
    property UseDimColor: boolean read FUseDimColor write SetUseDimColor;
    property OverrideOwnerDraw: boolean read FOverrideOwnerDraw
     write SetOverrideOwnerDraw;

    property Gradient: boolean read FGradient write SetGradient;
    property FlatMenu: boolean read FFlatMenu write SetFlatMenu;
    property AutoDetect: boolean read FAutoDetect write SetAutoDetect;
    property XPContainers: TXPContainers read FXPContainers write SetXPContainers
      default [xccForm, xccFrame, xccToolbar, xccCoolbar, xccControlbar, xccPanel,
                  xccScrollBox, xccGroupBox, xccTabSheet, xccPageScroller];
    property XPControls :TXPControls read FXPControls write SetXPControls
      default [xcMainMenu, xcPopupMenu, xcToolbar, xcControlbar, xcCombo,
               xcEdit, xcMaskEdit, xcMemo, xcRichEdit, xcCheckBox, xcRadioButton,
               xcButton, xcBitBtn, xcSpeedButton, xcPanel, xcGroupBox];

    property Active: boolean read FActive write SetActive;

   // Added by Uwe Runkel, uwe@runkel.info
    property DisableSubclassing: boolean read FDisableSubclassing write SetDisableSubclassing
      default false;
//    property IsMainXPMenu: boolean read GetIsMainXPMenu;
   // ----- end ur -----
  end;



function GetShadeColor(ACanvas: TCanvas; clr: TColor; Value: integer): TColor;
function NewColor(ACanvas: TCanvas; clr: TColor; Value: integer): TColor;
procedure DimBitmap(ABitmap: TBitmap; Value: integer);
procedure DrawArrow(ACanvas: TCanvas; X, Y: integer);
function GrayColor(ACanvas: TCanvas; clr: TColor; Value: integer): TColor;

procedure GrayBitmap(ABitmap: TBitmap; Value: integer);
procedure DrawBitmapShadow(B: TBitmap; ACanvas: TCanvas; X, Y: integer;
  ShadowColor: TColor);
procedure DrawCheckMark(ACanvas: TCanvas; X, Y: integer);

//procedure GetSystemMenuFont(Font: TFont);

procedure Register;

implementation

// Added by Uwe Runkel, uwe@runkel.info
const
  WM_MAINXPMENURELEASED = CN_NOTIFY + 100;   // Notifocation when main XPMenu has been
                                             // destroyed
var
  MainXPMenu: TXPMenu;                       // Main XPMenu (only this one can subclass
                                             // forms to use XPMenu automatically)
// ----- end ur -----

procedure Register;
begin
  RegisterComponents('XP', [TXPMenu]);
end;

// Added by Uwe Runkel, uwe@runkel.info
// Test if mouse cursor is in the given rect of the application's main form
function IsMouseInRect(TheForm: TScrollingWinControl; DestRect: TRect): boolean;
var
  p: TPoint;

begin

//  if Assigned(Application.MainForm)
  if Assigned(TheForm) then
  begin
    p := Mouse.CursorPos;
    p.x := p.x - TheForm.Left;//  Application.MainForm.Left;
    p.y := p.y - TheForm.Top;//   Application.MainForm.Top;

    Dec(DestRect.Right);
    Dec(DestRect.Bottom, 2);
    Result := (p.x >= DestRect.Left) and (p.x <= DestRect.Right) and
              (p.y >= DestRect.Top) and (p.y <= DestRect.Bottom);
  end
  else Result := false;
end;
// ----- end ur -----

{ TXPMenue }

constructor TXPMenu.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

// Added by Uwe Runkel, uwe@runkel.info
// Prepare list used for global usage of XPMenu
  FPendingFormsList := TList.Create;   // list of forms inserted but not subclassed yet
  FFormList := TList.Create;           // list of subclassed forms
  FDisableSubclassing := false;        // enable XPMenu to be used globally
  FShutDown := false;
// ----- end ur -----

  FFont := TFont.Create;

{$IFDEF VER5U}
  FFont.Assign(Screen.MenuFont);
{$ELSE}
  GetSystemMenuFont(FFont);
{$ENDIF}
  FForm := Owner as TScrollingWinControl;

//  (FForm as TCustomForm).Font := FFont; //felix added resolving font problems
                                          //in Chinese Win98

  FUseSystemColors := true;


  FColor := clBtnFace;
  FIconBackColor := clBtnFace;
  FSelectColor := clHighlight;
  FSelectBorderColor := clHighlight;
  FMenuBarColor := clBtnFace;
  FDisabledColor := clInactiveCaption;
  FSeparatorColor := clBtnFace;
  FCheckedColor := clHighlight;
  FSelectFontColor := FFont.Color;
  FGrayLevel := 10;
  FDimLevel := 30;
  FIconWidth := 24;
  FDrawSelect := true;
  XPContainers := [xccForm, xccFrame, xccToolbar, xccCoolbar, xccControlbar, xccPanel,
                  xccScrollBox, xccGroupBox, xccTabSheet, xccPageScroller];
  XPControls := [xcMainMenu, xcPopupMenu, xcToolbar, xcControlbar, xcCombo, xcListBox,
                xcEdit, xcMaskEdit, xcMemo, xcRichEdit, xcCheckBox, xcRadioButton,
                xcButton, xcBitBtn, xcSpeedButton, xcPanel, xcGroupBox];


  if Assigned(FForm) then
    SetGlobalColor(TForm(FForm).Canvas);

// Added by Uwe Runkel, uwe@runkel.info
// In an application only one main XPMenu can do subclassing. The first inserted XPMenu is
// set as this main XPMenu. All other XPMenu componets have subclassing disabled
  if not(csDesigning in ComponentState) then begin
    if (MainXPMenu = nil) and not(FDisableSubclassing) and not(FShutDown) then
      MainXPMenu := Self
    else begin
      FDisableSubclassing := true;
      if MainXPMenu.FFormList.IndexOf(FForm) >= 0 then
      begin
        InitItems(FForm, false, true);
        MainXPMenu.FFormList.Remove(FForm);
      end;
      MainXPMenu.FPendingFormsList.Remove(FForm);
    end;
// listen to windows messages sent to the main window, so we can look if there are pending
// forms to be subclassed
    Application.HookMainWindow(MainWindowHook);
  end;
// ----- end ur -----


  {if FActive then
  begin
    InitItems(FForm, true, false);
  end;
  }
end;

destructor TXPMenu.Destroy;
begin
// Added by Uwe Runkel, uwe@runkel.info
  FPendingFormsList.Free;
  FFormList.Free;
  FShutDown := true;
// ----- end ur -----
  if Assigned(FForm) then    //oleg oleg@vdv-s.ru  Mon Oct  7
    InitItems(FForm, false, false);
  FFont.Free;
// Added by Uwe Runkel, uwe@runkel.info
  if not(csDesigning in ComponentState) then
  begin
    Application.UnhookMainWindow(MainWindowHook);
    if MainXPMenu = self then
    begin
      MainXPMenu := nil;             //??
      if Application.Handle <> 0 then
        SendAppMessage(WM_MAINXPMENURELEASED, ord(FDisableSubclassing), 0);
    end;
  end
  else
    MainXPMenu := nil;
// ----- end ur -----
  inherited;
end;

//add by:
//liyang <liyang@guangdainfo.com> ,2002-07-19
//Pedro Miguel Cunha <PCunha@codeware.pt>- 02 Apr 2002
procedure TXPMenu.Loaded;
begin
  inherited Loaded;
 { if FActive then
  begin
    InitItems(FForm, true, false);
  end;}
// Added by Uwe Runkel, uwe@runkel.info
// Collect all forms which already exist at this time
  if (MainXPMenu = self) and not(csDesigning in ComponentState) then
    CollectForms;
// ----- end ur -----
end;

// Added by Uwe Runkel, uwe@runkel.info
// Listens to messages sent to the application and looks if a window is inserted.
function TXPMenu.MainWindowHook(var Message: TMessage): boolean;
var

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -