Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Delphi Tokyo突出显示主题Delphi应用程序中的控件_Delphi_Winapi_Themes - Fatal编程技术网

使用Delphi Tokyo突出显示主题Delphi应用程序中的控件

使用Delphi Tokyo突出显示主题Delphi应用程序中的控件,delphi,winapi,themes,Delphi,Winapi,Themes,使用Delphi Tokyo 10.2,具有样式化主题。我试图突出显示表单上的组件,例如,组合框,编辑文本,等等。例如,如果用户输入了无效数据,我希望突出显示该组件 在过去,我们只将组件涂成红色,通常通过调整大小/移动/重新绘制来保持颜色。现在有了主题化,我们需要做更多的工作来让颜色显示和保持 我已尝试禁用每个组件的样式元素[seFont,seClient,seBorder]属性以强制显示颜色。这是可行的,但似乎很困难,特别是当有许多组件正在验证时。此外,简单地将组件涂成红色可能与某些主题不符

使用Delphi Tokyo 10.2,具有样式化主题。我试图突出显示表单上的组件,例如,
组合框
编辑文本
,等等。例如,如果用户输入了无效数据,我希望突出显示该组件

在过去,我们只将组件
涂成红色
,通常通过调整大小/移动/重新绘制来保持颜色。现在有了主题化,我们需要做更多的工作来让颜色显示和保持

我已尝试禁用每个组件的
样式元素[seFont,seClient,seBorder]
属性以强制显示颜色。这是可行的,但似乎很困难,特别是当有许多组件正在验证时。此外,简单地将组件涂成红色可能与某些主题不符

我还尝试使用
WinAPI SetRop2(..)
简单地在组件周围绘制一个红色矩形。例如,是一些聪明的代码,我调整了一下,在它周围画了一个
TWinControl
Draw
a
redbox
;我还可以使用类似的调用来删除
红色框
。这项工作:

…但很明显,在重新油漆的过程中不会持续。在这里添加自定义绘制方法似乎有点过头了。除非有更好的办法

我考虑过的其他事项:

所有组件都位于面板上,我考虑过使用受保护的黑客在面板画布上围绕组件绘制红色
rect
s,但同样,还有更多自定义绘制例程

我也在考虑根据需要动态绘制
t形状
,但这让我觉得很愚蠢

在同样的情况下,肯定还有其他情况,例如,数据输入验证在旧版本的Delphi中工作得很好,但在主题化时看起来不太好。使用主题的最佳方法是什么?
SetRop2(…)
方法似乎是最干净的,但是有人能建议一种简单的方法来保持颜色吗?我也欢迎其他想法。多谢各位

编辑 因此,也许仅仅动态地在无效响应周围绘制
t形状就没那么糟糕了。它们通过重新绘制保持不变,并且不会从
TWinControl
下降,这意味着它们会自动显示在它们高亮显示的控件后面

这对我来说非常有效,我希望它对其他人有帮助

// assuming owning control will be free'd properly and 
// will in turn free HI_LITE Box.
// 
// tantamount to adding an instance variable, TShape, to existing Control,
// since class helpers don't allow. And I don't want to descend 
// new controls just to have a hiLiteBox Instance Variable.

procedure HiLiteMe(aControl : TWinControl; HILITE_FLAG : Boolean = TRUE; aColor : TColor = clRed);
const OFFSET = 4;                         // specify the offset of the border size of the box.
const BOX_NAME_PREFIX = 'HI_LITE_BOX_';

var
   hiLiteBox : TShape;      // reference created on stack, but object created on the heap,
   uniqueBoxName : String;    // so use the persistent aControl's owned component list to maintain the reference.
begin
  uniqueBoxName := BOX_NAME_PREFIX + aControl.Name;              // uniquename for each associated HiLiteBox.
  HiLiteBox := aControl.FindComponent(uniqueBoxName) as TShape;  // phishing for the HiLiteBox if it was previously created.

  if NOT Assigned(hiLiteBox) then         // create HiLiteBox and make persist outside this proc.
  begin
    if NOT HILITE_FLAG then exit;         // don't create a box if we're just going to hide it anyway.
    hiLiteBox := TShape.Create(aControl); // Create HiLiteBox, setting aControl as owner, quicker retrieval using aControl.findComponent
    hiLiteBox.Parent := aControl.Parent;  // Render the box on the control's parent, e.g., panel, form, etc.
    hiLiteBox.Name :=  uniqueBoxName;
    hiLiteBox.Pen.Color := aColor;        // Color the Pen
    hiLiteBox.Pen.Width := offset-1;      // Make the Pen just slightly smaller than the offset.
    hiLiteBox.Brush.Color := clWindow;    // Choose a brush color, to fill the space between the pen and the Control
    hiLiteBox.Left := aControl.Left - offset;
    hiLiteBox.Width := aControl.Width + offset*2;
    hiLiteBox.Top := aControl.Top - offset;
    hiLiteBox.Height := aControl.Height + offset*2;
  end;

  hiLiteBox.Visible := HILITE_FLAG; // Show/Hide HiLite as appropriate.
end;
像这样用一个红蓝相间的盒子叫HiLite

begin
  HiLiteMe(checkListBox1, TRUE, clRed);   // Draw a RedBox around the CheckListBox, e.g., Invalid.
  HiLiteMe(bitBtn3, TRUE, clBlue);        // Draw a Blue Box around the Button, e.g., Required.
end;

这样调用可以删除
HiLites

begin
  HiLiteMe(checkListBox1, FALSE);   // Draw a RedBox around the CheckListBox, e.g., Invalid.
  HiLiteMe(bitBtn3, FALSE);        // Draw a Blue Box around the Button, e.g., Required.
end;

我建议只在控件的一侧(例如,左侧或底部)显示或隐藏红色t形状。

不要使用VCL样式。使用本机Win32外观。从技术上讲,VCL样式从一开始就是一种黑客行为。不推荐使用它们,尤其是生产软件。它的整个工作原理是脆弱的,应该尽可能避免。另一方面,您说重新绘制会覆盖您的图形。当然,如果不在控件的
OnPaint
事件或
WM_paint
Windows消息中绘制它,它会这样做。“必须有其他人处于相同的情况…”-可能。。。“.data entry validation在旧版本中工作得很好…”“data entry validation不需要任何提示,您可以通过提示或对话框弹出消息,并将焦点放在具有无效条目的控件上。再加上Andreas的建议,它可能会成为一个轻松的应用程序。@AndreasRejbrand用户真的想要Sapphire Kamri主题,所以我恐怕无法接受这个主题。这很好,真的。SertacAkyuz感谢这些想法,不幸的是,用户会发现一个弹出对话框/提示/将焦点设置为罪犯后退了一步。这是他们以前所拥有的。表单是使用WinTablet和笔输入的所有数据。我真的很想用SetRop2和otw找到一个好的解决方案,我只需要切换StyleElements。[seClient]。再次感谢您。当您知道不会有任何中断时,您将执行rop操作。拖动时的公用。。。F.i.你正在画一个行进中蚂蚁的选择矩形,你知道只有当你从鼠标下移回来时,才能处理任何绘画信息。即使如此,一些应用程序从地下突然弹出一条最重要的消息也并不罕见,超过一半的蚂蚁在它消失后留下了人工制品。无论如何,这不太适合你的场景。