问题: Panel 控件在使用了 XPtheme 后背景色没了 ...
解决方法有四: 1、使用 TShape 带颜色覆盖在 panel 的表面 2、修改 ExtCtrls.pas 得 1778 行,忽略对 Themes 的判断 3、先设置 panel 的 ParentBackground 为 True,再设置回去 4、修改 ExtCtrls.pas 的 262 行为: property ParentBackground { stored FParentBackgroundSet }; 总体的,方法 3 的改动最少,不过每次都要这样弄一下 ... 论述: 在设计期、运行期,没有使用 windows xp theme 样式(引用 XpMan 单元): 而使用了 xp 样式后的设计期、运行期: 使用 xp theme 后 panel 竟然变得透明了! 查看源码: procedure TCustomPanel.Paint; 得实现: 其中 ExtCtrls.pas 得 1778 行决定背景得画法: if not ThemeServices.ThemesEnabled or not ParentBackground then begin Brush.Color := Color; FillRect(Rect); end; 解决办法 1:直接把 not ThemeServices.ThemesEnabled 砍掉,定成 True,不过似乎暴力些 解决办法 2:设置 ParentBackground 属性为 False 就可以了,=^0^= so easy 可是查看属性,傻眼了:ParentBackground 属性已经是 False 了: 单步看 TCustomPanel.Paint 得运行,此时得 ParentBackground 却是 True! 查找 GetParentBackground 得实现代码: function TWinControl.GetParentBackground: Boolean; begin Result := csParentBackground in ControlStyle; end;
而 csParentBackground 只有在 procedure TWinControl.SetParentBackground(Value: Boolean); 中才被设置:其中在 TCustomPanel 中被 override 了: procedure TCustomPanel.SetParentBackground(Value: Boolean); begin { TCustomPanel needs to not have csOpaque when painting with the ParentBackground in Themed applications } if Value then ControlStyle := ControlStyle - [csOpaque] else ControlStyle := ControlStyle + [csOpaque]; FParentBackgroundSet := True; inherited; end; 注意到那个 FParentBackgroundSet 变量,他标记用户是否设置了 ParentBackground,干什么用的?: 在 ExtCtrls.pas 的 262 行: property ParentBackground stored FParentBackgroundSet; 原来 ParentBackground 只有当用户设置了 ParentBackground 后才流化到 dfm 中的,为了验证,查看 dfm 流化: 原使的(没有流化 ParentBackground 属性,此时 ParentBackground 为 True,不过再设计器没有表现出来,而是默认的 False): object Panel1: TPanel Left = 8 Top = 8 Width = 218 Height = 245 Caption = 'Panel1' Color = clGreen TabOrder = 0 end 设置 panel 的 ParentBackground 为 True,再设置回去,此时应该与上面的“一摸一样”,可是: object Panel1: TPanel Left = 8 Top = 8 Width = 218 Height = 245 Caption = 'Panel1' Color = clGreen ParentBackground = False TabOrder = 0 end
此时运行,一切正常 :)

|