前两天做都还没有问题的,今天启动工程,运行的时候不是出错,而是IDE整个死掉。于是我就在整个程序开始的地方开始调试,发现到了GdipTranslateRegion VolumeBarBregion, (X - xl) * 1.03, 0时就会死掉。也不知道为什么。我是将GDI+用到控件设计中,下面的代码是绘制界面的。按道理来说在用GdipCreateFromHDC函数创建一个graphics对象之后,只要这个对象不被销毁,在后续的绘图中就应该可以一直使用它。但实际上却不行,每一次绘图都要重新调用GdiplusStartup函数和GdipCreateFromHDC函数,不调用的话就画不出任何图像(在下面的代码中,有一个Terminate子程序,里面的GdipDeleteGraphics graphics语句即使去掉也不行)。也不知道为什么。

解决方案 »

  1.   


    '公共变量声明
    Dim graphics As Long
    Dim pen As Long
    Dim bursh As Long
    Dim p1 As POINTF, p2 As POINTF
    Dim Path As Long
    Dim result As Long
    Dim Bregion  As Long
    Dim Color As ColorParts
    '特定变量
    Public PlayBregion As Long
    Public StopBregion As Long
    Public QuietBregion As Long
    Public VolumeBarBregion As Long
    Public Down As Boolean
    Public xl As Single
    Public LastVolume As Integer'State=0(缺省,默认),1(鼠标移过),2(鼠标按下)
    Public Sub DrawDefault(ByRef UserControls As MutilePlayer)  '默认状态下的控制栏
    '控制栏高度:55像素    UserControls.Cls '清空界面
        GetGDIPlus UserControls '初始化GDI+
        
        '绘制播放按钮
            PlayButton UserControls
        '绘制停止按钮
            StopButton UserControls
        '绘制声音按钮
            QuietButton UserControls
        '调音量
            VolumeBar UserControls, xl, True
        '绘制边框
            DrawBorder UserControls
        '释放资源占用
            Terminate
    End SubPublic Sub BPlayActive(ByRef UserControls As MutilePlayer, Optional State As Integer = 0) '播放按钮
        GetGDIPlus UserControls '初始化GDI+
        
        p1.X = UserControls.Width / 30 - 62.5
        p1.Y = UserControls.Height / 15 - 45    '添加裁剪区
            GdipSetClipRectI graphics, p1.X - 1, p1.Y - 1, 41, 41, CombineModeReplace
        '返回各组分颜色
            Color = GetColorPart(UserControls.BackColor)
        '清除图像
            GdipGraphicsClear graphics, "&HFF" & Hex(Color.Red) & Hex(Color.Green) & Hex(Color.Bule)
            UserControls.refresh
        '绘制播放按钮
            PlayButton UserControls, State
            UserControls.refresh
        '释放裁剪区
            GdipResetClip graphics
        '释放资源占用
            Terminate
    End SubPublic Sub BStopActive(ByRef UserControls As MutilePlayer, Optional State As Integer = 0) '停止按钮
        GetGDIPlus UserControls '初始化GDI+
        
        p1.X = UserControls.Width / 30 - 85
        p1.Y = UserControls.Height / 15 - 32    '添加裁剪区
            GdipSetClipRectI graphics, p1.X - 1, p1.Y - 1, 16, 16, CombineModeReplace
        '返回各组分颜色
            Color = GetColorPart(UserControls.BackColor)
        '清除图像
            GdipGraphicsClear graphics, "&HFF" & Hex(Color.Red) & Hex(Color.Green) & Hex(Color.Bule)
            UserControls.refresh
        '绘制停止按钮
            StopButton UserControls, State
            UserControls.refresh
        '释放裁剪区
            GdipResetClip graphics
        '释放资源占用
            Terminate
    End SubPublic Sub BQuietActive(ByRef UserControls As MutilePlayer, Optional State As Integer = 0) '音量按钮
        GetGDIPlus UserControls '初始化GDI+
        
        p1.X = UserControls.Width / 30 - 18
        p1.Y = UserControls.Height / 15 - 31    '添加裁剪区
            GdipSetClipRectI graphics, p1.X - 1, p1.Y - 1, 16, 16, CombineModeReplace
        '返回各组分颜色
            Color = GetColorPart(UserControls.BackColor)
        '清除图像
            GdipGraphicsClear graphics, "&HFF" & Hex(Color.Red) & Hex(Color.Green) & Hex(Color.Bule)
            UserControls.refresh
        '绘制停止按钮
            QuietButton UserControls, State
            UserControls.refresh
        '释放裁剪区
            GdipResetClip graphics
        '释放资源占用
            Terminate
    End SubPublic Sub ChangeVolumeBar(ByRef UserControls As MutilePlayer, X As Single, OnlyReDraw As Boolean) '调音量
    'OnlyReDraw指定程序只重画,不再修改Volume属性的值    GetGDIPlus UserControls '初始化GDI+
        
        p1.X = UserControls.Width / 30
        p1.Y = UserControls.Height / 15 - 31    '添加裁剪区
            GdipSetClipRectI graphics, p1.X - 1, p1.Y - 1, 87, 15, CombineModeReplace
        '返回各组分颜色
            Color = GetColorPart(UserControls.BackColor)
        '清除图像
            GdipGraphicsClear graphics, "&HFF" & Hex(Color.Red) & Hex(Color.Green) & Hex(Color.Bule)
            UserControls.refresh
        '调音量
            VolumeBar UserControls, X, OnlyReDraw
            UserControls.refresh
        '释放裁剪区
            GdipResetClip graphics
        '释放资源占用
            Terminate
    End Sub'------------------------------------------
    '分步代码
    '------------------------------------------
    Public Sub PlayButton(ByRef UserControls As MutilePlayer, Optional State As Integer = 0)
        '绘制播放/停止按钮
    ……
    End SubPublic Sub StopButton(ByRef UserControls As MutilePlayer, Optional State As Integer = 0)
        '绘制停止按钮
    ……
    End SubPublic Sub QuietButton(ByRef UserControls As MutilePlayer, Optional State As Integer = 0)
        '绘制声音/静音按钮
    ……
    End SubPublic Sub VolumeBar(ByRef UserControls As MutilePlayer, X As Single, OnlyReDraw As Boolean) '音量条
    '绘制音量条
        p1.X = UserControls.Width / 30
        p1.Y = UserControls.Height / 15 - 31
        p2.X = p1.X + 12
        p2.Y = p1.Y + 12    If VolumeBarBregion = 0 Then '没有区域就先初始化
            GdipCreatePath FillModeWinding, Path
            '创建路径
            GdipAddPathEllipse Path, p1.X, p1.Y, 12, 12
            '添加路径
            GdipCreateRegionPath Path, VolumeBarBregion
            '转换路径成区域
        End If
        
        '绘制横条
            GdipCreateLineBrush p1, p2, &HFFFFF000, &HFFFF6000, WrapModeTileFlipXY, bursh
            '创建路径
            GdipDeletePath Path
            Path = 0
            GdipCreatePath FillModeWinding, Path
            '添加路径
            GdipAddPathArc Path, p1.X, p1.Y + 2, 8, 8, 90, 180
            GdipAddPathLine Path, p1.X + 8, p1.Y + 2, p1.X + 75, p1.Y + 2
            GdipAddPathArc Path, p1.X + 75, p1.Y + 2, 8, 8, -90, 180
            GdipAddPathLine Path, p1.X + 8, p1.Y + 10, p1.X + 75, p1.Y + 10
            '填充路径
            GdipFillPath graphics, bursh, Path
            
        '绘制按钮
            '创建刷子
            GdipCreateLineBrush p1, p2, &HFF0024FF, &HFF00FF24, WrapModeTileFlipXY, bursh
            '移动区域
            If X > UserControls.Width / 30 + 8 And X < UserControls.Width / 30 + 75 Then '96是音量条的最大长度
                GdipTranslateRegion VolumeBarBregion, (X - xl) * 1.03, 0'这里会出错
            End If
            '绘制新的按钮
            GdipFillRegion graphics, bursh, VolumeBarBregion
            '重设当前位置
            xl = X
            
            If OnlyReDraw = False Then
                '调整音量的值
                UserControls.Volume(True) = (xl - UserControls.Width / 30) / 96 * 100
            End If
    End SubPublic Sub DrawBorder(ByRef UserControls As MutilePlayer)
        '绘制边框
    ……
    End SubPublic Sub Terminate() '释放graphics占用的内存
        GdipDeletePath Path
        GdipDeletePen pen
        GdipDeleteBrush bursh
        GdipDisposeImage img
        GdipDeleteGraphics graphics
        TerminateGDIPlus
    End SubPrivate Function GetColorPart(ByVal colors As Long) As ColorParts '分离颜色
      ……
    End FunctionPublic Sub GetGDIPlus(ByRef UserControls As MutilePlayer)
    InitGDIPlus '初始化GDI+
    GdipCreateFromHDC UserControls.hDC, graphics '创建一个graphics对象,但实际上我们只需要保存下地址即可
    GdipSetSmoothingMode graphics, SmoothingModeAntiAlias '抗锯齿
    End Sub
      

  2.   

    看看这个http://blog.vbgood.com/blog-94128-34201.html
    你的代码我没有看到运行了 GdiplusStartup gToken, GDIsi 这个启动命令,该命令gdi+中是必须的
      

  3.   

    上面的代码直接粘到IDE上去是没用的,因为还有控件本身的代码,调试控件的EXE工程的代码,等等。不过问题是到底GdiplusStartup应该要在那里调用,是不是真的就像我上面说的那样每一个子过程都要调用一次?还有,听说GDI+的一些对象如果忘了释放就会引发IDE死掉,能列举一些这样的强狂骂?就是那些对象或资源没有释放会让IDE死掉?
      

  4.   

    过程开始的时候使用
    GdiplusStartup
    结束的时候使用
    GdiplusShutdown 两者之间进行输出操作啊
      

  5.   

    http://download.csdn.net/detail/veron_04/4814790
      

  6.   

    VB中用GDI+要在sub main或者程序的最开始的执行初始化(GdiplusStartup),在程序结束的时候调用GdiplusShutdown ,不要多次初始化。然后UserControls.Cls会导致原先用GdipCreateFromHDC创建的 Graphics对象无效的,所以必须重新创建。看看这篇文章在增加点理解吧http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=69434&lngWId=1
    FYI: GDI+ Crash in IDE