对于两个小组为何工作不同感到困惑

时间:2019-06-20 23:18:28

标签: c# winforms winapi

我有一个使我真正困惑的问题。让我奠定一些背景。我正在尝试开发自己的编辑器控件。我希望有一个闪烁的插入符号,我知道我可以使用CreateCaret,ShowCaret ect来做到这一点,但这不是我想要的方式,我希望自己实现。我的插入符号没有眨眼,我也不明白为什么。

我尝试实现此目的的方法是将插入符下方的区域缓存起来,然后显示插入符。然后半秒后,我将缓存的数据重新绘制回编辑器控件,从而实现了插入符号的闪烁。我已经尝试过仅使用图形对象和位图作为缓存,但均不起作用,但我想我知道为什么。所以我决定尝试。我通过设计器在窗体本身上设置了一个面板,其中一个面板被编码为Caret类本身。窗体上的面板有效,但封装在类中的面板无效,我也不知道为什么。我的问题是为什么?

下面是代码。 BlinkTimer_Tick方法仅导致闪烁。绘制只是绘制插入符号,这些都不应该很难理解。

BackupBackground将插入符号下方的区域复制到缓存,而RestoreBackground将缓存复制到控件。现在的问题是,如果您在两种方法中都注释掉了用“如果此行被注释掉,则为Works”注释的行,则它们都可以工作,但是当这些注释不起作用时,插入记号不会闪烁。这两个面板的设置相同。

    private void BlinkTimer_Tick(object sender, EventArgs e)
    {
        Paint();
        _BlinkTimer.Start();
    }

    private void BackupBackground(Graphics SrcGraph)
    {
        Form TF = _Parent.FindForm() as Form;
        Panel P = TF.Controls["_TestPanel"] as Panel;
        P = _Buffer; // Works if this line is Commentted out

        Graphics DestGraph = P.CreateGraphics();

        IntPtr SrcHDC = SrcGraph.GetHdc();
        IntPtr DestHDC = DestGraph.GetHdc();

        BitBlt(DestHDC, 0, 0, _Size.Width, _Size.Height,
               SrcHDC, _Location.X, _Location.Y, TernaryRasterOperations.SRCCOPY);

        DestGraph.ReleaseHdc(DestHDC);
        SrcGraph.ReleaseHdc(SrcHDC);
    }

    private void RestoreBackground(Graphics DestGraph)
    {
        Form TF = _Parent.FindForm() as Form;
        Panel P = TF.Controls["_TestPanel"] as Panel;
        P = _Buffer; // Works if this line is Commentted out

        Graphics SrcGraph = P.CreateGraphics();

        IntPtr SrcHDC = SrcGraph.GetHdc();
        IntPtr DestHDC = DestGraph.GetHdc();

        BitBlt(DestHDC, _Location.X, _Location.Y, _Size.Width, _Size.Height,
               SrcHDC, 0, 0, TernaryRasterOperations.SRCCOPY);

        DestGraph.ReleaseHdc(DestHDC);
        SrcGraph.ReleaseHdc(SrcHDC);
    }

    internal void Paint()
    {
        Graphics Graph = _Parent.CreateGraphics();
        if (!_BlinkOn)
        {
            // Restore Graphics from Backup
            RestoreBackground(Graph);

            _BlinkOn = true;
        }
        else
        {
            // Backup Graphics
            Graph.Flush();
            BackupBackground(Graph);

            // Draw Caret
            using (SolidBrush P = new SolidBrush(Color.Black))
            {
                Graph.FillRectangle(P, new Rectangle(_Location, _Size));
            }

            _BlinkOn = false;
        }
    }

在两种情况下,插入记号均应闪烁,因为我并未真正更改任何内容,但仅当我使用窗体上的面板时,它才会闪烁。

注意:我不打算将Panel用于刚刚尝试的缓存,并且发现了此行为及其怪异,所以我需要知道。

谢谢丹尼。

0 个答案:

没有答案