2011-02-05 13 views
10

Estoy tratando de lidiar con el color del texto de TextBox en DWM Glass. He leído mucho material, todavía no hay una solución perfecta.Pruebas con TextBox en cristal DWM

El código de resultados casi perfecto que encontré aquí: http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/316a178e-252b-480d-8cc9-85814c2073d8/, pero tiene muchas operaciones rápidas y específicas de un evento (Por ejemplo: escriba un texto y presione el botón de inicio).

Estoy tratando de resolver esos problemas.

El siguiente código es una mutación del código original, pero no depende de ningún evento, solo WM_PAINT. Todavía parpadea, ¡y el cursor (cursor de texto) ha desaparecido de alguna manera!

Cómo evitar el parpadeo y cómo recuperar el cursor de texto (cursor de texto)?

Gracias.

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

Empecé una recompensa para, en general, mejorar el método. En general evito parpadear, evitar invalidaciones, etc. No me importa lo feo que sea el código. – Lazlo

+0

Otro punto: no sé lo que AeroFix incluso hace en este código, ya que nunca se establece. Pero consulte el código original en VB (vinculado en la publicación) que indica un código de invalidación por evento. – Lazlo

+1

Puedes usar WPF y vivir feliz para siempre. –

Respuesta

1

Si se establece el TransparencyKey de la forma a la fondo de color en el área de vidrio cuando, se puede utilizar cualquier control sobre él, pero no se puede utilizar el color especificado en la TransparencyKey en cualquiera de los controles colocados allí.

Este método tiene un inconveniente que le permite hacer clic a través del cristal en la ventana en el fondo. Pero puede haber una forma de evitar esto también.

EDIT: He estado buscando esto por un largo tiempo ahora ... debe ser imposible entonces. El carret es administrado por la API de Windows en sí misma, no se puede obligar a que aparezca en la forma que desee. Lo que podría hacer es dibujar todo el cuadro de texto usted mismo ... pero eso sería demasiado trabajo para tan poco.

Sumario: GDI + y DWM no combinan muy bien. Me doy por vencido.

+1

Este método también tiene otro inconveniente de mostrar el color TransparencyKey en lugar del vidrio dentro de la imagen con un canal alfa gradual. – DxCK

+0

De acuerdo con DxCK. Y una forma de evitar el problema de clics es establecer los valores en diferentes bytes (200, 200, 201). Sin ningún motivo para degradar su respuesta, espero que esto no reciba la recompensa por defecto. Parece una respuesta de "cazarrecompensas". Editar: Lol, la recompensa terminó hace minutos. Puedo elegir a la persona que lo consigue. – Lazlo

+0

@Lazlo: una recompensa solo va a una persona automáticamente cuando hay al menos 2 votos. –