System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。而且报错并不在这个ProgressBar的重绘函数WndProc中,而是在另一个线程的Excel.Application.Close()处报错;
当然从时间和执行顺序上估算,正好是ProgressBar控件所在窗口关闭时调用Excel.Application.Close()。protected override void WndProc(ref Message m)
{
const int WM_PAINT = 0x000F;
base.WndProc(ref m);
if (control == null) return;
switch (m.Msg)
{
case WM_PAINT:
IntPtr vDC = GetWindowDC(m.HWnd);
Graphics vGraphics = Graphics.FromHdc(vDC);
StringFormat vStringFormat = new StringFormat();
vStringFormat.Alignment = StringAlignment.Center;
vStringFormat.LineAlignment = StringAlignment.Center;
vGraphics.DrawString(text , font , new SolidBrush(foreColor) , new Rectangle(0 , 0 , control.Width , control.Height) , vStringFormat);
ReleaseDC(m.HWnd , vDC);
break;
}
//删掉这一句就没问题了
base.WndProc(ref m);
}

解决方案 »

  1.   

    某些消息处理后,会吧lparam和wparam修改掉。这2个参数可能记录的是某个内存块的指针,使用后会被释放,多次调用会访问越界使用野指针报错。具体,可能是和字符串相关的,或某个消息的参数是一个结构体类型的堆栈对象。
      

  2.   

    这样好一点
    private const int WM_PAINT = 0x000F;
    protected override void WndProc(ref Message m)
    {
    if(m.Msg == WM_PAINT && control != null)
    {
    IntPtr vDC = GetWindowDC(m.HWnd);
    Graphics vGraphics = Graphics.FromHdc(vDC);
    StringFormat vStringFormat = new StringFormat();
    vStringFormat.Alignment = StringAlignment.Center;
    vStringFormat.LineAlignment = StringAlignment.Center;
    vGraphics.DrawString(text , font , new SolidBrush(foreColor) , new Rectangle(0 , 0 , control.Width , control.Height) , vStringFormat);
    ReleaseDC(m.HWnd , vDC);
    }    
        base.WndProc(ref m);
    }
      

  3.   


    base.WndProc(ref m);放在后面为什么不会把前面的绘图操作给覆盖了呢
      

  4.   

    WM_PAINT会调用OnPaint触发Paint事件。如果你事件空的自然就不会有问题。
    只有public const int WM_ERASEBKGND = 0x14;才会重绘背景,这个是默认实现的。你调用消息处理会更新屏幕。
      

  5.   

    不行……刚试了下,如果吧base.WndProc放后面,重绘的文本几乎看不到,不停的闪烁,大概是被base.WndProc覆盖掉了吧
      

  6.   

    那你可以不调用private const int WM_PAINT = 0x000F;
    protected override void WndProc(ref Message m)
    {
        if(m.Msg == WM_PAINT && control != null)
        {
            IntPtr vDC = GetWindowDC(m.HWnd);
            Graphics vGraphics = Graphics.FromHdc(vDC);
            StringFormat vStringFormat = new StringFormat();
            vStringFormat.Alignment = StringAlignment.Center;
            vStringFormat.LineAlignment = StringAlignment.Center;
            vGraphics.DrawString(text , font , new SolidBrush(foreColor) , new Rectangle(0 , 0 , control.Width , control.Height) , vStringFormat);
            ReleaseDC(m.HWnd , vDC);
            return;
        }
        base.WndProc(ref m);
    }