Previous | Index | Next 

[PRB] Using the hDC property causes an InvalidOperationException error

VB Migration Partner supports the hDC property of forms, user controls, and regular controls. However, when a .NET program acquires the handle of a GDI device context, the device context becomes “locked” until you explicitly release it. If the application attempts to display any user interface or graphic element on the control, the .NET runtime throws an InvalidOperationException error whose message reads “Object is currently in use elsewhere”.

If you experience this error, you must ensure that you release the GDI handle as soon as you don’t need it any longer. You do this by calling the ReleaseHdc method that the VB6Form, VB6PictureBox, and VB6UserControl classesexpose. Here’ s an example of a piece of VB6 code that calls for this treatment:

        ' display all sprites
        For n = 1 To spriteNumber - 1
            BitBlt(Picture1.hDC, n* 32 - 32, 0, 32, 32, Picture2.hDC, 96, 224, SRCCOPY)
        Next

        ' display all the images
        For i = 0 To imageNum - 1
            BitBlt(Picture1.hDC, 416 – i * 32, 0, 32, 32, Picture2.hDC, X, Y, SRCCOPY)
        Next

        ' refresh the form
        Me.Refresh

It is converted to VB.NET as follows:

        ' display all sprites
        For n = 1 To spriteNumber - 1
            ' UPGRADE_ISSUE (#1478): The hDC property requires that the ReleaseHdc method be 
            ' invoked when the hDC handle isn't used any longer.
            BitBlt(Picture1.hDC, n* 32 - 32, 0, 32, 32, Picture2.hDC, 96, 224, SRCCOPY)
        Next
			
        ' display all the images
        For i = 0 To imageNum - 1
            ' UPGRADE_ISSUE (#1478): The hDC property requires that the ReleaseHdc method be 
            ' invoked when the hDC handle isn't used any longer.
            BitBlt(Picture1.hDC, 416 – i * 32, 0, 32, 32, Picture2.hDC, X, Y, SRCCOPY)
        Next

        ' refresh the form
        Me.Refresh()

At runtime the last statement throws the InvalidOperationException error, thus it is essential that you release the Picture1.hDC and Picture2.hDC handles before the Me.Refresh method. You can fix the original code as follows:

        ' display all sprites
        For n = 1 To spriteNumber - 1
            BitBlt(Picture1.hDC, n* 32 - 32, 0, 32, 32, Picture2.hDC, 96, 224, SRCCOPY)
        Next
			
        ' display all the images
        For i = 0 To imageNum - 1
            BitBlt(Picture1.hDC, 416 – i * 32, 0, 32, 32, Picture2.hDC, X, Y, SRCCOPY)
        Next
			
        '## InsertStatement Picture1.ReleaseHdc()
        '## InsertStatement Picture2.ReleaseHdc()
        Me.Refresh

Alternatively, you can use the ReleaseHdc6 method defined in the VBMigrationPartner_Support module, which takes any number of controls as arguments and invokes the ReleaseHdc method on each of them:

        ' display all sprites
        For n = 1 To spriteNumber - 1
            BitBlt(Picture1.hDC, n* 32 - 32, 0, 32, 32, Picture2.hDC, 96, 224, SRCCOPY)
        Next
			
        ' display all the images
        For i = 0 To imageNum - 1
            BitBlt(Picture1.hDC, 416 – i * 32, 0, 32, 32, Picture2.hDC, X, Y, SRCCOPY)
        Next
			
        ReleaseHdc6 Picture1, Picture2
        Me.Refresh

 

Previous | Index | Next