当对表单类添加了对运行时DPI切换的支持时,没有考虑像菜单这样的基本UI元素.
菜单绘图从根本上被打破,因为它依赖于Screen.MenuFont,这是一个系统范围的度量,不是特定于监视器.因此,虽然表单本身可以相对简单地进行适当缩放,但是显示在其上的菜单只有在缩放恰好匹配加载到Screen对象中的任何度量标准时才能正常工作.
这是主菜单栏,弹出菜单和表单上所有弹出菜单的问题.如果将表单移动到具有与系统指标不同的DPI的监视器,则这些都不会缩放.
真正做到这一点的唯一方法是修复VCL.等待Embarcadero充实多DPI并不是一个真正的选择.
查看VCL代码,基本问题是Screen.MenuFont属性被分配给菜单画布,而不是选择适合显示菜单的监视器的字体.只需在VCL源代码中搜索Screen.MenuFont即可找到受影响的类.
在不必完全重写所涉及的类的情况下,解决此限制的正确方法是什么?
我的第一个倾向是使用绕行来跟踪菜单弹出窗口并在用于设置菜单时覆盖Screen.MenuFont属性.这似乎太过分了.
径向菜单已经开始出现在几个地方.我很好奇是否有人见过或正在研究Delphi的径向菜单组件?我们有一个我们想要的概念,在http://jmrsoftware.delaneyjoi.com/wheel.gif上的动画GIF中显示.(菜单动画启动大约需要10秒钟.)
alt text http://jmrsoftware.delaneyjoi.com/wheel.gif
有没有人知道具有类似功能的Delphi组件?
谢谢
由于在Delphi中出现了匿名方法,我想在VCL组件事件中使用它们.显然,为了向后兼容,VCL没有更新,所以我设法做了一个简单的实现,但有几点需要注意.
type
TNotifyEventDispatcher = class(TComponent)
protected
FClosure: TProc<TObject>;
procedure OnNotifyEvent(Sender: TObject);
public
class function Create(Owner: TComponent; Closure: TProc<TObject>): TNotifyEvent; overload;
function Attach(Closure: TProc<TObject>): TNotifyEvent;
end;
implementation
class function TNotifyEventDispatcher.Create(Owner: TComponent; Closure: TProc<TObject>): TNotifyEvent;
begin
Result := TNotifyEventDispatcher.Create(Owner).Attach(Closure)
end;
function TNotifyEventDispatcher.Attach(Closure: TProc<TObject>): TNotifyEvent;
begin
FClosure := Closure;
Result := Self.OnNotifyEvent
end;
procedure TNotifyEventDispatcher.OnNotifyEvent(Sender: TObject);
begin
if Assigned(FClosure) then
FClosure(Sender)
end;
end.
Run Code Online (Sandbox Code Playgroud)
以下是它的用法:
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.OnClick := TNotifyEventDispatcher.Create(Self,
procedure (Sender: TObject)
begin
Self.Caption := 'DONE!'
end)
end;
Run Code Online (Sandbox Code Playgroud)
我相信很简单,有两个缺点:
我必须创建一个组件来管理匿名方法的生命周期(我浪费了更多的内存,对于间接方式来说它有点慢,我仍然希望在我的应用程序中更清晰的代码)
我必须为每个事件签名实现一个新类(非常简单).这个有点复杂,VCL仍然有非常常见的事件签名,而且对于我创建类的每一个特殊情况,它都是永远完成的. …
要求TComponent作为所有者来实例化某种对象似乎完全无关紧要.为什么有这么多Delphi组件需要这个?
例如,TXMLDocument需要TComponent对象来实例化.
为什么会这样,如果有充分的理由,我应该在那里使用"做正确的事"?
我正在使用VCL控件在Borland C++ Builder IDE中工作.我试图让一个TStringGrid组件向下滚动到一行,并根据不同形式的用户输入突出显示该行.我完成了高亮部分,但我无法弄清楚如何将网格向下滚动到正确的行.这里有人知道吗?
我需要将VCL组件从32位转换为64位(Delphi XE2).现在我只能在选择"32位平台"时安装它,如果我选择"64位平台"我可以编译但不安装(没有安装菜单).如何添加64位支持并将其安装到64位应用程序中?
I'm looking for some code allowing easy asigning many event handlers to a single event of object... I needed it very much for my plugin architecture, so I implemented some replacement for that, however I don't like my solution for that, so I'd like to know what is yours idea/solution/tip ... My solution is just a list with items like
eventName: string;
proc: TMyEventProc;
where TMyEventProc takes two arguments, sender and eventData: pointer.
depending on name of the event, eventData …
我能走远路,遍历每一行,获得了TRect从CellRect(col, row),然后查询其State为gdSelected...
但是,有没有更快的方法来获取当前所选行的行号,如果有的话?
Delphi 2010,Win32 VCL.我需要以最标准的外观为我的应用程序创建一个主菜单.TMainMenu在所有Windows版本中看起来都不错,唯一不好的是当它显示具有Enabled = False的项目的图像时.
Delphi有一些奇怪的方法来构建禁用的图像(使用斜面进行b/w挤出,对我来说它看起来像是喷出).我想在VCL源代码中为该过程制作一个补丁,让菜单从同一个TImageList中选择禁用的图像,但我找不到它.
它是否存在或者是一些标准的Windows API调用?你知道那个程序在哪里吗?
当然OwnerDraw风格可以修复所有这些,但我想要更快的解决方案.
昨天我发现了一个键盘ShortCut在我期待它时没有发射的情况.
具体情况是:我在MDI子项上按下了ShortCut键组合以获取ActionList的Action,同时聚焦了MDI表单上的侧栏.
我一直认为ShortCuts可以在全球范围内运作.在哪种情况下,他们不会开火?
delphi ×10
vcl ×10
c++builder ×2
menu ×2
tstringgrid ×2
64-bit ×1
components ×1
delphi-2010 ×1
delphi-xe2 ×1
dpi ×1
events ×1
menuitem ×1