gpt4 book ai didi

delphi - XE2 中的下拉菜单过高 "View"

转载 作者:行者123 更新时间:2023-12-02 01:51:14 25 4
gpt4 key购买 nike

历史上,Delphi 的 View 下拉列表包含大量项目。使用 Delphi XE2 加上几个必要的插件,这个数字变得稍大,几乎不适合我的屏幕高度。 Windows 支持的普通 TMainMenu 可以适应这种情况,并提供滚动或换行功能。不幸的是,看起来 RAD Studio 的主菜单是 TActionMainMenuBar,它无法处理这个问题。

我能用它做什么?请指教。如果我再添加一个创建“ View ”菜单项的加载项,它将开始重新定位下拉菜单并在释放鼠标时产生恶意点击。再多两三个项目就会有一个不可见的项目:-(

最佳答案

您可以尝试以下操作(将此单元添加到设计包中并将其安装在 IDE 中)。它找到 IDE 主窗体的 ActionManager 并将其样式设置为自定义样式,该样式为弹出菜单定义了一个新类。如果菜单项通常不适合屏幕,则此弹出菜单类会包装其菜单项:

Wrapping menu

unit TestUnit1;

interface

procedure InitializeStyle;

implementation

uses
System.Types, System.Classes, System.SysUtils,
Winapi.Messages, Winapi.Windows,
Vcl.GraphUtil, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ActnMan, Vcl.ActnMenus, Vcl.StdActnMenus, Vcl.ActnCtrls,
Vcl.PlatformDefaultStyleActnCtrls;

type
THackCustomActionMenuBar = class(TCustomActionMenuBar);

TStandardMenuPopupEx = class(TStandardMenuPopup)
protected
procedure AlignControls(AControl: TControl; var Rect: TRect); override;
procedure CustomAlignPosition(Control: TControl; var NewLeft, NewTop, NewWidth, NewHeight: Integer;
var AlignRect: TRect; AlignInfo: TAlignInfo); override;
procedure PositionPopup(AnOwner: TCustomActionBar; ParentItem: TCustomActionControl); override;
procedure WMKeyDown(var Message: TWMKey); override;
public
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
end;

TPlatformDefaultStyleActionBarsEx = class(TPlatformDefaultStyleActionBars)
public
function GetPopupClass(ActionBar: TCustomActionBar): TCustomPopupClass; override;
function GetStyleName: string; override;
end;

{ TStandardMenuPopupEx }

var
NextLeft, NextTop: Integer;

procedure TStandardMenuPopupEx.AlignControls(AControl: TControl; var Rect: TRect);
begin
NextLeft := 0;
NextTop := 0;
inherited AlignControls(AControl, Rect);
end;

procedure TStandardMenuPopupEx.CustomAlignPosition(Control: TControl; var NewLeft, NewTop, NewWidth, NewHeight: Integer;
var AlignRect: TRect; AlignInfo: TAlignInfo);
var
ScreenPos: TPoint;
begin
inherited CustomAlignPosition(Control, NewLeft, NewTop, NewWidth, NewHeight, AlignRect, AlignInfo);
NewLeft := NextLeft;
NewTop := NextTop;
NextTop := NewTop + NewHeight;

ScreenPos := ClientToScreen(Point(NewLeft, NewTop));
if ScreenPos.Y + NewHeight > Screen.MonitorFromPoint(ScreenPos).Height then
begin
NextTop := 0;
Inc(NextLeft, NewWidth);
end;
end;

procedure TStandardMenuPopupEx.PositionPopup(AnOwner: TCustomActionBar; ParentItem: TCustomActionControl);
var
Popup: TStandardMenuPopupEx;
begin
inherited PositionPopup(AnOwner, ParentItem);
if (ParentItem.Parent is TStandardMenuPopupEx) then
begin
Popup := TStandardMenuPopupEx(ParentItem.Parent);
if Assigned(Popup.Selected) and Assigned(Popup.Selected.Control) then
Left := Popup.ClientToScreen(Popup.Selected.Control.BoundsRect.BottomRight).X - 6;
end;
end;

procedure TStandardMenuPopupEx.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
ScreenPos: TPoint;
MonitorHeight: Integer;
begin
ScreenPos := ClientToScreen(Point(ALeft, ATop));
MonitorHeight := Screen.MonitorFromPoint(ScreenPos).Height;
if ScreenPos.Y + AHeight > MonitorHeight then
AHeight := MonitorHeight - ScreenPos.Y;

inherited SetBounds(ALeft, ATop, AWidth, AHeight);
if HandleAllocated then
RequestAlign;
end;

procedure TStandardMenuPopupEx.WMKeyDown(var Message: TWMKey);
var
NextPos: TPoint;
Sibling: TControl;
begin
case Message.CharCode of
VK_RIGHT:
if Assigned(Selected) and not Selected.HasItems and Assigned(Selected.Control) then
begin
NextPos := Point(Selected.Control.BoundsRect.Right + 1, Selected.Control.BoundsRect.Top);
Sibling := ControlAtPos(NextPos, False);
if Assigned(Sibling) then
begin
SelectItem(Sibling as TCustomActionControl);
Exit;
end;
end;
VK_LEFT:
if Assigned(Selected) and not Selected.HasItems and Assigned(Selected.Control) then
begin
NextPos := Point(Selected.Control.BoundsRect.Left - 1, Selected.Control.BoundsRect.Top);
Sibling := ControlAtPos(NextPos, False);
if Assigned(Sibling) then
begin
SelectItem(Sibling as TCustomActionControl);
Exit;
end;
end;
end;
inherited;
end;

{ TPlatformDefaultStyleActionBarsEx }

function TPlatformDefaultStyleActionBarsEx.GetPopupClass(ActionBar: TCustomActionBar): TCustomPopupClass;
begin
if ActionBar is TCustomActionToolBar then
Result := inherited GetPopupClass(ActionBar)
else
Result := TStandardMenuPopupEx;
end;

function TPlatformDefaultStyleActionBarsEx.GetStyleName: string;
begin
Result := 'Platform Default Ex (with wrapping menus)';
end;

function FindMainActionManager: TActionManager;
var
I: Integer;
begin
Result := nil;
if Assigned(Application) and Assigned(Application.MainForm) then
for I := 0 to Application.MainForm.ComponentCount - 1 do
if Application.MainForm.Components[I] is TActionManager then
begin
Result := TActionManager(Application.MainForm.Components[I]);
Break;
end;
end;

var
ExStyle: TPlatformDefaultStyleActionBarsEx = nil;

procedure InitializeStyle;
var
ActionManager: TActionManager;
begin
ActionManager := FindMainActionManager;
if Assigned(ActionManager) then
begin
ExStyle := TPlatformDefaultStyleActionBarsEx.Create;
ActionManager.Style := ExStyle;
end;
end;

procedure FinalizeStyle;
var
ActionManager: TActionManager;
begin
if not Assigned(ExStyle) then
Exit;
ActionManager := FindMainActionManager;
if Assigned(ActionManager) then
begin
ActionManager.Style := PlatformDefaultStyle;
FreeAndNil(ExStyle);
end;
end;

initialization
InitializeStyle;

finalization
FinalizeStyle;

end.

关于delphi - XE2 中的下拉菜单过高 "View",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12434408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com