2011-02-05 30 views
10

TextBox metninin rengini DWM Glass altında ele almaya çalışıyorum. Çok fazla malzeme okuyorum, hala mükemmel bir çözüm yok.DWM camı altında TextBox ile testler

Neredeyse mükemmel sonuçlar kodunu burada bulabilirim: http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/316a178e-252b-480d-8cc9-85814c2073d8/, ancak çok fazla harekete geçirme ve olaya özel işlem var (Örneğin: bazı metinleri yazın ve Ana Sayfa düğmesine basın).

Bu sorunları çözmeye çalışıyorum.

Aşağıdaki kod, orijinal kodun bir mütasyonudur, ancak yalnızca WM_PAINT üzerinde herhangi bir olaya dayanmaz. Hala flicking, ve caret (metin imleci) bir şekilde ortadan kayboldu!

Yanıp sönmeyi nasıl önlersiniz ve karet (metin imleci) nasıl geri alınır?

Teşekkürler. Sonra cam alanında arka plan renge formun TransparencyKey ayarlarsanız

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

Genel olarak yöntemi geliştirmek için bir ödül başlattım. Çoğunlukla flört etmekten kaçının, geçersiz kılmalardan kaçının, vb. Kodun ne kadar çirkin olduğunu düşünmüyorum. – Lazlo

+0

Başka bir nokta: Bu kodda AeroFix'in ne yaptığını bilmiyorum, çünkü asla ayarlanmadı. Ancak lütfen etkinlik başına geçersiz kılma kodunu belirten VB'deki (postayla bağlantılı) orijinal koda bakın. – Lazlo

+1

WPF'yi kullanabilir ve sonsuza dek mutlu yaşayabilirsiniz. –

cevap

1

, bunun üzerinde herhangi bir kontrol kullanabilirsiniz, ancak herhangi birinde TransparencyKey belirtilen rengi kullanamazsınız kontrollerin yer aldığı yer.

Bu yöntem, arka planda pencereden camı tıklatmanıza izin verme konusunda bir sakıncaya sahiptir. Fakat bu konuda da bir yol olabilir.

DÜZENLEME: Uzun zamandır bunun için araştırıyorum ... o zaman imkansız olmalı. Carret windows API tarafından yönetiliyor, istediğiniz şekilde görünmesini zorlayamıyorsunuz. Yapabileceğin şey, bütün metin kutusunu kendin çizmektir ... ama bu kadar az çalışan çok az şey.

Özet: GDI + ve DWM çok iyi birleşmiyor. Pes ediyorum.

+1

Bu yöntem aynı zamanda kademeli alfa kanalı ile Görüntü içindeki cam yerine TransparencyKey rengini göstermenin başka bir sakıncasına da sahiptir. – DxCK

+0

DxCK ile anlaşıldı. Tıklama sorununun bir yolu da değerleri farklı baytlara ayarlamaktır (200, 200, 201). Cevabınızı düşürmek için herhangi bir sebep olmadan, umarım bu, varsayılan olarak ödül kazanmaz. Bir "ödül avcısı" cevabı gibi görünüyor. Düzenleme: Lol, kelle dakika önce bitti. Onu alan kişiyi seçebilirim. – Lazlo

+0

@Lazlo: Bir ödül sadece en az 2 oy oyu olduğunda otomatik olarak bir kişiye gider. –