自行实现透明的控件如Panel GroupBox(使用不需要重绘父控件的效果,一切都因为窗口有了WS_EX_TRANSPARENT属性)

CSDN的Blog开通了。我想这里的Blog作为今后自己回答别人问题的时候,收藏答案的地方很不错呢。

因为社区的贴子早晚都会沉下去,查找起来很不方便,甚至再也找不到呢。

Q: http://community.csdn.net/Expert/TopicView.asp?id=3106090

言归正传,要实现一些标准的容器类控件的透明效果,也许是个经常会想到的问题。事实上在2000以上的系统下实现起来相当容易。

你不需要重绘父控件的效果,一切都因为窗口有了WS_EX_TRANSPARENT的属性可以选择。

下面我们就以TPanel和TGroupBox控件来说明。我们从它们继承两个新的控件,TTransPanel和TTransGroupBox。

class TTransPanel :public TPanel
{
  void __fastcall CreateParams(Controls::TCreateParams &Params)
  {
    TPanel::CreateParams(Params);
    Params.ExStyle += WS_EX_TRANSPARENT;
  }
  void __fastcall AdjustColors(TPanelBevel Bevel,TColor& TopColor,TColor& BottomColor)
  {
    TopColor = clBtnHighlight;
    if (Bevel == bvLowered) TopColor = clBtnShadow;
    BottomColor = clBtnShadow;
    if (Bevel == bvLowered) BottomColor = clBtnHighlight;
  }
  void __fastcall Paint()
  {
    DynamicArray<int> Alignments;
    Alignments.set_length(3);
    Alignments[taLeftJustify] = DT_LEFT;
    Alignments[taCenter] = DT_CENTER;
    Alignments[taRightJustify] = DT_RIGHT;
    TRect Rect;
    TColor TopColor, BottomColor;
    int FontHeight;
    Longint Flags;
    Rect = GetClientRect();
    if (BevelOuter != bvNone)
    {
      AdjustColors(BevelOuter,TopColor, BottomColor);
      Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
    }
    Frame3D(Canvas, Rect, Color, Color, BorderWidth);
    if (BevelInner != bvNone)
    {
      AdjustColors(BevelInner,TopColor, BottomColor);
      Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
    }
    Canvas->Brush->Color = Color;
//    Canvas->FillRect(Rect); 注释掉这一句,就透明了。下面的bsClear保证写Caption的不使用底色。
    
Canvas->Brush->Style = bsClear;
    Canvas->Font = this->Font;
    FontHeight = Canvas->TextHeight(‘W‘);

Rect.Top = ((Rect.Bottom + Rect.Top) - FontHeight) / 2;
    Rect.Bottom = Rect.Top + FontHeight;
    Flags = DT_EXPANDTABS | DT_VCENTER | Alignments[Alignment];
    Flags = DrawTextBiDiModeFlags(Flags);
    DrawText(Canvas->Handle, Caption.c_str(), -1, &Rect, Flags);
  }
public:
  __fastcall virtual TTransPanel(TComponent* AOwner):TPanel(AOwner)
  {
    ControlStyle >> csOpaque;
    Width  = 185;
    Height = 41;
  }
};

https://blog.csdn.net/cker/article/details/24110

原文地址:https://www.cnblogs.com/findumars/p/8877257.html

时间: 2024-08-28 23:16:20

自行实现透明的控件如Panel GroupBox(使用不需要重绘父控件的效果,一切都因为窗口有了WS_EX_TRANSPARENT属性)的相关文章

Android 设置子控件的宽度或高度为 match_parent来填充父控件中的剩余宽度或高度的方法

先上几张效果图, 如下:          上述四张图要实现的布局效果是: 假如父控件中包含两个子控件, 其中一个子控件(上图中为红色button)的宽度是固定数值, 而另一个子控件(上图中为绿色button)的宽度不固定, 要想让这两个子控件的总宽度刚好等于父控件的宽度.可以将宽度不固定的那个控件的宽度设置为match_parent来实现, 但有些细节需要注意, 否则即使设置了match_parent, 也不能出现如上的效果. 注意细节如下: 上述效果可以使用RelativeLayout实现.

五种情况下会刷新控件状态(刷新所有子FWinControls的显示)——从DFM读取数据时、新增加子控件时、重新创建当前控件的句柄时、设置父控件时、显示状态被改变时

五种情况下会刷新控件状态(刷新控件状态才能刷新所有子FWinControls的显示): 在TWinControls.PaintControls中,对所有FWinControls只是重绘了边框,而没有整个重绘这些FWinControl子控件.那么什么时候才整个重绘全部FWinControls呢?这时候,就不是一个单纯的WM_PAINT来解决控件重绘的问题了,而是这个TWinControl.UpdateShowing函数: procedure TWinControl.UpdateShowing; v

控件重绘

1. 设置控件DrawMode属性为OwnerDrawFixed,编辑控件DrawItem事件 重绘tabControl--选项卡控件 string text = ((TabControl)sender).TabPages[e.Index].Text; SolidBrush brush = new SolidBrush(Color.Black); StringFormat sf = new StringFormat(StringFormatFlags.DirectionRightToLeft);

为什么日历控件放在panel无法显示出来

前言 以前一直没有做过c/s这块开发,最近一段时间,刚接触.当然winform自己肯定会,但是只是很早以前自己玩的时候弄弄.最近做的时候,很简单的一个效果,自己怎么也实现不出来,最后没事和一个哥们私下弄得时候发现了奥妙,哈哈,可能大家做过winform的都知道,但是还是分享一下. 需求 form窗体上,放一个groupbox控件,放一个datagridview控件,放一个panel控件.groupbox中放一个textbox控件,dock属性为top,panel中放一个日历控件,gridview

深入Windows窗体原理及控件重绘技巧

之前有学MFC的同学告诉我觉得Windows的控件重绘难以理解,就算重绘成功了还是有些地方不明白,我觉得可能很多人都有这样的问题,在这里我从Windows窗体的最基本原理来讲解,如果你有类似的疑惑希望这篇文章可以帮你解惑. 1.Windows窗体原理 首先,如果看过Win32 SDK编程的都知道Windows的三大核心系统:负责窗口对象产生和消息分发的USER模块,负责图像显示绘制的GDI模块,负责内存.进程.IO管理的KERNEL模块.试想象一下如何在一个像素阵列上产生窗口对象,其实就是使用G

Android开发之解决父控件拦截子控件事件问题

以ViewPager为例: 1 public class TopNewsViewPager extends ViewPager { 2 public TopNewsViewPager(Context context) { 3 super(context); 4 } 5 6 public TopNewsViewPager(Context context, AttributeSet attrs) { 7 super(context, attrs); 8 } 9 10 //重写这个方法,并且在方法里面

父控件、子控件

1 每一个控件其实都是一个容器可以将其他控件放到该控件的内部比较常见的还是将UIView作为容器 2 可以将A控件放入B控件A控件是B控件的子控件B控件是A控件的父控件 3 每一个控制器都有一个UIView控制器本身是不可见能够看到的是控制器的View每一个控制器中都一个UIVIew的属性控制器中管理的所有子控件都是该控件的子控件

C#在某个线程上创建的控件不能成为在另一个线程上创建的控件的父级

首先在form1的窗体载入中新建了一个Class1对象并将本身的引用传递进入其构造函数,然后在Class1的构造函数中创建一个线程.该线程所代理的方法事件是本类中的一个add方法.而add方法的内容则是在form1上放一个textbox.然而这个流程你需要注意的有几个问题:1.哪个是主线程?所谓主线程是第一个启动的线程,是从main开始的.form1的这个窗体是由主线程创建的.2.Thread t的线程是什么?t是由主线程创建的,t的操作内容是在由主线程创建的窗体上放一个textbox.也就是说

事件委托应用:在父控件中创建子控件,并接收值

传值过程使用委托方法 定义一个打开按扭,一个文本框 1 /// <summary> 2 /// 增加父控件 3 /// </summary> 4 public void AddParent(BaseControl ctl) 5 { 6 foreach (Control ct2 in this.Parent.Controls) 7 { 8 if (ct2.Name == ctl.Name) { 9 ct2.Focus(); 10 return; 11 } 12 } 13 ctl.Wi