RichTextBox 的 AnimateWindow API 透明度问题

发布于 2024-09-14 10:36:13 字数 6877 浏览 2 评论 0原文

我正在使用 AnimateWindow API 来显示或隐藏带有幻灯片动画的 Form。问题是,如果表单包含 RichTextBox 控件,则它无法正确显示该控件。它是透明的,不显示任何文字。

动画完成后,双击控件中的某处将显示文本行。

我创建了一个完整的示例,任何人都可以使用它来自行编译和测试。除非您已经知道答案,否则没有更好的方法来调试此问题。

主窗体中有 2 个按钮,一个用于显示另一个窗体,另一个用于隐藏同一窗体。我已将 RichTextBox 添加为简单的 TextBox。正如您将看到的,问题仅发生在 RichTextBox 上。

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1 {
    static class Program {
        public const int AW_ACTIVATE = 0x00020000;
        public const int AW_HIDE = 0x00010000;
        public const int AW_HOR_NEGATIVE = 0x00000002;
        public const int AW_HOR_POSITIVE = 0x00000001;
        public const int AW_SLIDE = 0x00040000;

        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AnimateWindow(IntPtr hWnd, int time, int awFlags);

        [STAThread]
        public static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    public class Form1 : Form {
        public Form form;

        public Form1() {
            InitializeComponent();
            form = new Form2();
            form.Show();
            form.Hide();
        }

        private void button1_Click(object sender, EventArgs e) {
            form.Location = new Point(Location.X, Location.Y + form.Height + 100);
            Program.AnimateWindow(form.Handle, 1000, Program.AW_SLIDE | Program.AW_HOR_NEGATIVE | Program.AW_ACTIVATE);
            form.Show();
        }

        private void button2_Click(object sender, EventArgs e) {
            Program.AnimateWindow(form.Handle, 1000, Program.AW_HIDE | Program.AW_HOR_POSITIVE);
            form.Hide();
        }

        #region Windows Form Designer generated code

        private void InitializeComponent() {
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button1.Location = new System.Drawing.Point(11, 12);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(133, 114);
            this.button1.TabIndex = 0;
            this.button1.Text = "SHOW";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            this.button2.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button2.Location = new System.Drawing.Point(150, 12);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(133, 114);
            this.button2.TabIndex = 1;
            this.button2.Text = "HIDE";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(294, 138);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Form1";
            this.ResumeLayout(false);
        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
    }

    public class Form2 : Form {
        public Form2() {
            InitializeComponent();
        }

        #region Windows Form Designer generated code

        private void InitializeComponent() {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form2));
            this.richTextBox1 = new System.Windows.Forms.RichTextBox();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Top;
            this.richTextBox1.Location = new System.Drawing.Point(0, 0);
            this.richTextBox1.Name = "richTextBox1";
            this.richTextBox1.Size = new System.Drawing.Size(240, 50);
            this.richTextBox1.TabIndex = 0;
            this.richTextBox1.Text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.";
            this.textBox1.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.textBox1.Location = new System.Drawing.Point(0, 57);
            this.textBox1.Multiline = true;
            this.textBox1.Name = "textBox1";
            this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.textBox1.Size = new System.Drawing.Size(240, 50);
            this.textBox1.TabIndex = 1;
            this.textBox1.Text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.";
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(240, 107);
            this.ControlBox = false;
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.richTextBox1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.Name = "Form2";
            this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
            this.Text = "Form2";
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        #endregion

        private System.Windows.Forms.RichTextBox richTextBox1;
        private System.Windows.Forms.TextBox textBox1;
    }
}

注意:我正在为此启动悬赏,所以如果您要回答,请回答一个有效的解决方案,而不是让我尝试看看它是否有效。为什么?因为如果人们对你的答案投了赞成票并且没有解决任何问题,它仍然会被标记为已接受,但这没有帮助。感谢您的理解。

I'm using the AnimateWindow API to show or hide a Form with a slide animation. The problem is that if the Form contains a RichTextBox control, it doesn't display this control correctly. It's transparent and doesn't show any text.

After the animation is complete, double clicking somewhere in the control will reveal lines of text.

I've created a full sample that anyone can use to compile and test themselves. There's no better way to debug this, unless you already know the answer.

There's 2 buttons in the main form, one to show another form and the other to hide that same form. I've added both the RichTextBox as a simple TextBox. As you'll see, the problem only happens on the RichTextBox.

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1 {
    static class Program {
        public const int AW_ACTIVATE = 0x00020000;
        public const int AW_HIDE = 0x00010000;
        public const int AW_HOR_NEGATIVE = 0x00000002;
        public const int AW_HOR_POSITIVE = 0x00000001;
        public const int AW_SLIDE = 0x00040000;

        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AnimateWindow(IntPtr hWnd, int time, int awFlags);

        [STAThread]
        public static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    public class Form1 : Form {
        public Form form;

        public Form1() {
            InitializeComponent();
            form = new Form2();
            form.Show();
            form.Hide();
        }

        private void button1_Click(object sender, EventArgs e) {
            form.Location = new Point(Location.X, Location.Y + form.Height + 100);
            Program.AnimateWindow(form.Handle, 1000, Program.AW_SLIDE | Program.AW_HOR_NEGATIVE | Program.AW_ACTIVATE);
            form.Show();
        }

        private void button2_Click(object sender, EventArgs e) {
            Program.AnimateWindow(form.Handle, 1000, Program.AW_HIDE | Program.AW_HOR_POSITIVE);
            form.Hide();
        }

        #region Windows Form Designer generated code

        private void InitializeComponent() {
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button1.Location = new System.Drawing.Point(11, 12);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(133, 114);
            this.button1.TabIndex = 0;
            this.button1.Text = "SHOW";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            this.button2.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button2.Location = new System.Drawing.Point(150, 12);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(133, 114);
            this.button2.TabIndex = 1;
            this.button2.Text = "HIDE";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(294, 138);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Form1";
            this.ResumeLayout(false);
        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
    }

    public class Form2 : Form {
        public Form2() {
            InitializeComponent();
        }

        #region Windows Form Designer generated code

        private void InitializeComponent() {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form2));
            this.richTextBox1 = new System.Windows.Forms.RichTextBox();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Top;
            this.richTextBox1.Location = new System.Drawing.Point(0, 0);
            this.richTextBox1.Name = "richTextBox1";
            this.richTextBox1.Size = new System.Drawing.Size(240, 50);
            this.richTextBox1.TabIndex = 0;
            this.richTextBox1.Text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.";
            this.textBox1.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.textBox1.Location = new System.Drawing.Point(0, 57);
            this.textBox1.Multiline = true;
            this.textBox1.Name = "textBox1";
            this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.textBox1.Size = new System.Drawing.Size(240, 50);
            this.textBox1.TabIndex = 1;
            this.textBox1.Text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.";
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(240, 107);
            this.ControlBox = false;
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.richTextBox1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.Name = "Form2";
            this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
            this.Text = "Form2";
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        #endregion

        private System.Windows.Forms.RichTextBox richTextBox1;
        private System.Windows.Forms.TextBox textBox1;
    }
}

NOTE: I'm starting a bounty on this so if you're going to answer, please answer with a solution that works and not something for me to try and see if it works. Why? Because if people upvote your answer and doesn't fix anything , it will still be marked as accepted which it didn't help. Thanks for understanding.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我家小可爱 2024-09-21 10:36:13

请查看这段代码...这是我见过的最奇怪的错误...唯一的区别是我必须捕获 RichTextBox 的 VisibleChanged 事件,并设置 Capture 属性,更新它,然后关闭Capture,我认为应该向控件发送一条消息以强制双击事件,但发现这不是必需的...我还必须覆盖form2 本身的 OnActivated 事件,以便在动画完成后捕获事件并强制刷新......奇怪的错误......

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Text;

namespace WindowsFormsApplication1
{
    static class Program
    {
        public const int AW_ACTIVATE = 0x00020000;
        public const int AW_HIDE = 0x00010000;
        public const int AW_HOR_NEGATIVE = 0x00000002;
        public const int AW_HOR_POSITIVE = 0x00000001;
        public const int AW_SLIDE = 0x00040000;

        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AnimateWindow(IntPtr hWnd, int time, int awFlags);

        [STAThread]
        public static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    public class Form1 : Form
    {
        public Form form;

        public Form1()
        {
            InitializeComponent();
            form = new Form2();
            form.Show();
            form.Hide();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            form.Location = new Point(Location.X, Location.Y + form.Height + 100);
            Program.AnimateWindow(form.Handle, 1000, Program.AW_SLIDE | Program.AW_HOR_NEGATIVE | Program.AW_ACTIVATE);
            form.Show();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Program.AnimateWindow(form.Handle, 1000, Program.AW_HIDE | Program.AW_HOR_POSITIVE);
            form.Hide();
        }

        #region Windows Form Designer generated code

        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button1.Location = new System.Drawing.Point(11, 12);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(133, 114);
            this.button1.TabIndex = 0;
            this.button1.Text = "SHOW";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            this.button2.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button2.Location = new System.Drawing.Point(150, 12);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(133, 114);
            this.button2.TabIndex = 1;
            this.button2.Text = "HIDE";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(294, 138);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Form1";
            this.ResumeLayout(false);
        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
    }

    public class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            this.richTextBox1.VisibleChanged += new EventHandler(richTextBox1_VisibleChanged);
        }

        void richTextBox1_VisibleChanged(object sender, EventArgs e)
        {
            if (this.richTextBox1.Visible)
            {
                System.Diagnostics.Debug.WriteLine("Visible!");
                this.richTextBox1.Capture = true;
                this.richTextBox1.Update();
                this.richTextBox1.Capture = false;
                this.richTextBox1.Refresh();
            }
            else System.Diagnostics.Debug.WriteLine("InVisible!");
        }

        #region Windows Form Designer generated code

        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form2));
            this.richTextBox1 = new System.Windows.Forms.RichTextBox();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Top;
            this.richTextBox1.Location = new System.Drawing.Point(0, 0);
            this.richTextBox1.Name = "richTextBox1";
            this.richTextBox1.Size = new System.Drawing.Size(240, 50);
            this.richTextBox1.TabIndex = 0;
            this.richTextBox1.Text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.";
            this.textBox1.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.textBox1.Location = new System.Drawing.Point(0, 57);
            this.textBox1.Multiline = true;
            this.textBox1.Name = "textBox1";
            this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.textBox1.Size = new System.Drawing.Size(240, 50);
            this.textBox1.TabIndex = 1;
            this.textBox1.Text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.";
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(240, 107);
            this.ControlBox = false;
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.richTextBox1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.Name = "Form2";
            this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
            this.Text = "Form2";
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        #endregion

        protected override void OnActivated(EventArgs e)
        {
            base.OnActivated(e);
            System.Diagnostics.Debug.WriteLine("OnActivated");
            this.Refresh();
        }

        private System.Windows.Forms.RichTextBox richTextBox1;
        private System.Windows.Forms.TextBox textBox1;
    }
}

代码有效尽管如此 - 一件非常晦涩的事情 - 有趣的是在 VisibleChanged 处理程序中,我原以为单击“隐藏”按钮时调试输出会显示“InVisible”,但事实并非如此。我确实尝试使用 WM_PRINTWM_PRINTCLIENT 消息,但在富文本框上失败了,只是不要问我为什么在富文本框本身上设置捕获并强制刷新解决了它...这是来自 的引用MSDN 对此:

窗口及其子窗口的窗口过程应该处理任何 WM_PRINT 或 WM_PRINTCLIENT 消息。对话框、控件和通用控件已处理 WM_PRINTCLIENT。默认的窗口消息处理程序已经处理WM_PRINT。如果子窗口显示为部分剪裁,则在进行动画处理时,其剪裁处将出现孔洞。

我不知道是否值得向 Microsoft 指出这一点并说“AnimateWindow 或带有 .NET 的 RichTextBox 控件中存在错误”,无论哪种方式,都很难确定,因为动画完成后,文本框显示正常,但富文本框显示不正常,但在捕获打开时显式使用 CaptureUpdate 强制刷新。它在错误本身上双向摆动 - 可能在两个地方......无论如何都很不寻常和奇怪......希望代码对你有用。

Please see this code... this is the most bizarre bug I've ever seen... the only difference is that I had to trap the VisibleChanged Event for the RichTextBox, and to set the Capture property, update it, then switch off the Capture, my thinking there was to send a message to the control to force a double-click event but discovered that is not required... I also had to override the OnActivated event for the form2 itself in order to get the event trapped AFTER the animation is done and to force a refresh...strange bizarre bug....

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Text;

namespace WindowsFormsApplication1
{
    static class Program
    {
        public const int AW_ACTIVATE = 0x00020000;
        public const int AW_HIDE = 0x00010000;
        public const int AW_HOR_NEGATIVE = 0x00000002;
        public const int AW_HOR_POSITIVE = 0x00000001;
        public const int AW_SLIDE = 0x00040000;

        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AnimateWindow(IntPtr hWnd, int time, int awFlags);

        [STAThread]
        public static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    public class Form1 : Form
    {
        public Form form;

        public Form1()
        {
            InitializeComponent();
            form = new Form2();
            form.Show();
            form.Hide();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            form.Location = new Point(Location.X, Location.Y + form.Height + 100);
            Program.AnimateWindow(form.Handle, 1000, Program.AW_SLIDE | Program.AW_HOR_NEGATIVE | Program.AW_ACTIVATE);
            form.Show();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Program.AnimateWindow(form.Handle, 1000, Program.AW_HIDE | Program.AW_HOR_POSITIVE);
            form.Hide();
        }

        #region Windows Form Designer generated code

        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button1.Location = new System.Drawing.Point(11, 12);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(133, 114);
            this.button1.TabIndex = 0;
            this.button1.Text = "SHOW";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            this.button2.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button2.Location = new System.Drawing.Point(150, 12);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(133, 114);
            this.button2.TabIndex = 1;
            this.button2.Text = "HIDE";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(294, 138);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Form1";
            this.ResumeLayout(false);
        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
    }

    public class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            this.richTextBox1.VisibleChanged += new EventHandler(richTextBox1_VisibleChanged);
        }

        void richTextBox1_VisibleChanged(object sender, EventArgs e)
        {
            if (this.richTextBox1.Visible)
            {
                System.Diagnostics.Debug.WriteLine("Visible!");
                this.richTextBox1.Capture = true;
                this.richTextBox1.Update();
                this.richTextBox1.Capture = false;
                this.richTextBox1.Refresh();
            }
            else System.Diagnostics.Debug.WriteLine("InVisible!");
        }

        #region Windows Form Designer generated code

        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form2));
            this.richTextBox1 = new System.Windows.Forms.RichTextBox();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Top;
            this.richTextBox1.Location = new System.Drawing.Point(0, 0);
            this.richTextBox1.Name = "richTextBox1";
            this.richTextBox1.Size = new System.Drawing.Size(240, 50);
            this.richTextBox1.TabIndex = 0;
            this.richTextBox1.Text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.";
            this.textBox1.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.textBox1.Location = new System.Drawing.Point(0, 57);
            this.textBox1.Multiline = true;
            this.textBox1.Name = "textBox1";
            this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.textBox1.Size = new System.Drawing.Size(240, 50);
            this.textBox1.TabIndex = 1;
            this.textBox1.Text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.";
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(240, 107);
            this.ControlBox = false;
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.richTextBox1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.Name = "Form2";
            this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
            this.Text = "Form2";
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        #endregion

        protected override void OnActivated(EventArgs e)
        {
            base.OnActivated(e);
            System.Diagnostics.Debug.WriteLine("OnActivated");
            this.Refresh();
        }

        private System.Windows.Forms.RichTextBox richTextBox1;
        private System.Windows.Forms.TextBox textBox1;
    }
}

The code works nonetheless - a very obscure thing - the funny thing is within the VisibleChanged handler, I was expecting the debug output to say "InVisible" when clicking on the 'Hide' button but it did not. I did try using WM_PRINT and WM_PRINTCLIENT message which failed with the rich-text-box, just don't ask me why setting the capture on the rich-text-box itself and forcing a refresh solved it... Here's the quote from MSDN on this:

The window procedures for the window and its child windows should handle any WM_PRINT or WM_PRINTCLIENT messages. Dialog boxes, controls, and common controls already handle WM_PRINTCLIENT. The default window procedure already handles WM_PRINT. If a child window is displayed partially clipped, when it is animated it will have holes where it is clipped.

I do not know if it's worth the trouble in pointing this out to Microsoft and say "There's a bug either in the AnimateWindow or in the RichTextBox Control with .NET", either way, it is difficult to ascertain, since after the animation is done, the text-box appears ok, but not the rich-text-box, yet explicitly using the Capture and the Update when the capture is on, forced a refresh... it swings both ways on the bug itself - could be in both spots... Very unusual and bizarre anyway.. hope the code is of use to you.

站稳脚跟 2024-09-21 10:36:13

RichTextBox 不处理 WM_PRINT 消息,我相信 AnimateWindow 在幕后使用的是什么,所以我看不到任何使用富文本框中可见的文本执行动画的方法(如果您希望富文本框显示文本)动画期间)。

动画完成后,您可以调用 richTextBox1.Refresh (通过 Form2 类中的辅助方法在您的 button1_Click 中)来重新绘制框 - 带有文本的控件将正常显示,无需任何双击。

The RichTextBox does not process WM_PRINT messages, which is I believe what AnimateWindow uses behind the scenes, so I don't see any way of doing the animation with the text visible in your rich text box (in case you want richtext box to display text during the animation).

When the animation is complete you can call richTextBox1.Refresh (in your button1_Click via a helper method in the Form2 class) for the box to repaint - the control with the text will be shown alright without any double-clicking.

甜味拾荒者 2024-09-21 10:36:13

WPF 不包含您需要的幻灯片动画吗?

像 AnimateWindow 这样的 API...在 Microsoft 中并没有得到太多关注 - 通常支持“更好”的 .NET / WPF 方法。使用本机/非托管 API 来设置窗口动画很快会让您陷入痛苦的世界:- Microsoft 不支持本机控件和窗口中的闪烁控制动画或 alpha 效果。

如果目标窗口具有航空玻璃,则本机 AnimateWindow 往往会翻倒。任何非客户端元素。任何孩子都可以控制。任何透明度(窗口区域、带有 Alpha 或遮罩的分层窗口)。

它真的根本没有那么好用。


解决这个问题的唯一方法是执行 AnimateWindow 所做的事情。 AnimateWindow 与其说是 API 调用,不如说是用户可以“轻松”实现的功能的便捷包装。

AnimateWindow 所做的一切,就是在计时器上重新定位动画窗口。根据动画,它将在动画持续时间内使用剪辑区域,或添加 WS_EX_LAYERED 样式(以进行 alpha 混合)。这就是为什么当给定窗口已经使用这些效果时 AnimateWindow 会如此失败。

自己执行动画时,您可以尝试调整参数以更符合丰富的编辑绘画要求。

Does WPF not contain the slide animations you need?

APIs like AnimateWindow are ... not given a lot of attention at Microsoft - usually in favor of a 'better' .NET / WPF method. Using native / not managed APIs to animate windows quickly lands you in a world of hurt :- Microsoft do not support flicker control animations - or alpha effects - in native controls and windows.

The native AnimateWindow tends to fall over if the target window has aero glass. any non-client elements at all. Any child controls. any transparency (window regions, layered windows with alpha or masking).

It really just doesn't work that well at all.


The only way to work around it would be to do what AnimateWindow does. AnimateWindow is not so much an API call, but a convenience wrapper around functionality that can "easilly" be implemented by the user.

All that AnimateWindow does it, well, reposition the animated window on a timer. Depending on the animation it will use clip regions, or add the WS_EX_LAYERED style (to do the alpha blends) for the duration of the animation. This is why AnimateWindow fails so spectacularly when given windows already using those effects.

Performing the animation yourself, you can try to tweak the parameters to do it in a way more compatible with the rich edits painting requirements.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文