Tests with TextBox under DWM glass

1.3k views Asked by At

I'm trying to deal with TextBox text's color under DWM Glass. I read a lot of material, still no perfect solution.

The almost perfect results code i found here: http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/316a178e-252b-480d-8cc9-85814c2073d8/ , but it has a lot of flicking and event-specific operations (For example: type some text and push Home button).

I trying to solve those problems.

The following code is a mutation of the original code, but it does not relies on any event, just WM_PAINT. It still flicking, and the caret (text cursor) is disappeared somehow!

How to prevent flickering, and how to get the caret (text cursor) back?

Thanks.

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;
            }
        }
    }
}
1

There are 1 answers

3
Miguel Angelo On

If you set the TransparencyKey of the form to the background color in the glass area then, you can use any control over it, but you cannot use the color specified in the TransparencyKey in any one of the controls placed there.

This method has an inconvenient of allowing you to click through the glass on the window in the background. But there may be a way around this too.

EDIT: I have been searching for this for a long time now... it must be impossible then. The carret is managed by windows API itself, you cannot force it to appear in the way you want. What you could do is to draw the whole text-box yourself... but that whould be too much work for so little.

I summary: GDI+ and DWM do not combine very well. I give up.