Tests with TextBox under DWM glass

2020-06-03 04:29发布

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条回答
劳资没心,怎么记你
2楼-- · 2020-06-03 04:51

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.

查看更多
登录 后发表回答