2010-05-29 96 views
0

我想在窗體的擴展玻璃框上繪製文本框。我不會描述這種技術,這是衆所周知的。以下是一些沒有聽說過的例子:http://www.danielmoth.com/Blog/Vista-Glass-In-C.aspx在沒有WPF的擴展玻璃框中繪製文本框

問題是,畫這個玻璃框很複雜。由於黑色被認爲是0-alpha顏色,黑色消失。

有明顯的方法來解決這個問題:繪製複雜的GDI +形狀不受這個alpha-ness的影響。例如,該代碼可以被用來繪製在玻璃上的標籤(注:GraphicsPath爲了避開可怕的ClearType問題是用來代替DrawString):

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); 
    } 
} 

現在我的問題是:如何繪製文本框? 經過大量的谷歌搜索,我想出了以下解決方案:

  • 子類文本框的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方法成功了,我發誓S/O,我會做一個簡單的DLL與所有常見的Windows窗體控件可繪製在玻璃上。

+0

回答自己在另一個線程:http://stackoverflow.com/questions/7061531/rendering-controls-on-glass-solution-found-needs-double-buffering-perfecting – Lazlo 2012-01-12 04:54:23

回答

0

前段時間我在這個話題上花了一些時間。基本上你需要的是一個透明的文本框。我最初的做法是使用codeproject AlphaBlendTextBox - A transparent/translucent textbox for .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; 
     } 
    } 
} 
+0

這是在玻璃完全透明- 沒有用。我寧願希望有些不透明的東西。 – Lazlo 2010-05-31 23:57:35

+0

@Lazlo你可以放任何背景漸變背景 – volody 2010-06-01 01:25:17