2011-02-05 21 views
10

Sto cercando di gestire il colore del testo di TextBox sotto DWM Glass. Ho letto molto materiale, ancora nessuna soluzione perfetta.Test con TextBox sotto il vetro DWM

Il codice di risultati quasi perfetto che ho trovato qui: http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/316a178e-252b-480d-8cc9-85814c2073d8/, ma ha un sacco di sfarfallio e operazioni specifiche degli eventi (ad esempio: digitare del testo e premere il pulsante Home).

Ho provato a risolvere questi problemi.

Il seguente codice è una mutazione del codice originale, ma non si basa su alcun evento, solo WM_PAINT. Fa ancora sfarfallio e il cursore (cursore del testo) è scomparso in qualche modo!

Come evitare lo sfarfallio e come riportare il cursore (cursore del testo)?

Grazie.

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

Ho iniziato una taglia in genere per migliorare il metodo. Per lo più evitare di sfogliare, evitare invalidi, ecc. Non mi importa quanto sia brutto il codice. – Lazlo

+0

Un altro punto: non so cosa faccia AeroFix in questo codice, poiché non è mai impostato. Ma si prega di fare riferimento al codice originale in VB (link in post) che indicava un codice di invalidazione per evento. – Lazlo

+1

Si potrebbe semplicemente usare WPF e vivere felici e contenti. –

risposta

1

Se si imposta la TransparencyKey della forma al colore di sfondo nella zona di vetro poi, è possibile utilizzare qualsiasi controllo su di esso, ma non si può usare il colore specificato nel TransparencyKey in uno qualsiasi dei controlli posti lì.

Questo metodo ha l'inconveniente di consentire di fare clic sul vetro della finestra sullo sfondo. Ma potrebbe esserci un modo per aggirare anche questo.

EDIT: Ho cercato questo per molto tempo ora ... deve essere impossibile allora. Il carret è gestito dalla stessa API di Windows, non puoi forzarlo a comparire nel modo desiderato. Quello che potresti fare è disegnare tu stesso l'intera casella di testo ... ma sarebbe troppo lavoro per così poco.

Riepilogo: GDI + e DWM non si combinano molto bene. Mi arrendo.

+1

Questo metodo ha anche un altro inconveniente di mostrare il colore TransparencyKey al posto del vetro all'interno dell'immagine con un canale alfa graduale. – DxCK

+0

Concordato con DxCK. E un modo per aggirare il problema del click-through è di impostare i valori su diversi byte (200, 200, 201). Senza alcun mezzo per degradare la tua risposta, spero che questo non venga assegnato la taglia di default. Sembra una risposta "cacciatore di taglie". Edit: Lol, la taglia si è conclusa pochi minuti fa. Posso scegliere la persona che la riceve. – Lazlo

+0

@Lazlo: una taglia viene assegnata automaticamente a una persona solo se sono presenti almeno 2 voti positivi. –