2010-05-29 2 views
0

Я пытаюсь нарисовать TextBox на расширенной стеклянной рамке моей формы. Я не буду описывать эту технику, это хорошо известно. Вот пример для тех, кто этого не слышал: http://www.danielmoth.com/Blog/Vista-Glass-In-C.aspxРисование TextBox в расширенной стеклянной рамке без WPF

Дело в том, что сложнее нарисовать эту стеклянную рамку. Поскольку черный считается 0-альфа-цветом, все черное исчезает.

Есть, по-видимому, способы противодействия этой проблеме: эта формальность не влияет на рисование сложных форм GDI +. Например, этот код может быть использован, чтобы сделать метку на стекло (примечание: 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); 
    } 
} 

Аналогичным образом, такой подход может быть использован для создать контейнер на площади стекла. Обратите внимание на использование полигонов вместо прямоугольника - при использовании прямоугольника его черные части рассматриваются как альфа.

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? После большого количества Googling, я пришел со следующими растворами:

  • подклассов OnPaint метод текстового поля в. Это возможно, хотя я не мог заставить его работать правильно. Это должно включать в себя рисование некоторых магических вещей, которые я не знаю, как это сделать.
  • Изготовление на заказ TextBox, возможно, на TextBoxBase. Если у кого есть good, действительные и рабочие примеры, и думает, что это может быть хорошим общим решением, пожалуйста, скажите мне.
  • Использование 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 Forms рисуем на стекле.

+0

Ответил себя в другом потоке: http://stackoverflow.com/questions/7061531/rendering-controls-on-glass-solution-found-needs-double-buffering-perfecting – Lazlo

ответ

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

+0

@ Lazlo Вы можете разместить любой фон градиента позади – volody