cxgridcustompopupmenu.pas
来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 777 行 · 第 1/2 页
PAS
777 行
{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressQuantumGrid Utils }
{ }
{ Copyright (c) 1998-2008 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSQUANTUMGRID AND ALL }
{ ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{********************************************************************}
unit cxGridCustomPopupMenu;
{$I cxVer.inc}
interface
uses
Windows, Messages, Classes, SysUtils, Controls, cxGridCustomView, Menus;
const
cxhtGridBase = 1000;
type
EcxGridPopupMenu = class(Exception);
TcxGridViewHitType = (gvhtGridNone, gvhtGridTab, gvhtNone, gvhtTab, gvhtCell,
gvhtExpandButton, gvhtRecord, gvhtNavigator, gvhtPreview, gvhtColumnHeader,
gvhtColumnHeaderFilterButton, gvhtFilter, gvhtFooter, gvhtFooterCell,
gvhtGroupFooter, gvhtGroupFooterCell, gvhtGroupByBox, gvhtIndicator,
gvhtRowIndicator, gvhtRowLevelIndent, gvhtBand, gvhtBandHeader,
gvhtRowCaption, gvhtSeparator, gvhtGroupSummary);
TcxGridViewHitTypes = set of TcxGridViewHitType;
TcxGridBeforePopupProc = procedure(ASenderMenu: TComponent;
AHitTest: TcxCustomGridHitTest; X,Y: Integer; var AllowPopup: Boolean) of object;
TcxGridOnPopupProc = procedure(ASenderMenu: TComponent;
AHitTest: TcxCustomGridHitTest; X,Y: Integer) of object;
TcxGridPopupMenuItemClickProc = procedure(ASender: TObject;
AHitTest: TcxCustomGridHitTest; var AHandler: TNotifyEvent;
AParams: TList; var AHandled: Boolean) of object;
IDoPopup = interface
['{41999EDE-B9D9-4808-9D01-61B09DF700FA}']
function GetPopupHandler: TcxGridOnPopupProc;
end;
IcxGridPopupMenu = interface
['{302C3B32-D753-43A6-BAE2-F513EB4F9399}']
function CanPopup(AHitTest: TcxCustomGridHitTest): Boolean;
end;
TcxPopupMenuInfo = Class(TCollectionItem)
private
FPopupMenu: TComponent;
FPopupProc: TcxGridOnPopupProc;
FHitTypes: TcxGridViewHitTypes;
FLocked: Boolean;
FView: TcxCustomGridView;
FViewClass: TcxCustomGridViewClass;
function FindCorrectComponent(const AComponent: TComponent): TComponent;
procedure SetPopupMenu(const AValue: TComponent);
procedure SetView(const AValue: TcxCustomGridView);
procedure SetViewClass(const Value: TcxCustomGridViewClass);
protected
FIsBuiltIn: Boolean;
procedure BeginUpdate; virtual;
procedure EndUpdate; virtual;
function CanPopup(AHitTest: TcxCustomGridHitTest): Boolean;
procedure DoChanged(const APopupMenu: TComponent; const AView: TcxCustomGridView;
AViewClass: TcxCustomGridViewClass); virtual;
property GridViewClass: TcxCustomGridViewClass read FViewClass write SetViewClass;
public
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
property IsBuiltIn: Boolean read FIsBuiltIn;
published
property GridView: TcxCustomGridView read FView write SetView;
property HitTypes: TcxGridViewHitTypes read FHitTypes write FHitTypes;
property Index;
property OnPopup: TcxGridOnPopupProc read FPopupProc write FPopupProc;
property PopupMenu: TComponent read FPopupMenu write SetPopupMenu;
end;
TcxPopupMenuInfos = class(TCollection)
private
FOwner: TComponent;
function GetItem(AIndex: Integer): TcxPopupMenuInfo;
procedure SetItem(AIndex: Integer; const AValue: TcxPopupMenuInfo);
protected
function GetOwner: TPersistent; override;
function IsMenuInfoShortCut(AMenuInfo: TcxPopupMenuInfo;
var Message: TWMKey): Boolean; virtual;
function IsShortCut(var Message: TWMKey): Boolean; virtual;
{$IFDEF DELPHI6}
procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); override;
{$ENDIF}
public
constructor Create(AOwner: TComponent); virtual;
function GetSameMenuCount(const AMenu: TComponent): Integer;
property Items[AIndex: Integer]: TcxPopupMenuInfo read GetItem write SetItem; default;
end;
TcxCustomGridPopupMenu = class(TComponent)
private
FPopupMenuInfos: TcxPopupMenuInfos;
function GetMenuInfo(AIndex: Integer): TcxPopupMenuInfo;
function GetMenuInfoCount: Integer;
procedure SetPopupMenuInfos(const AValue: TcxPopupMenuInfos);
protected
procedure AddMenuInfo(const AMenu: TComponent; AHitTypes: TcxGridViewHitTypes;
ADoPopupProc: TcxGridOnPopupProc; AViewClass: TcxCustomGridViewClass = nil;
const AView: TcxCustomGridView = nil; AIsBuiltIn: Boolean = False);
procedure AdjustMenuInfo(AMenuInfo: TcxPopupMenuInfo;
const AMenu: TComponent; AHitTypes: TcxGridViewHitTypes;
ADoPopupProc: TcxGridOnPopupProc; AViewClass: TcxCustomGridViewClass = nil;
const AView: TcxCustomGridView = nil; AIsBuiltIn: Boolean = False);
procedure ClearMenuInfosGridView(const AView: TcxCustomGridView = nil);
function GetPopupMenuInfo(const AMenu: TComponent; const AView: TcxCustomGridView;
ASearchDefault: Boolean = True): TcxPopupMenuInfo; overload; virtual;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
property PopupMenuInfos: TcxPopupMenuInfos read FPopupMenuInfos write SetPopupMenuInfos;
property MenuInfos[AIndex: Integer]: TcxPopupMenuInfo read GetMenuInfo; default;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function CheckShortCuts(var Message: TWMKeyDown): Boolean; virtual;
function FindPopupMenuInfo(const AView: TcxCustomGridView;
AHitType: TcxGridViewHitType; AHitTest: TcxCustomGridHitTest): TcxPopupMenuInfo; virtual;
function GetPopupMenuInfo(const AMenu: TComponent; AViewClass: TcxCustomGridViewClass;
ASearchDefault: Boolean = True): TcxPopupMenuInfo; overload; virtual;
property Count: Integer read GetMenuInfoCount;
end;
TcxGridDefaultPopupMenu = class(TcxCustomGridPopupMenu)
protected
function GetPopupMenuInfo(const AMenu: TComponent; const AView: TcxCustomGridView;
ASearchDefault: Boolean = True): TcxPopupMenuInfo; overload; override;
procedure InternalRegisterPopupMenu(const AMenu: TComponent;
AHitTypes: TcxGridViewHitTypes; ADoPopupProc: TcxGridOnPopupProc;
AViewClass: TcxCustomGridViewClass; AIsBuiltIn: Boolean = False); virtual;
public
function GetPopupMenuInfo(const AMenu: TComponent; AViewClass: TcxCustomGridViewClass;
ASearchDefault: Boolean = True): TcxPopupMenuInfo; overload; override;
procedure RegisterPopupMenu(const AMenu: TComponent; AHitTypes: TcxGridViewHitTypes;
ADoPopupProc: TcxGridOnPopupProc; AViewClass: TcxCustomGridViewClass); virtual;
procedure UnRegisterPopupMenu(const AMenu: TComponent; AViewClass: TcxCustomGridViewClass;
AHitTypes: TcxGridViewHitTypes = []); virtual;
property MenuInfos;
end;
TcxPopupMenuClass = class of TComponent;
TcxPopupMenuClassInfoRec = class
public
MenuClass: TcxPopupMenuClass;
HitTypes: TcxGridViewHitTypes;
ViewClass: TcxCustomGridViewClass;
constructor Create(AMenuClass: TcxPopupMenuClass; AHitTypes: TcxGridViewHitTypes;
AViewClass: TcxCustomGridViewClass);
end;
TcxBuiltInPopupMenus = class
private
FInfoRecs: TList;
function GetCount: Integer;
function GetItem(AIndex: Integer): TcxPopupMenuClassInfoRec;
protected
function Add(AMenuClass: TcxPopupMenuClass; AHitTypes: TcxGridViewHitTypes;
AViewClass: TcxCustomGridViewClass): TcxPopupMenuClassInfoRec;
procedure Clear;
procedure Delete(AIndex: Integer);
procedure RegisterItemTo(ADefaultPopupMenu: TcxGridDefaultPopupMenu;
AItemIndex: Integer);
procedure Remove(APopupMenuClass: TcxPopupMenuClass);
property Count: Integer read GetCount;
property Items[AIndex: Integer]: TcxPopupMenuClassInfoRec read GetItem; default;
public
constructor Create;
destructor Destroy; override;
procedure RegisterItemsTo(ADefaultPopupMenu: TcxGridDefaultPopupMenu);
end;
function GetHitTypeByHitCode(AHitCode: Integer): TcxGridViewHitType;
procedure RegisterPopupMenuClass(APopupMenuClass: TcxPopupMenuClass;
AHitTypes: TcxGridViewHitTypes; AViewClass: TcxCustomGridViewClass);
procedure UnregisterPopupMenuClass(APopupMenuClass: TcxPopupMenuClass);
var
BuiltInPopupMenuList: TcxBuiltInPopupMenus;
implementation
uses
cxGridCustomTableView, cxGridTableView, Graphics, cxGridDetailsSite,
cxGridRows, cxGridBandedTableView, cxGridCardView, cxControls;
function GetHitTypeByHitCode(AHitCode: Integer): TcxGridViewHitType;
const
cxGridViewHitCodes: array[TcxGridViewHitType] of Integer = (htNone + cxhtGridBase,
htTab + cxhtGridBase, htNone, htTab, htCell, htExpandButton, htRecord, htNavigator,
htPreview, htColumnHeader, htColumnHeaderFilterButton, htFilter, htFooter, htFooterCell,
htGroupFooter, htGroupFooterCell, htGroupByBox, htIndicator, htRowIndicator,
htRowLevelIndent, htBand, htBandHeader, htRowCaption, htSeparator, htGroupSummary);
begin
for Result := Low(Result) to High(Result) do
if cxGridViewHitCodes[Result] = AHitCode then
Exit;
Result := TcxGridViewHitType(-1);
end;
{ TcxPopupMenuInfo }
procedure TcxPopupMenuInfo.BeginUpdate;
begin
FLocked := True;
end;
procedure TcxPopupMenuInfo.EndUpdate;
begin
FLocked := False;
end;
function TcxPopupMenuInfo.CanPopup(AHitTest: TcxCustomGridHitTest): Boolean;
var
APopupMenuIntf: IcxGridPopupMenu;
begin
if (PopupMenu <> nil) and Supports(PopupMenu, IcxGridPopupMenu, APopupMenuIntf) then
Result := APopupMenuIntf.CanPopup(AHitTest)
else
Result := True;
end;
procedure TcxPopupMenuInfo.DoChanged(const APopupMenu: TComponent;
const AView: TcxCustomGridView; AViewClass: TcxCustomGridViewClass);
var
AMenuInfo: TcxPopupMenuInfo;
MenuInfos: TcxPopupMenuInfos;
begin
AMenuInfo := nil;
if FLocked then exit;
MenuInfos := TcxPopupMenuInfos(Collection);
if Assigned(AView) then
AMenuInfo :=
TcxCustomGridPopupMenu(MenuInfos.GetOwner).GetPopupMenuInfo(APopupMenu, AView)
else
begin
if Assigned(AViewClass) and (MenuInfos.GetOwner is TcxGridDefaultPopupMenu) then
AMenuInfo :=
TcxGridDefaultPopupMenu(MenuInfos.GetOwner).GetPopupMenuInfo(APopupMenu, AViewClass);
end;
if (AMenuInfo <> nil) and (MenuInfos.GetOwner <> nil) and
not (csLoading in (MenuInfos.GetOwner as TComponent).ComponentState) then
Raise EcxGridPopupMenu.Create(
Format('This PopupMenuInfo is already registered. Index: %d',[AMenuInfo.Index]));
end;
function TcxPopupMenuInfo.FindCorrectComponent(const AComponent: TComponent): TComponent;
var
AOwner: TComponent;
begin
Result := AComponent;
if not Assigned(AComponent) then
Exit;
AOwner := TComponent(TcxPopupMenuInfos(Collection).GetOwner);
while AOwner.InheritsFrom(TcxCustomGridPopupMenu) do
AOwner := TcxCustomGridPopupMenu(AOwner).Owner;
with AOwner do
if (csUpdating in ComponentState) then
begin
Result := FindComponent(AComponent.Name);
if not Assigned(Result) or (Result.ClassType <> AComponent.ClassType) then
Result := AComponent;
end;
end;
procedure TcxPopupMenuInfo.SetPopupMenu(const AValue: TComponent);
begin
if FPopupMenu <> AValue then
begin
if (TcxPopupMenuInfos(Collection).GetSameMenuCount(FPopupMenu) = 1) and
(FPopupMenu <> nil) and not (csDestroying in FPopupMenu.ComponentState) then
FPopupMenu.RemoveFreeNotification(TComponent(TcxPopupMenuInfos(Collection).GetOwner));
DoChanged(AValue, FView, FViewClass);
if FIsBuiltIn then
begin
FIsBuiltIn := False;
FreeAndNil(FPopupMenu);
end;
FPopupMenu := AValue;
if FPopupMenu <> nil then
FPopupMenu.FreeNotification(TComponent(TcxPopupMenuInfos(Collection).GetOwner));
end;
end;
procedure TcxPopupMenuInfo.SetView(const AValue: TcxCustomGridView);
begin
if FView <> AValue then
begin
if Assigned(FView) and not (csDestroying in FView.ComponentState) then
FView.RemoveFreeNotification(TComponent(TcxPopupMenuInfos(Collection).GetOwner));
DoChanged(FPopupMenu, AValue, FViewClass);
FView := AValue;
if Assigned(FView) then
FView.FreeNotification(TComponent(TcxPopupMenuInfos(Collection).GetOwner));
end;
end;
procedure TcxPopupMenuInfo.SetViewClass(
const Value: TcxCustomGridViewClass);
begin
DoChanged(FPopupMenu, FView, Value);
FViewClass := Value;
end;
destructor TcxPopupMenuInfo.Destroy;
begin
if FIsBuiltIn then
FreeAndNil(FPopupMenu);
inherited Destroy;
end;
procedure TcxPopupMenuInfo.Assign(Source: TPersistent);
var
AMenuInfo: TcxPopupMenuInfo;
begin
if Source is TcxPopupMenuInfo then
begin
if Collection <> nil then
Collection.BeginUpdate;
try
BeginUpdate;
try
AMenuInfo := TcxPopupMenuInfo(Source);
Index := AMenuInfo.Index;
PopupMenu := FindCorrectComponent(AMenuInfo.PopupMenu);
OnPopup := AMenuInfo.OnPopup;
HitTypes := AMenuInfo.HitTypes;
GridView := TcxCustomGridView(FindCorrectComponent(AMenuInfo.GridView));
GridViewClass := AMenuInfo.GridViewClass;
finally
EndUpdate;
end;
finally
if Collection <> nil then
Collection.EndUpdate;
end;
end
else
inherited;
end;
{ TcxCustomGridPopupMenu }
constructor TcxCustomGridPopupMenu.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FPopupMenuInfos := TcxPopupMenuInfos.Create(Self);
end;
destructor TcxCustomGridPopupMenu.Destroy;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?