创建图标

时间:2015-10-15 18:01:30

标签: vb.net memory-leaks icons gdi+ system.drawing

我的智慧结束了这个。我有一个返回图标的功能。我的问题是,当应用程序运行并且正在使用该功能时,我可以看到我的应用程序内存使用率攀升。几分钟后,我将得到一个" GDI +"这导致我的应用程序崩溃。 我已经浏览了论坛并找到了建议,但我尝试过的任何内容似乎都无法解决问题。在函数末尾添加.dispose()会延长发生这种情况之前的时间长度但不会停止它。 这是我的问题的代码:

Private Function drawIcon(ByVal frameColor As Color, ByVal numColor As Color, ByVal capColor As Color, ByVal scrColor As Color)
    Dim ti As Icon
    Dim bmp As New Bitmap(16, 16)
    Dim bmpgraphics As Graphics = Graphics.FromImage(bmp)
    Using bmpgraphics
        Dim framePen As New Pen(frameColor)
        Dim numBrush As New SolidBrush(numColor)
        Dim capBrush As New SolidBrush(capColor)
        Dim scrBrush As New SolidBrush(scrColor)
        Dim strip As Integer = 64 / 3
        'outside
        Dim numFrame As Rectangle = New Rectangle(0, 0, strip, 16 - 1)
        Dim capFrame As Rectangle = New Rectangle(strip, 0, strip, 16 - 1)
        Dim scrFrame As Rectangle = New Rectangle(strip * 2, 0, strip, 16 - 1)
        ' inside
        Dim numInside As Drawing.Rectangle = New Rectangle(1, 1, strip - 1, 16 - 2)
        Dim capInside As Drawing.Rectangle = New Rectangle(strip + 1, 1, strip - 1, 16 - 2)
        Dim scrInside As Drawing.Rectangle = New Rectangle(strip * 2 + 1, 1, strip - 1, 16 - 2)
        ' do the drawing
        With bmpgraphics
            .DrawRectangle(framePen, numFrame)
            .DrawRectangle(framePen, capFrame)
            .DrawRectangle(framePen, scrFrame)
            .FillRectangle(numBrush, numInside)
            .FillRectangle(capBrush, capInside)
            .FillRectangle(scrBrush, scrInside)
        End With
        'Dim tmpBmp As New Bitmap(bmp)
        'ti = Drawing.Icon.FromHandle(tmpBmp.GetHicon)
        'tmpBmp.Dispose()
        ti = Drawing.Icon.FromHandle(bmp.GetHicon)
    End Using
    bmp.Dispose()
    bmpgraphics.Dispose()
    Return ti
End Function

2 个答案:

答案 0 :(得分:0)

在另一个网站上找到此修复程序。没有想到书签,似乎无法将其从历史中挖掘出来。一旦我添加了DestroyIcon功能,我的程序启动并运行了8个多小时,内存使用率上升然后

    Private Declare Auto Function DestroyIcon Lib "user32" (ByVal hIcon As IntPtr) As Boolean

    Private Function drawIcon(ByVal frameColor As Color, ByVal numColor As Color, ByVal capColor As Color, ByVal scrColor As Color)
    Dim bmp As New Bitmap(16, 16)
    Dim bmpgraphics As Graphics = Graphics.FromImage(bmp)
    Using bmpgraphics ' As Graphics = Graphics.FromImage(pb.Image)
        Dim ti As Icon
        Dim framePen As New Pen(frameColor)
        Dim numBrush As New SolidBrush(numColor)
        Dim capBrush As New SolidBrush(capColor)
        Dim scrBrush As New SolidBrush(scrColor)
        Dim strip As Integer = 64 / 3
        'outside
        Dim numFrame As Rectangle = New Rectangle(0, 0, strip, 16 - 1)
        Dim capFrame As Rectangle = New Rectangle(strip, 0, strip, 16 - 1)
        Dim scrFrame As Rectangle = New Rectangle(strip * 2, 0, strip, 16 - 1)
        ' inside
        Dim numInside As Drawing.Rectangle = New Rectangle(1, 1, strip - 1, 16 - 2)
        Dim capInside As Drawing.Rectangle = New Rectangle(strip + 1, 1, strip - 1, 16 - 2)
        Dim scrInside As Drawing.Rectangle = New Rectangle(strip * 2 + 1, 1, strip - 1, 16 - 2)
        ' do the drawing
        With bmpgraphics
            .DrawRectangle(framePen, numFrame)
            .DrawRectangle(framePen, capFrame)
            .DrawRectangle(framePen, scrFrame)
            .FillRectangle(numBrush, numInside)
            .FillRectangle(capBrush, capInside)
            .FillRectangle(scrBrush, scrInside)
        End With
        'Dim tmpBmp As New Bitmap(bmp)
        'ti = Drawing.Icon.FromHandle(tmpBmp.GetHicon)
        'tmpBmp.Dispose()
        'ti = Drawing.Icon.FromHandle(bmp.GetHicon)

        Dim hicon As IntPtr = bmp.GetHicon()
        Dim bitmapIcon As Icon = Icon.FromHandle(hicon)
        DestroyIcon(bitmapIcon.Handle)
        Return bitmapIcon
    End Using
    bmp.Dispose()
    bmpgraphics.Dispose()
End Function

答案 1 :(得分:0)

另一种方法是在程序启动时构建一个Icons数组,然后从那里获取所需的图标,而不是每次从位图转换它。

Module MyModule
    Public IconList16() As Icon

    Sub BuildIconList(SourceImgList as ImageList)
        ' Builds up Icon List from provided ImageList
        Dim q As Int16
        Dim bmp As Bitmap = Nothing

        ReDim IconList16(MainForm.Icons16.Images.Count - 1)
        For q = 0 To UBound(IconList16)
            bmp = SourceImgList.Images(q)
            IconList16(q) = Icon.FromHandle(bmp.GetHicon)
        Next
        bmp.Dispose()

    End Sub

    (...)

    Sub AnySub()
        Dim IconID as Integer

        ' Initialize IconList16
        Call BuildIconList(Form1.ImageList1)                
        (...)
            (do stuff)
        (...)
        IconID = [**ChosenValue**]                      ' Just make sure IconID is set to a value which is in IconList16 bounds...
        AnySuitableObject.Icon = Iconlist16(IconID)     ' AnySuitableObject: any object, having .Icon property, of course.

End Sub

结束模块