在没有WPF的扩展Glass Frame中绘制TextBox

我试图在我的表格的扩展玻璃框架上绘制一个TextBox。 我不会描述这种技术,它是众所周知的。 以下是那些没有听说过的人的例子: http : //www.danielmoth.com/Blog/Vista-Glass-In-C.aspx

问题是,绘制这个玻璃框架是很复杂的。 由于黑色被认为是0-alpha颜色,因此任何黑色都会消失。

显然有一些方法可以解决这个问题:绘制复杂的GDI +形状不受此alpha-ness的影响。 例如,此代码可用于在玻璃上绘制标签(注意:使用GraphicsPath代替DrawString以解决可怕的ClearType问题):

 public class GlassLabel : Control { public GlassLabel() { this.BackColor = Color.Black; } protected override void OnPaint(PaintEventArgs e) { GraphicsPath font = new GraphicsPath(); font.AddString( this.Text, this.Font.FontFamily, (int)this.Font.Style, this.Font.Size, Point.Empty, StringFormat.GenericDefault); e.Graphics.SmoothingMode = SmoothingMode.HighQuality; e.Graphics.FillPath(new SolidBrush(this.ForeColor), font); } } 

类似地,这种方法可用于在玻璃区域上创建容器。 请注意使用多边形而不是矩形 – 使用矩形时,其黑色部分被视为alpha。

 public class GlassPanel : Panel { public GlassPanel() { this.BackColor = Color.Black; } protected override void OnPaint(PaintEventArgs e) { Point[] area = new Point[] { new Point(0, 1), new Point(1, 0), new Point(this.Width - 2, 0), new Point(this.Width - 1, 1), new Point(this.Width -1, this.Height - 2), new Point(this.Width -2, this.Height-1), new Point(1, this.Height -1), new Point(0, this.Height - 2) }; Point[] inArea = new Point[] { new Point(1, 1), new Point(this.Width - 1, 1), new Point(this.Width - 1, this.Height - 1), new Point(this.Width - 1, this.Height - 1), new Point(1, this.Height - 1) }; e.Graphics.FillPolygon(new SolidBrush(Color.FromArgb(240, 240, 240)), inArea); e.Graphics.DrawPolygon(new Pen(Color.FromArgb(55, 0, 0, 0)), area); base.OnPaint(e); } } 

现在我的问题是:我如何绘制TextBox? 经过大量的谷歌搜索,我想出了以下解决方案:

  • 对TextBox的OnPaint方法进行子类化。 这是可能的 ,虽然我无法让它正常工作。 它应该包括画一些我不知道该怎么做的神奇的东西。
  • 制作我自己的自定义TextBox ,也许在TextBoxBase 。 如果有人有好的 ,有效的和有效的例子,并认为这可能是一个很好的整体解决方案,请告诉我。
  • 使用BufferedPaintSetAlpha 。 ( http://msdn.microsoft.com/en-us/library/ms649805.aspx )。 这种方法的缺点可能是文本框的角可能看起来很奇怪,但我可以忍受。 如果有人知道如何从Graphics对象中正确实现该方法,请告诉我。 我个人没有,但这似乎是迄今为止最好的解决方案。 说实话,我发现了一篇很棒的C ++文章,但是我太懒了转换它。 http://weblogs.asp.net/kennykerr/archive/2007/01/23/controls-and-the-desktop-window-manager.aspx

注意:如果我成功使用BufferedPaint方法,我发誓,我将制作一个简单的DLL,其中所有常见的Windows窗体控件都可以在玻璃上绘制。

我刚才在这个话题上花了一些时间。 基本上你需要的是一个透明的文本框。 我最初的方法是使用codeproject AlphaBlendTextBox – 一个透明/半透明的.NET文本框 。 但我有一些难以解决的问题。 过了一段时间我找到了所需的解决方案,它只适用于Windows XP及更高版本。 同样要使此控件的行为与单行文本框一样,将RichTextBox.Multiline设置为false。

 // Source: // http://www.dotnetjunkies.com/WebLog/johnwood/archive/2006/07/04/transparent_richtextbox.aspx // It seems there are 4 versions of the RichEdit control out there - when I'm talking about the // RichEdit control, I'm talking about the C DLL that either comes with Windows or some version // of Office. The files are named either RICHEDXX.DLL (XX is the version number), or MSFTEDIT.DLL // and they're in the System32 folder. // .Net RichTextBox control is bound to version 2. The biggest problem with this version (at least // for me) is that it does not render properly if you try to make the window transparent. Later versions, // however, do. // We can fix that. If you create a control deriving from the original RichTextBox control, but overriding // the CreateParams property, you can put in a new Windows class name (this is the window class name, // nothing to do with classes in the C# sense). This effectively gives us a free upgrade. When the .Net // RichTextBox control instantiates, it will now use the latest RichEdit control and not the old, archaic, // version 2. // There are other benefits too - version 3 and beyond of the RichEdit control support quite an extensive // array of layout features, such as tables and full text justification. This is the version of the RichEdit // that WordPad uses in Windows XP. To really see what it's capable of displaying you can create documents in // Word and save them in RTF, load these into the new RichEdit and in a lot of cases it'll look identical, // it's that powerful. A full list of features can be found here: // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/richedit/richeditcontrols/aboutricheditcontrols.asp // There are a couple of caveats: // // 1. The control that this is bound to was shipped with Windows XP, and so this code won't work in // Windows 2000 or earlier. // // 2. The RichTextBox control in C# only knows about version 2, so the interface doesn't include // all the new features. You can wrap a few of the features yourself through new methods on the // RichEdit class. using System; using System.Runtime.InteropServices; using System.Windows.Forms; internal class RichEdit : RichTextBox { [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private static extern IntPtr LoadLibrary(string lpFileName); protected override CreateParams CreateParams { get { CreateParams parameters = base.CreateParams; if (LoadLibrary("msftedit.dll") != IntPtr.Zero) { parameters.ExStyle |= 0x020; // transparent parameters.ClassName = "RICHEDIT50W"; } return parameters; } } }