delphi 利用TPopupMenu做一个更换主题的功能

效果图:

核心代码:

use
  Vcl.Themes;


procedure TForm1.FormCreate(Sender: TObject);
var
i:integer; popItem:TMenuItem; begin
//动态生成右键菜单与绑定事件
//TStyleManager样式管理器,不用声明.TStyleManager.StyleNames 返回一个皮肤数组. for i := Low(TStyleManager.StyleNames) to High(TStyleManager.StyleNames) do begin popItem := TMenuItem.Create(PopupMenu1); //定义一个菜单 popItem.Caption := TStyleManager.StyleNames[i]; //赋值 popItem.OnClick := SelectTheme; //绑定事件 PopupMenu1.Items.Add(popItem); // 创建菜单 end; end;

//自定义过程SelectTheme
procedure TForm1.SelectTheme(sender: TObject); var ThemeName: string; begin ThemeName := (sender as TMenuItem).Caption;  //取得点击菜单的caption ThemeName := StringReplace(ThemeName, '&', '', [rfReplaceAll]); //这一步很重要. TStyleManager.TrySetStyle(ThemeName);  //设置主题 这里有个坑,留到最后讲 end;

请注意上面一行红色的代码,其作用是把字符串中的 & 符号替换为空.如果没有这一行,就会出现如下错误

 

可能有些朋友不知道为什么要替换,提示信息上明明说的是"Luna"主题没有找到,跟替换&符号好像没什么关系.

这里要科普一下D里面的一些规则:

请留意下图中底部带下划线的字母.在D的菜单设置规则里,caption属性里面的&+字母表示设置快捷方式,比如第一行的windows,它的caption实际上是 : &Windows,又如第三行,它实际为: L&gua Light Slate

所以,现在再回才头去看那个出错信息,就明白里面的意思了吧.

解决方案:

  选中TPopupMenu,设置AutoHotKeys为maManual,禁止自动设置热键即可

 

填坑:

1.问题描述:当用户进行主题切换时,可能会发生错误

2.原因分析:主题切换时会触发onShowg事件,所以可以想象到,主题切换它其实是对窗体的重绘,当窗体没有显示出来时,是不能保持原有焦点的,所以才会产生错误(小白的个人见解)

 

 3.解决方案: 切换前,设置焦点为nil

FocusControl(nil);
TStyleManager.TrySetStyle(ThemeName);  //设置主题

感谢群里大佬的指点:

 

 

  

 

 


 

posted @ 2022-10-06 19:29  一曲轻扬  阅读(291)  评论(0)    收藏  举报