嵌入式字体导致系统崩溃 [英] Embedded Font Causes a Crash

查看:394
本文介绍了嵌入式字体导致系统崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WinForm程序。我使用的是自定义的字体,在我的嵌入的资源。
它工作在第一,但随后导致程序一段时间后死机。
使用下面的code作为一个例子,如果我继续调整的形式,迫使其不断地重新绘制本身,它会在几秒钟内崩溃。我得到的消息是Form1_Paint 中的错误()。对象是目前在其他地方使用。
我究竟做错了什么?我怎样才能避免这种情况?
我从在这里得到的字体。
谢谢你。

 进口System.Drawing.Text
进口了System.Runtime.InteropServices

公共类Form1中
    朋友Harabara由于字体

    私人小组Form1_Load的(BYVAL发件人为System.Object的,BYVALË作为System.EventArgs)把手MyBase.Load
        LoadFonts()
    结束小组

    私人小组Form1_Paint(BYVAL发件人为对象,BYVAL E上System.Windows.Forms.PaintEventArgs)处理Me.Paint
        尝试
            e.Graphics.DrawString(这是使用自定义字体Harabara绘制,Harabara,Brushes.Lime,10.0F,10.0F)
        抓住EX为例外
            MSGBOX(在Form1_Paint错误()与& vbCrLf&安培; ex.Message)
        结束尝试
    结束小组

    公用Sub LoadFonts()
        尝试
            Harabara = GetFontInstance(My.Resources.HarabaraHand,24.0F,FontStyle.Italic)
        抓住EX为例外
            MSGBOX(在错误'LoadFonts()与& vbCrLf&安培; ex.Message)
        结束尝试
    结束小组

    专用功能GetFontInstance(BYVAL数据()为字节,大小BYVAL单,BYVAL风格fontstyle的)由于字体
        昏暗的结果作为字体
        尝试
            昏暗的PFC =新PrivateFontCollection
            装载内存的指针字体资源
            昏暗FontPtr作为System.IntPtr = Marshal.AllocCoTaskMem(data.Length)
            将数据复制到内存位置
            Marshal.Copy(数据,0,FontPtr,data.Length)
            加载存储器FONT到私有字体集合
            pfc.AddMemoryFont(FontPtr,data.Length)
            免费的安全存储器
            Marshal.FreeCoTaskMem(FontPtr)

            结果=新字体(pfc.Families(0),大小,样式)
            pfc.Families(0).Dispose()
            pfc.Dispose()
        抓住EX为例外
            错误加载字体。处理异常HERE
            MSGBOX(放大器,在GetFontInstance()'错误; vbCrLf&安培; ex.Message)
            结果=新字体(FontFamily.GenericMonospace,8)
        结束尝试
        返回结果
    端功能
末级
 

解决方案

  Marshal.FreeCoTaskMem(FontPtr)
 

MSDN文档PrivateFontCollection太钝这个问题。但是,你需要保持内存为添加的字体有效,直到你不能再使用的字体。或者换一种说法,AddMemoryFont()做的不可以使字体的副本。所以,你的程序将翻倒带有神秘色彩的GDI +错误,当它试图访问的字体数据,并得到了覆盖由其他非托管内存分配。

将FreeCoTaskMem()调用一个FormClosed事件处理程序。还是不要打扰,如果关闭窗体也终止程序。

I have a WinForm app. I am using a custom font that is in my embedded resources.
It works at first, but then causes the program to crash after a while.
Using the following code as an example, if I keep resizing the form, forcing it to constantly redraw itself, it will crash within a few seconds. The message I get is 'Error in 'Form1_Paint()'. Object is currently in use elsewhere.'.
What am I doing wrong? How can I avoid this?
I got the font from here.
Thanks.

Imports System.Drawing.Text
Imports System.Runtime.InteropServices

Public Class Form1
    Friend Harabara As Font

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        LoadFonts()
    End Sub

    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        Try
            e.Graphics.DrawString("This was drawn using the custom font 'Harabara'", Harabara, Brushes.Lime, 10.0F, 10.0F)
        Catch ex As Exception
            MsgBox("Error in Form1_Paint()'" & vbCrLf & ex.Message)
        End Try
    End Sub

    Public Sub LoadFonts()
        Try
            Harabara = GetFontInstance(My.Resources.HarabaraHand, 24.0F, FontStyle.Italic)
        Catch ex As Exception
            MsgBox("Error in 'LoadFonts()'" & vbCrLf & ex.Message)
        End Try
    End Sub

    Private Function GetFontInstance(ByVal data() As Byte, ByVal Size As Single, ByVal Style As FontStyle) As Font
        Dim result As Font
        Try
            Dim pfc = New PrivateFontCollection
            'LOAD MEMORY POINTER FOR FONT RESOURCE
            Dim FontPtr As System.IntPtr = Marshal.AllocCoTaskMem(data.Length)
            'COPY THE DATA TO THE MEMORY LOCATION
            Marshal.Copy(data, 0, FontPtr, data.Length)
            'LOAD THE MEMORY FONT INTO THE PRIVATE FONT COLLECTION
            pfc.AddMemoryFont(FontPtr, data.Length)
            'FREE UNSAFE MEMORY
            Marshal.FreeCoTaskMem(FontPtr)

            result = New Font(pfc.Families(0), Size, Style)
            pfc.Families(0).Dispose()
            pfc.Dispose()
        Catch ex As Exception
            'ERROR LOADING FONT. HANDLE EXCEPTION HERE
            MsgBox("Error in 'GetFontInstance()'" & vbCrLf & ex.Message)
            result = New Font(FontFamily.GenericMonospace, 8)
        End Try
        Return result
    End Function
End Class

解决方案

        Marshal.FreeCoTaskMem(FontPtr)

The MSDN documentation for PrivateFontCollection is too obtuse about this. But you need to keep the memory for the added font valid until you can no longer use the font. Or to put it another way, AddMemoryFont() does not make a copy of the font. So your program will fall over with a mysterious GDI+ error when it tries to access the font data and it got overwritten by another unmanaged memory allocation.

Move the FreeCoTaskMem() call to a FormClosed event handler. Or don't bother if closing the form also terminates your program.

这篇关于嵌入式字体导致系统崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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