2011-02-05 4 views
10

Я пытаюсь иметь дело с цветом текста TextBox под DWM Glass. Я прочитал много материала, все еще не идеальное решение.Тесты с TextBox под стеклом DWM

Почти идеальный код результатов, который я нашел здесь: http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/316a178e-252b-480d-8cc9-85814c2073d8/, но он имеет множество операций по перемещению и событиям (например: введите текст и нажмите кнопку «Домой»).

Я пытаюсь решить эти проблемы.

Следующий код является мутацией исходного кода, но он не полагается ни на какое событие, просто на WM_PAINT. Он все еще щелкнет, и карет (текстовый курсор) как-то исчез!

Как предотвратить мерцание и как вернуть курсор (текстовый курсор)?

Спасибо.

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Windows.Forms; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Diagnostics; 

namespace AeroWindowsFormsApplication 
{ 
    public class AeroTextBox : TextBox 
    { 
     private const int WM_PAINT = 0xf; 

     private bool _aeroFix; 

     public AeroTextBox() 
     { 
      SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true); 
     } 

     protected override void WndProc(ref Message m) 
     { 
      if (_aeroFix) 
      { 
       switch (m.Msg) 
       { 
        case WM_PAINT: 
         RedrawAsBitmap(); 
         m.Result = new IntPtr(1); 
         break; 

        default: 
         base.WndProc(ref m); 
         break; 
       } 
      } 
      else 
      { 
       base.WndProc(ref m); 
      } 
     } 

     private void RedrawAsBitmap() 
     { 
      using (Bitmap bm = new Bitmap(this.Width, this.Height)) 
      using (Graphics g = this.CreateGraphics()) 
      { 
       this.DrawToBitmap(bm, this.ClientRectangle); 
       g.DrawImageUnscaled(bm, -1, -1); 
      } 
     } 

     public bool AeroFix 
     { 
      get { return _aeroFix; } 
      set 
      { 
       if (_aeroFix != value) 
       { 
        Invalidate(); 
       } 

       _aeroFix = value; 
      } 
     } 
    } 
} 
+0

Я начал щедрость, чтобы улучшить метод. В основном избегайте щелчка, избегайте недействительности и т. Д. На самом деле я не против, насколько уродливым должен быть код. – Lazlo

+0

Еще один момент: я не знаю, что делает AeroFix даже в этом коде, поскольку он никогда не устанавливается. Но, пожалуйста, обратитесь к исходному коду в VB (связанному в сообщении), в котором указывается код недействительности для каждого события. – Lazlo

+1

Вы можете просто использовать WPF и жить долго и счастливо. –

ответ

1

Если вы установите TransparencyKey формы на фоне цвета в области стекла, то вы можете использовать любой контроль над ним, но вы не можете использовать цвет, указанный в TransparencyKey в одном размещенных там элементов управления.

Этот метод имеет неудобство, позволяя вам щелкнуть по стеклу в окне в фоновом режиме. Но может быть и способ обойти это.

EDIT: Я искал это в течение длительного времени ... тогда это невозможно. Карре управляется самим API окон, вы не можете заставить его появляться так, как вы хотите. То, что вы могли бы сделать, это рисовать весь текстовый ящик самостоятельно ... но это слишком много для работы.

I summary: GDI + и DWM не очень хорошо сочетаются. Я сдаюсь.

+1

У этого метода также есть еще один неудобный показ цвета TransparencyKey вместо стекла внутри изображения с постепенным альфа-каналом. – DxCK

+0

Согласовано с DxCK. И путь вокруг проблемы с кликом - установить значения в разные байты (200, 200, 201). Без каких-либо признаков ухудшения вашего ответа я надеюсь, что это не получит награду по умолчанию. Это похоже на ответ «охотника за головами». Редактировать: Lol, щедрость закончилась минут назад. Я могу выбрать человека, который его получит. – Lazlo

+0

@ Lazlo: щедрость распространяется только на человека, когда есть как минимум 2 голоса. –