delphi – TActionMainMenuBar和TActionToolbar丢失设置
我最近偶然发现了一个非常奇怪的行为.当我在程序中使用TActionMainMenuBar(或TActionToolBar),编译并运行,然后启动Photoshop CS5或Internet Explorer 9时,ActionMainMenuBar(和ActionToolBar)将丢失其所有设置.指定的色彩映射中定义的颜色消失,字体设置也会丢失.有没有人见过这个,知道一个解决方法?
D2007 Pro(所有更新均已应用),D2010 Pro(已应用所有更新),Vista Home Premium 32位,NVidia GForce 8600 GT,最新驱动程序已安装. 重现步骤: >在表单上删除TActionManager和TActionMainMenuBar 如果您先启动Photoshop或IE,然后再启动Delphi程序,则不会发生任何事情.在IDE中的设计模式下,该错误也存在.一位开发人员已经使用Win7 Pro 32bit和ATI Radeon 9800 Pro确认了他所描述的系统行为. Thx任何评论/解决方案 菲尔 PS:使用Photoshop CS3不会产生此错误 解决方法
这是另一种再现问题的方法:
>完成问题中的步骤1到4(包括删除TwilightColorMap). 所以现在我们知道WM_SETTINGCHANGE广播可能会导致问题,我们可能想知道启动IE是否会产生相同的问题: type TForm1 = class(TForm) .. protected procedure WMSettingChange(var Message: TWMSettingChange); message WM_SETTINGCHANGE; .. procedure TForm1.WMSettingChange(var Message: TWMSettingChange); begin Memo1.Lines.Add(IntToHex(Message.Flag,4) + ',' + Message.Section); inherited; end; 在我们运行我们的应用程序然后启动IE之后,几秒钟后,备忘录中出现以下内容:
我不知道IE在每次发布时对我们的表格(以及所有其他顶级窗口)都要说什么,我不知道它是在地球上的每个Windows机箱上还是仅仅是你自己和我的,但显然ActionMainMenuBaris不擅长处理它. 接收WM_WININICHANGE的获胜控件(表单)执行CM_WININICHANGE,并在接收到它时将其广播到其所有控件.以下是菜单栏的处理方式: procedure TCustomActionMainMenuBar.CMWininichange(var Message: TWMWinIniChange); begin inherited; RequestAlign; Font.Assign(Screen.MenuFont); end; 认为系统菜单字体可能已被更改(代码应该在消息中查找’WindowsThemeElement’或’WindowMetrics’部分,但无论如何..),它将从刷新的Screen.MenuFont重新分配.问题是,我们并没有完全使用它. 此外,ColorMap通过调用其UpdateColors方法重置其颜色来响应CM_WININICHANGE.这甚至是documented:
所以解决方案将涉及决定做什么和覆盖两种行为,我试图评论下面的解决方案,为什么我认为这将是正确的解决方案: type // Derive your own ColorMap that would reset its own colors. // This is an interposer for simplicity.. TTwilightColorMap = class(actncolormaps.TTwilightColorMap) public procedure UpdateColors; override; published property Color default clGreen; property FontColor default clYellow; property MenuColor default $4488FF; // reintroduce as many property as necessary,probably all is necessary.. end; TForm1 = class(TForm) .. private FSaveMenuFont: TFont; // will hold initial main menu bar's font settings protected procedure WMSettingChange(var Message: TWMSettingChange); message WM_SETTINGCHANGE; end; .. procedure TForm1.FormCreate(Sender: TObject); begin FSaveMenuFont := TFont.Create; FSaveMenuFont.Assign(ActionMainMenuBar1.Font); end; procedure TForm1.FormDestroy(Sender: TObject); begin FSaveMenuFont.Destroy; end; procedure TForm1.WMSettingChange(var Message: TWMSettingChange); begin inherited; // The below are the *section*s that really changing system settings // would notify that I'm aware of,there may be more... if (Message.Section <> 'WindowsThemeElement') or (Message.Section <> 'WindowMetrics') then ActionMainMenuBar1.Font.Assign(FSaveMenuFont) else // Develop your logic here. The system menu font might really have been // changed. You can get it from Screen.MenuFont. But then if we had been // using the system font,the control already applies the change by default. end; procedure TTwilightColorMap.UpdateColors; begin inherited; // Reset your colors,note that system colors might have been // changed or not. If changed,they should be reflected in 'cl..' constants. Color := clGreen; FontColor := clYellow; MenuColor := $4488FF; end; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |