Search code examples
vb.netvb6drawingvb6-migrationgdi

System.Drawing.dll threw an unhandled exception of type 'System.ArgumentException' when Graphics.GetHdc is used


I am translating codes from VB6 to VB .NET.

Here is the VB6 code:

retval = BitBlt(Picture1.hdc, 0, 0, Picture1.Width, Picture1.Height, jdc, 0, 0, SRCCOPY)

The equivalent VB .NET code is:

Dim gr As Graphics = Picture1.CreateGraphics()
Dim hdc As IntPtr = gr.GetHdc()

g_variable3D.retval = BitBlt(hdc, 0, 0, Picture1.Width, Picture1.Height, g_variable3D.jdc, 
        0, 0, TernaryRasterOperations.SRCCOPY)

When I run the codes, I got an error message from:

Dim hdc As IntPtr = gr.GetHdc()

The error message says:

An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll. Additional information: Parameter is not valid.

Here is the stack trace:

StackTrace:
    at System.Drawing.Graphics.GetHdc()      
    at frm3D.vb:line 313
    at frm3D.Picture1_MouseMove(Object sender, MouseEventArgs e) in frm3D.vb:line 1176
    at System.Windows.Forms.Control.OnMouseMove(MouseEventArgs e)
    at System.Windows.Forms.Control.WmMouseMove(Message& m)
    at System.Windows.Forms.Control.WndProc(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
    at My.MyApplication.Main(String[] Args) in :line 81
      InnerException: 

I have checked various websites and forums but I could not find a clue on solving this problem.

How can I handle this exception? What parameter is not valid here?


Solution

  • Yes, this will happen eventually. Won't take very long in a MouseMove event handler. As the documentation for Graphics.GetHdc() does not fail to point out, you must call ReleaseHdc() to release the device context again.

    Allocating too many of them gets the operating system upset. It will pull the plug and won't let you allocate more. The exception is a bit confusing, GDI does not provide error information. This is something you can see in Task Manager, Processes tab. Use View > Select columns and tick GDI Objects and USER Objects. You should see the first one steadily climbing as you move the mouse. The show usually ends at 10,000 objects.