我如何修改位图时如何暂停无效? [英] How To Suspend Invalidate While I Make Modifications To Bitmap?

查看:69
本文介绍了我如何修改位图时如何暂停无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们都知道Invalidate是如何工作的。

1.我创建了Vector图像并在Bitmap上绘制。

2.无论我如何,每次在Form1上重绘一次重绘Bitmap。

3.当Invalidate尝试重绘时,我对Bitmap进行了修改。



那么,该怎么办?



注意:我必须只使用.Net库,而不是平台调用。

解决方案

下一种方式有效,但它滞后一点,因为Form1的行为就像它失去了它的焦点。



代码:

  public   static   class  SuspendUpdate 
{
private const int WM_SETREDRAW = 0x000B;

public static void 挂起(控制控件)
{
消息msgSuspendUpdate = Message.Create(control.Handle,WM_SETREDRAW, IntPtr .Zero,
IntPtr .Zero);

NativeWindow window = NativeWindow.FromHandle(control.Handle);
window.DefWndProc( ref msgSuspendUpdate);
}

public static void 恢复(控制控制)
{
IntPtr wparam = new IntPtr 1 );
消息msgResumeUpdate = Message.Create(control.Handle,WM_SETREDRAW,wparam,
IntPtr .Zero);

NativeWindow window = NativeWindow.FromHandle(control.Handle);
window.DefWndProc( ref msgResumeUpdate);

control.Invalidate();
}
}





使用:

 使用系统; 
使用 System.Collections.Generic;
使用 System.ComponentModel;
使用 System.Data;
使用 System.Drawing;
使用 System.Linq;
使用 System.Reflection;
使用 System.Text;
使用 System.Threading;
使用 System.Threading.Tasks;
使用 System.Windows.Forms;

命名空间 WindowsFormsApplication1
{
public partial class Form1:Form
{
public Form1()
{
InitializeComponent();

this .Paint + = Draw;
new Thread(Method))。Start();
}

位图位图= 位图( 200 ,< span class =code-digit> 200 );

private void 绘制(对象发​​送者,PaintEventArgs e)
{
e.Graphics.DrawImage(位图, 0 0 );
}

私有 void 方法()
{
使用(图形g = Graphics.FromImage(位图))
g.Clear(Color.Red);

this .Invoke( new Action(委托
{
SuspendUpdate.Suspend( this ); // 暂停
}));

bitmap = new 位图( 100 100 ); // 暂停时的修改
使用(Graphics g = Graphics.FromImage(bitmap))
g.Clear(Color.Yellow);
this .Invalidate(); // 无效无法绘制

.Invoke( new 操作(委托
{
SuspendUpdate.Resume( this ); // 简历
this .Invalidate();
this .Activate( ); // Active Form1因为它失去焦点
}));
}
}

public static class SuspendUpdate
{
private const int WM_SETREDRAW = 0x000B;

public static void 挂起(控制控件)
{
消息msgSuspendUpdate = Message.Create(control.Handle,WM_SETREDRAW, IntPtr .Zero,
IntPtr .Zero);

NativeWindow window = NativeWindow.FromHandle(control.Handle);
window.DefWndProc( ref msgSuspendUpdate);
}

public static void 恢复(控制控制)
{
IntPtr wparam = new IntPtr 1 );
消息msgResumeUpdate = Message.Create(control.Handle,WM_SETREDRAW,wparam,
IntPtr .Zero);

NativeWindow window = NativeWindow.FromHandle(control.Handle);
window.DefWndProc( ref msgResumeUpdate);

control.Invalidate();
}
}
}


下一步100%确定:

< pre lang =c#> public partial class Form1:Form
{
public Form1()
{
InitializeComponent();

this .Paint + = Draw;
}

位图位图= 位图( 100 ,< span class =code-digit> 100 );
bool ok = true ;

位图bitmapSaved = 位图( 100 100 );
bool saved = false ;

private void 绘制(对象 sender,PaintEventArgs e)
{
if (ok)
e.Graphics.DrawImage(bitmap,< span class =code-digit> 0
0 );
else
{
if (!saved)
{
使用(图形g = Graphics.FromImage(bitmapSaved))
g.DrawImage(bitmap, 0 0 );
saved = true ;
}

e.Graphics.DrawImage(bitmapSaved, 0 0 );
}
}

私有 void 线程( )
{
ok = false ;
this .Invoke( new Action( delegate
{
this .Refresh();
}));
使用(图形g = Graphics.FromImage(位图))
{
/ / 修改位图
}

ok = true ;
saved = false ;
}
}


We all know how Invalidate works.
1. I create Vector image and draw it on Bitmap.
2. Invalidate redraws Bitmap on Form1 every time regardless me.
3. I make modifications to Bitmap when Invalidate attempts to redraw it.

So, what to do?

Note: I have to use only .Net libraries, not Platform Invoke.

解决方案

The next way works, but it lags a bit, because Form1 acts like it loses its Focus.

Code:

public static class SuspendUpdate
{
    private const int WM_SETREDRAW = 0x000B;

    public static void Suspend(Control control)
    {
        Message msgSuspendUpdate = Message.Create(control.Handle, WM_SETREDRAW, IntPtr.Zero,
            IntPtr.Zero);

        NativeWindow window = NativeWindow.FromHandle(control.Handle);
        window.DefWndProc(ref msgSuspendUpdate);
    }

    public static void Resume(Control control)
    {
        IntPtr wparam = new IntPtr(1);
        Message msgResumeUpdate = Message.Create(control.Handle, WM_SETREDRAW, wparam,
            IntPtr.Zero);

        NativeWindow window = NativeWindow.FromHandle(control.Handle);
        window.DefWndProc(ref msgResumeUpdate);

        control.Invalidate();
    }
}



Using:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            this.Paint += Draw;
            (new Thread(Method)).Start();
        }

        Bitmap bitmap = new Bitmap(200, 200);

        private void Draw(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(bitmap, 0, 0);
        }

        private void Method()
        {
            using (Graphics g = Graphics.FromImage(bitmap))
                g.Clear(Color.Red);

            this.Invoke(new Action(delegate
            {
                SuspendUpdate.Suspend(this); // Suspend
            }));

            bitmap = new Bitmap(100, 100); // Modificate while Suspended
            using (Graphics g = Graphics.FromImage(bitmap))
                g.Clear(Color.Yellow);
            this.Invalidate(); // Invalidate does't draw

            this.Invoke(new Action(delegate
            {
                SuspendUpdate.Resume(this); // Resume
                this.Invalidate();
                this.Activate(); // Active Form1 because it loses Focus
            }));
        }
    }

    public static class SuspendUpdate
    {
        private const int WM_SETREDRAW = 0x000B;

        public static void Suspend(Control control)
        {
            Message msgSuspendUpdate = Message.Create(control.Handle, WM_SETREDRAW, IntPtr.Zero,
                IntPtr.Zero);

            NativeWindow window = NativeWindow.FromHandle(control.Handle);
            window.DefWndProc(ref msgSuspendUpdate);
        }

        public static void Resume(Control control)
        {
            IntPtr wparam = new IntPtr(1);
            Message msgResumeUpdate = Message.Create(control.Handle, WM_SETREDRAW, wparam,
                IntPtr.Zero);

            NativeWindow window = NativeWindow.FromHandle(control.Handle);
            window.DefWndProc(ref msgResumeUpdate);

            control.Invalidate();
        }
    }
}


The next way works 100% sure:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        this.Paint += Draw;
    }

    Bitmap bitmap = new Bitmap(100, 100);
    bool ok = true;

    Bitmap bitmapSaved = new Bitmap(100, 100);
    bool saved = false;

    private void Draw(object sender, PaintEventArgs e)
    {
        if (ok)
            e.Graphics.DrawImage(bitmap, 0, 0);
        else
        {
            if (!saved)
            {
                using (Graphics g = Graphics.FromImage(bitmapSaved))
                    g.DrawImage(bitmap, 0, 0);
                saved = true;
            }

            e.Graphics.DrawImage(bitmapSaved, 0, 0);
        }
    }

    private void Thread()
    {
        ok = false;
        this.Invoke(new Action(delegate
        {
            this.Refresh();
        }));
        using (Graphics g = Graphics.FromImage(bitmap))
        {
            // Modificate bitmap
        }

        ok = true;
        saved = false;
    }
}


这篇关于我如何修改位图时如何暂停无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆