渲染期间绘制加载封面图像

立克次体

成员
已加入
2020年1月22日
留言内容
10
编程经验
10+
你好,
我有一个简单的无边框全屏Form(现在已启用了双缓冲)应用程序,因为我想要Forms applet。问题很简单,一个提到的applet reqiure完全延迟重新绘制,因此会导致屏幕闪烁。我为该小程序的隐藏加载状态制作了全屏封面图像。有趣的是,我的封面图像也闪烁了!  :) 问题是组合表格和硬图像大小。快速绘制封面图像以避免背景闪烁是否容易? (某些屏幕绘图可能带有某些Windows lib或Nuget包。)我想要的结果没有任何外部要求,如果必须的话,只需很小的lib。还请记住,我想要过渡此封面图像以真正平滑地加载...
 

羊皮

退休程序员
已加入
2018年9月5日
留言内容
1,982
地点
英国
编程经验
10+
提到applet reqiure完全懒惰重绘
什么小程序?您从哪里得到的?
问题是组合表格和硬图像大小
您似乎已经知道问题所在,所以为什么不能为此提出建议?"hard image size"?
如果您正在绘制另一幅图像(看起来就像您所描述的那样),您是否认为其正常发生闪烁?
如果在要绘制的前景项目后面绘制了一个前景项目,则双重缓冲不会对您有很大帮助。

鉴于Windows迫使Windows 7用户升级到Windows 10的事实,这听起来像是没有意义的问题,但是您的应用程序针对的是什么操作系统?
我问,因为如果您针对的是较旧的操作系统,则可以使用 WS_EX_COMPOSITED; 我可能还需要禁用AERO,这将大大减少闪烁。使用此API确实需要禁用DWM,但是,最合乎逻辑的事情是在WPF中设计应用程序,以避免所有这些必要情况,尤其是在您的应用程序始终依赖于图形处理的情况下。
 

立克次体

成员
已加入
2020年1月22日
留言内容
10
编程经验
10+
再说一遍。我有FULLSCREEN(无边界最大化)窗体(目前已启用DoubleBuffering)和停靠(填充)控件。我想要在背景中进行表格句柄渲染。这是全部。 Fomrs渲染问题是众所周知的-如果在窗体中的控件不可见,则无法在后台渲染。我尝试了两种解决方案-使用“控制手柄”和“屏幕手柄”。在控制手柄上绘图是不好的解决方案,因为以快速FPS进行小程序渲染会导致闪烁。但是在屏幕上绘制(零PTR)确实有效,并且涵盖了Control渲染。屏幕渲染的唯一问题是绘图速度慢。所以我只想用较低的代码在Form / Control上绘制封面图像,这可能是我知道的,我使用了很多渲染框架等。我需要做的就是让我的Form平滑地在后台渲染,并在前面绘制全屏封面...(并在不刷新加载的Control的情况下将Form放在前面,而只是绘制渲染。)我的目标是Windows 10,没有特殊的libs或其他内容-基本系统在可能的情况下。必须有简单的解决方案,因为我真的知道,这是可能的。我可以为此做准备,我可以运行一些具有DirectX访问权限或其他功能的后台应用程序-确实,我只是想在表格上绘制封面图像并将表格平滑地放在前面...

例如,我尝试过的方法效果很好:
我可以在ZeroPtr Handle上进行封面绘制并获取Control快照,我也可以在Desktop Handle中进行绘制,但是渲染速度非常慢-我知道,在Desktop Handle上绘制是个坏主意。但是它闪闪发光。
我在Control Handle处绘制了计时器封面,可以进行快速渲染和真正的Cower Control渲染,但是最后可以进行一次快速闪烁。所以我真的在寻找一些平稳的过渡...
 
Last edited:

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
请向我们显示您的代码。我怀疑您正在执行的操作正在引起屏幕闪烁。

考虑一下我在此介绍的代码 其他线程。它具有全屏Matrix屏幕保护程序效果,而不会闪烁。 (当然,我仅在2560x1080、1920x1080或更小尺寸的带有80-96 DPI常规显示器的计算机上进行过测试。我没有任何4K显示器。)我在这里所做的全部只是使用内置的双缓冲和在绘画事件中进行常规绘画。我什至没有花所有其他技巧来加快绘图速度,例如跳过背景绘画,仅跳过比屏幕刷新率更快的帧,仅更新实际更改的屏幕部分或通过以下方式实现我自己的双重缓冲:绘制到屏幕外的图形表面。
 

立克次体

成员
已加入
2020年1月22日
留言内容
10
编程经验
10+
我没有该小程序的代码。我有applet的LIB,它具有Forms外部的CUSTOM呈现系统,并且托管在Forms应用程序中。我完全知道为什么它会闪烁。我在第一篇文章中对此进行了描述。唯一的问题是,此applet需要处理以前的屏幕,因此它会绘制空白屏幕并变为渲染。我的意思是闪烁。 applet呈现之前的空白页。而且我还必须在渲染期间注意项目positionig。所以我只想在我拥有的图像下覆盖此渲染。真的没什么特别的。我被要求绘制其他场景,所以我显示封面图像并将新屏幕发送到applet。 Applet重绘具有空白页的屏幕并变为渲染状态。重做后,我将applet Control置于最前面。那就是我想要的。我只需要一些低代码的全屏渲染,就可以轻松地缩减Forms渲染。这是我的问题。确实,我在表单停靠的控件中只有表单{Maimized,Borderless},我想介绍一下。而已。我只有这两个简单的项目。

问题还在于,此小程序具有自定义呈现,因此不会引起Forms Paint事件。我无法控制applet渲染。而且我不需要它。我只想让此applet渲染并覆盖在我的图像下。而且我想在工作完成后隐藏图像。之前或之后没有空白屏幕。因此,在较低的代码中,不是愚蠢的形式...(模拟淡入/淡出。)

只是我看到了有关applet的信息,它应该使用SKIA endine进行渲染。
 
Last edited:

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
您正在全屏无边框窗体中托管的applet,WinForms控件或ActiveX控件吗?

Can you move your Form off screen (e.g. Form.Location = Screen.PrimaryScreen.Bounds.Location - Screen.PrimaryScreen.Bounds.Size;, and then when it is done drawing move it back on screen Form.Location = new Point(0,0);) ?
 

立克次体

成员
已加入
2020年1月22日
留言内容
10
编程经验
10+
但是当前屏幕上会显示什么?正如我提到的,它应该是SKIA applet-像WebGL。它不是在Form Handle之外呈现的,但是也不会引起正常的Forms事件...正如我所写的,当我在零Handle上绘制图像时,它覆盖了它下面的表单,并且对我有用。仅此渲染是如此缓慢,所以我只想通过某个DirectX库或屏幕缓冲区上的某个东西进行渲染。当我移动或调整主窗体的大小时,它仍会闪烁-我的意思是,在完成操作之前已绘制了一些颜色矩形...因此,我正在寻找真正需要遮盖的渲染,不需要窗体句柄...
 

羊皮

退休程序员
已加入
2018年9月5日
留言内容
1,982
地点
英国
编程经验
10+
再说一遍。我有FULLSCREEN(无边界最大化)表格(目前已启用DoubleBuffering)
这个线程上有可怕的回声。
您似乎已经知道问题所在,所以为什么不能为此提出建议?"hard image size"?
如果您正在绘制另一幅图像(看起来就像您所描述的那样),您是否认为其正常发生闪烁?
如果在要绘制的前景项目后面绘制了一个前景项目,则双重缓冲不会对您有很大帮助。
我会以您10年的经验来思考,这对于您理解我的意思相对来说比较简单,而不是试图将我的帖子视为无用的运球。也许如果您花了一些时间阅读收到的答复,您会发现您的方法是无法实现的。在第4个帖子中,您遇到了相当不礼貌的情况,好像代码猴子的回答您的人不理解您的问题,并且似乎已经超出了我们的脑袋,但事实并非如此。

您正在谈论在手柄上绘图。大声笑你没有画手柄,而且你似乎还真不明白什么是手柄或如何使用手柄。这确实部分地解释了该问题,但作为到您的原始问题的主题外链接。 什么是"handle"?

另外,如果您有10年的经验。您应该知道您在使用什么。它是一个applet,一个活动的X控件,一个用户控件,一个自定义插件吗?

仅阅读您的答复,我就能告诉您没有十年的工作经验,并且您当然对自己正在做的事情或什至是不可能的事情没有很好的了解。我将为您省心,并告诉您这是行不通的,尤其是在Winforms中。同样,如果您使用某种Applet,则无论您应用了什么缓冲,它都会在重绘时影响它前面的所有内容。 Winforms不是为这种类型的处理而构建的。祝你好运。
 

立克次体

成员
已加入
2020年1月22日
留言内容
10
编程经验
10+
我真的没有10年使用Windows Forms的经验。我一开始是BSD上的Linux程序员。过去5年的MVC ASP / PHP。我在用"IntPtr GetDC(IntPtr hwnd);"用于在控件上绘图。 (通过句柄。)大约7年之前,我使用了直接缓冲区绘制。所以我知道,重绘屏幕缓冲区真的很容易,只是我忘记了解决方案。我根本不是Desktop Forms开发人员。但是我很确定自己需要什么以及如何去做。因为我是Mono / Xamarin开发人员已有4年,所以我花了一些时间从事Forms渲染。我只想通过一些较低的渲染来隐藏Form渲染...一个小时前我才有了主意,所以大约40分钟后我会尝试一下。如我所写,我不是桌面开发人员,但是这确实必须有简单的解决方案-隐藏Control绘画...
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
I am using "IntPtr GetDC(IntPtr hwnd);"用于在控件上绘图。 (通过句柄。)
这也存在部分性能问题。当您使用P / Invoke调用时,需要将参数从世界的受管端编组到非受管端,执行实际的调用,然后将来自非受管端的任何响应编组回受管端。因此,使用非托管代码要花费几毫秒的Win32 GDI代码将达到几百毫秒。确保最小化这些托管/非托管过渡。

为什么不简单地在自己的控件上绘画,用它来覆盖其他窗体"applet" hosted in it?
 

立克次体

成员
已加入
2020年1月22日
留言内容
10
编程经验
10+
我可以在哪里画画?这都是我的问题。我有封面图片。但是要在哪里绘制...当我尝试在Control中绘制时,它的渲染效果就好了(而且闪烁了)。因此,我需要一些可以放在前面的新图层...这就是我想要的。只需让Control完全呈现并覆盖它即可。它不会导致正常的Paint事件,所以我不能使用正常的绘画...如前所述,例如,我可以准备一些后台应用程序。正如我之前写的,它是SKIA,WebGL之类的插件。我可以在后台准备第二个Form,但是我真的不知道如何将它放在前面而不会闪烁...而且,我的P / Invoke调用一点也不慢。因为我在触发控件刷新之前就已经这样做了。这就是我从一开始就试图告诉您的。是我造成了Control渲染,所以我可以为此做准备。我之前拍摄快照,之前拍摄快照,然后让Control刷新。我在Control渲染后隐藏了封面。我可以处理这一切。只是我无权访问较低的渲染,可以通过Form快速重绘图像...您仍然尝试告诉我,我的渲染闪烁,但实际上,这不是问题,因为我直到准备让它..我可以为它做准备,我可以在后台运行其他应用,我可以做的一切。只是我不知道有什么方法可以顺利地覆盖Form,并让Form出现在前面,而无需重新加载Control。 Applet渲染的唯一愚蠢之处在于,在清除它之前先清除它。因此,在渲染之前,它会在屏幕上显示几秒钟的背景色。它会导致闪烁...我只想在控制刷新之前先覆盖它。是的,一直以来,我一直在寻找如何在此applet论坛中为此applet启用双缓冲区的功能,但我对此没有答案。 。所以,我只想隐藏它,因为我敢肯定,这是简单快捷的解决方案...
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
同样,在看不到您的代码的情况下,很难谈论您在做什么以及如何使事情变得更好。

如果你的"applet"正在使用WebGL,并且正在使用任何类型的GPU加速,直接绘图,或者如果它实际上在正在使用的窗口上绘制覆盖图(例如某些nVidia和ATI / AMD视频播放加速),则WinForms双重缓冲不会继续进行对您有好处,因为双重缓冲发生在GDI级别,而您的"applet"实际上是绘制到屏幕上并绕过GDI。
 

立克次体

成员
已加入
2020年1月22日
留言内容
10
编程经验
10+
我没有小程序代码。我真的只有表格和控件。其他所有内容都是为applet内容编写的。我真的知道,Windows API的双重缓冲无法解决,这就是为什么我每次都将其写在括号中。是的,它具有GPU加速功能。我确实在4个帖子之前写过它,但您忽略了它...

"只是我看到了有关applet的信息,它应该使用SKIA endine进行渲染。"

我也可以关闭加速功能,但是不确定是否仅为此解决方案即可。 (必须在应用程序运行之前将其关闭,然后才能在任何时候使用。)我必须写几次,我不想用Forms Render解析它,我不想用Forms双缓冲来解析它!我知道,这不是解决方案。从第一篇文章开始,我一直希望在较低的代码中使用一些DirectX lib,但是您仍然会忽略它,并且仍然对Forms感兴趣。但是Form层确实无法解决它。我知道,这就是为什么我在这里。我想降低对屏幕缓冲区的访问...我真的不知道如何更好地编写它。我有Form,使用停靠的控件运行Form。从Control拍摄快照,在Control DC中绘制图像,调用刷新(重新加载小程序屏幕),并让Control的最后绘制在我的图像上闪烁。从那时起,我真的想关闭GPU加速功能,但是我仍然不确定是否可以使用它。但是您真的不能怪我,我从第一篇文章开始就写给您,我正在寻找底层渲染...我知道情况,我知道Forms的渲染是不行的。确实,我在谈论2个Form控件和刷新其中之一。而已。我真的没想到这个问题。我只是想在完成之前覆盖applet刷新...
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
您可以创建一个最小的WinForms应用程序来演示该问题吗?它将具有:
-托管该表单的某些最低版本"applet"
-托管您的表格的某些最低版本"docked Control"
-您的控件的一些最低版本
-拍摄快照,在Control DC中绘制图像,调用refresh或applet以及绘制控件的一些最小版本的代码。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
我知道,这就是为什么我在这里。我想访问较低的屏幕缓冲区...
"here"碰巧是WinForms论坛。 WinForms没有这种较低级别的访问权限。注意这个词"forms" in "WinForms".

在您的第一篇文章中,您说:
(某些屏幕绘图可能带有某些Windows lib或Nuget包。)我想要的结果没有任何外部要求,如果必须的话,只需很小的lib。
If you don't want external requirements, then using DirectX or DirectDraw is going to be eliminated because those are external dependencies. Even though it maybe installed on Windows, you'll still have to jump outside of WinForms to get to them. As it is, your current P/Invoke call to GetDC() is also technically an external dependency/requirement since again, you are jumping outside of WinForms. Granted that WinForms is built on WinUser and WinGDI, consider what happens when you run your code on .NET Core 3.0 on Linux where you may not have a real Windows DC to play with.
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
由于您非常乐于提供一些试图证明问题的代码,因此这里有一些代码试图重现该问题。

模拟承载基于SKIA的表单"applet", I have a fullscreen MainForm which has a SKGLControl. Inside the control, a bouncing ball and the current time is rendered at a target frame rate.

Unfortunately, I can't reproduce the flickering while drawing on SKIA control that is hardware accelerated. The closest I could get was for some horizontal tearing to happen on my old desktop computer with an 8 year ATI/AMD graphics card. (I couldn't get the same tearing to happen on my laptop that has a relatively modern dedicated ATI/AMD graphics chip.) I got the tearing to show by using higher values for PixelsPerSecond in the Ball class (line 142).

Anyway with the tearing appearing, I then show the covering DesktopForm on top of the MainForm by pressing the Escape key (see lines 91-101). All this form does is render an upside down screenshot of the desktop. I deliberately render the screen upside down because I was confusing myself as to when I had my real desktop vs. a static screenshot of it. If you don't want it upside down, comment out the transform lines. Any which way, I'm just using normal painting. I really don't understand why you would need to P/Invoke GetDC().

无论如何,在覆盖托管表单的新表单上,我看不到任何闪烁或撕裂。我无法重现您的问题,因为您说覆盖表格在覆盖托管表格时闪烁。

如果您不确定托管表单实际上仍在继续渲染,请尝试取消注释第26行,该注释将封面表单的不透明度设置为50%。您将可以看到球在遮挡形式下继续移动。

通过单击它或按一个键来关闭封面表格,将显示托管表格而没有任何问题。当封面消失时,原始表格绘制时,我没有看到任何闪烁或闪烁。

SkiaWinForms:
using SkiaSharp;
using SkiaSharp.Views.Desktop;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SkiaWinForms
{
    [DesignerCategory("Code")]
    class DesktopForm : Form
    {
        readonly Bitmap _bitmap;

        public DesktopForm(Bitmap bitmap)
        {
            _bitmap = bitmap;

            Bounds = Screen.PrimaryScreen.Bounds;
            FormBorderStyle = FormBorderStyle.None;
            DoubleBuffered = true;
            // Opacity = 0.50;

            Click += (o, e) => Close();
            KeyPress += (o, e) => Close();
            Paint += (o, e) =>
            {
                e.Graphics.TranslateTransform(_bitmap.Width, bitmap.Height);
                e.Graphics.ScaleTransform(-1, -1);
                e.Graphics.DrawImage(_bitmap, Point.Empty);
            };
        }
    }

    [DesignerCategory("Code")]
    class MainForm : Form
    {
        readonly Bitmap _screenshot;
        readonly Ball _ball;

        MainForm(Bitmap screenshot, Ball ball, int framesPerSecond)
        {
            _screenshot = screenshot;
            _ball = ball;

            Bounds = Screen.PrimaryScreen.Bounds;
            FormBorderStyle = FormBorderStyle.None;
            DoubleBuffered = true;

            var skcontrol = new SKGLControl() { Dock = DockStyle.Fill };
            skcontrol.PaintSurface += Skcontrol_PaintSurface;
            skcontrol.Click += (o, e) => Close();
            skcontrol.KeyPress += (o, e) => Close();

            var timer = new Timer() { Interval = (int)Math.Round(1000.0 / framesPerSecond) };
            timer.Tick += (o, e) => { _ball.Update(); skcontrol.Invalidate(); };
            timer.Start();

            Controls.Add(skcontrol);
        }

        private void Skcontrol_PaintSurface(object sender, SKPaintGLSurfaceEventArgs e)
        {
            var surface = e.Surface;
            var canvas = surface.Canvas;

            canvas.Clear(SKColors.White);

            canvas.DrawCircle(_ball.Position, _ball.Radius, new SKPaint()
            {
                IsAntialias = true,
                Color = SKColors.Green,
                Style = SKPaintStyle.Fill
            });

            canvas.DrawText($"{DateTime.Now}", 100, 100, new SKPaint()
            {
                TextSize = 64.0f,
                IsAntialias = true,
                Color = SKColors.Red,
                Style = SKPaintStyle.Fill
            });

            canvas.Flush();
        }

        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData.HasFlag(Keys.Escape))
            {
                using (var desktop = new DesktopForm(_screenshot))
                    desktop.ShowDialog();
                return true;
            }

            return base.ProcessDialogKey(keyData);
        }

        static Bitmap CreateScreenshot()
        {
            var rect = Screen.PrimaryScreen.Bounds;
            var bitmap = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
            using (var g = Graphics.FromImage(bitmap))
            {
                g.CopyFromScreen(rect.Location, Point.Empty, rect.Size);
            }
            return bitmap;
        }

        [STAThread]
        static void Main()
        {
            const int FramesPerSecond = 24;

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm(CreateScreenshot(),
                            new Ball(Screen.PrimaryScreen.Bounds, FramesPerSecond),
                            FramesPerSecond));
        }
    }

    class Ball
    {
        readonly Rectangle _bounds;
        SKPoint _vector;
        SKPoint _position;

        public SKPoint Position => _position;
        public float Radius => 200.0f;

        public Ball(Rectangle bounds, int framesPerSecond)
        {
            _bounds = bounds;
            _position.X = _bounds.Width / 2;
            _position.Y = _bounds.Height / 2;

            const int PixelsPerSecond = 150;
            var pixelsPerFrame = (float) PixelsPerSecond / framesPerSecond;
            _vector = new SKPoint(pixelsPerFrame, pixelsPerFrame);
        }

        public void Update()
        {
            (_position.X, _vector.X) = CheckBounds(_position.X, _vector.X, _bounds.Left, _bounds.Right);
            (_position.Y, _vector.Y) = CheckBounds(_position.Y, _vector.Y, _bounds.Top, _bounds.Bottom);

            (float newValue, float newVector) CheckBounds(float value, float vector, float min, float max)
            {
                value += vector;
                if (value + Radius > max)
                {
                    value = max - Radius;
                    vector *= -1;
                }
                else if (value - Radius < min)
                {
                    value = min + Radius;
                    vector *= -1;
                }
                return (value, vector);
            }
        }
    }
}

代码也可以在以下位置找到: azureskydiver / SKIAWinForms
 

立克次体

成员
已加入
2020年1月22日
留言内容
10
编程经验
10+
真是太简单了。我想避免为用户舒适可见的双重形式,但这只是问题。我只是保持激活一个表单的想法,并解决它。我只打开第二个Form,它允许先前的Form渲染,之后我可以在渲染主Form时隐藏我的Cover Form。两者都为DoubleBuffered形式,并且都使加载平滑。从一开始这就是我的问题-如何绘制图像以让Form在后台呈现。答案是,我只需要第二个应用程序即可管理封面。现在,我只是尝试将两个窗体绑定在一起,以防用户以某种方式更改Window的大小,因此我的Cover Form必须具有与Cover Form相同的位置和大小...(为了显示得好,我在显示Cover之前做了一些测试。)我也很感兴趣,如何隐藏我的应用程序的双窗体图标-不会在任务栏等中弄乱...但是,非常感谢您的帮助...
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
我也很感兴趣,如何隐藏应用程序的双窗体图标-不会在任务栏等中弄乱...
如果您不希望表单显示在任务栏中,只需设置 ShowInTaskbar 虚假。但是,如果您的主要表单是全屏的(如您在帖子#1中所述),那么无论如何它将隐藏任务栏,所以我看不到重点。 (有关更多信息,请参见下面的全屏。)

答案是,我只需要第二个应用程序即可管理封面。
You don't need a second app. See how I managed with just a single application in post #18. The trick is to keep the message pump running. In post #18, I did that by using ShowDialog() to create a dialog. A modeless dialog will also work. (For details on modeless dialogs, see WinForms中的无模式对话框 .)

当您的主表单准备运行时,您本质上需要的实际上是一个初始屏幕。为此,您只需将封面表单显示为当前表单顶部的无模式对话框即可,然后在准备好后关闭封面表单。

现在,我只是尝试将两个表单绑定在一起,以防该用户以某种方式更改窗口大小,因此我的Cover Form必须具有与Cover Form相同的位置和大小...
假设您使用的是单个应用程序,则每当您的主表单收到调整大小事件时,告诉您的封面表单也要调整大小。如果您必须拥有2个应用,则需要创建一条自定义WM_USER + n消息并将其发布

不过,在正常情况下,我没有看到您的主表单如何调整大小。在您的帖子1中,您说:
我有一个简单的无边框全屏表格
这意味着如果它是无边界的,将不会有任何大小调整手柄。

唯一一次调整大小是在平板电脑上运行并且用户更改方向,或者在PC或笔记本电脑上并且用户更换显示器时。考虑到您说闪烁仅在第一次显示主窗体时发生,所以发生这种情况的可能性确实很小。闪烁的时间有多长?不到1秒?少于3秒?
 
最佳 底部