OutOfMemory Exception with DrawGdPictureImageOnHDC

Discussions about document printing in GdPicture.NET using GdPictureImaging.
Post Reply
brian611
Posts: 5
Joined: Mon Apr 23, 2012 6:15 pm

OutOfMemory Exception with DrawGdPictureImageOnHDC

Post by brian611 » Mon Apr 23, 2012 6:48 pm

Hello,

I am currently trying to print a pdf file, actually just the first page, to a printer that is already defined by a calling application. So my application receives from the other application a HDC representing the printer. When I execute the following code I get an OutOfMemory Exception when the DrawGdPictureImageOnHDC method returns:

Code: Select all

            int imageID = 0;
            GdPictureImaging pictureImage = null;
            GdPicture.LicenseManager oLicenceManager = new GdPicture.LicenseManager();
            oLicenceManager.RegisterKEY("xxx");

            GdPicturePDF _pdf = new GdPicturePDF();

            if (_pdf.LoadFromFile(@"C:\Temp\gdtest.pdf", true) != GdPictureStatus.OK)
                throw new InvalidOperationException(string.Format("Unable to load PDF from file. Error status: {0}", _pdf.GetStat()));

            if (!_pdf.SelectPage(1))
                throw new InvalidOperationException(string.Format("Unable to select page. Error status: {0}", _pdf.GetStat()));

            imageID = _pdf.RenderPageToGdPictureImageEx(96, true);

            if (imageID == 0)
                throw new InvalidOperationException(string.Format("Unable to render page as image. Error status: {0}", _pdf.GetStat()));

            pictureImage = new GdPictureImaging();

            pictureImage.DrawGdPictureImageOnHDC(imageID, printHDC, 0, 0, 816, 1052, System.Drawing.Drawing2D.InterpolationMode.Default);

            if (pictureImage.GetStat() != GdPictureStatus.OK)
                throw new InvalidOperationException(string.Format("Unable to print page. Error status: {0}", pictureImage.GetStat()));

            if (pictureImage.ReleaseGdPictureImage(imageID) != GdPictureStatus.OK)
                throw new InvalidOperationException(string.Format("Unable to release image. Error status: {0}", pictureImage.GetStat()));
Should I code this differently?

Thanks for your help in advance

User avatar
Loïc
Site Admin
Posts: 5881
Joined: Tue Oct 17, 2006 10:48 pm
Location: France
Contact:

Re: OutOfMemory Exception with DrawGdPictureImageOnHDC

Post by Loïc » Tue Apr 24, 2012 1:36 pm

Hello,

Your snippet is not complete to analyze the issue.
- Are you sure you have a valid win32 device context in printHDC ?
- Have you tried with different PDFs ?

Kind regards,

Loïc

brian611
Posts: 5
Joined: Mon Apr 23, 2012 6:15 pm

Re: OutOfMemory Exception with DrawGdPictureImageOnHDC

Post by brian611 » Tue Apr 24, 2012 4:57 pm

Sorry for not supplying the full code. It follows:

This first part is the Win APIs that are used:

Code: Select all

    public static class WinUser32API
    {
        [DllImport("user32.dll", SetLastError = true)]
        public static extern int DrawText(IntPtr hDC, string lpString, int nCount, ref RECT lpRect, int uFormat);

        public struct RECT
        {
            public int Left, Top, Right, Bottom;
        }

        public const int DT_TOP = 0x00000000;
        public const int DT_LEFT = 0x00000000;
        public const int DT_CENTER = 0x00000001;
        public const int DT_RIGHT = 0x00000002;
        public const int DT_VCENTER = 0x00000004;
        public const int DT_BOTTOM = 0x00000008;
        public const int DT_WORDBREAK = 0x00000010;
        public const int DT_SINGLELINE = 0x00000020;
        public const int DT_EXPANDTABS = 0x00000040;
        public const int DT_TABSTOP = 0x00000080;
        public const int DT_NOCLIP = 0x00000100;
        public const int DT_EXTERNALLEADING = 0x00000200;
        public const int DT_CALCRECT = 0x00000400;
        public const int DT_NOPREFIX = 0x00000800;
        public const int DT_INTERNAL = 0x00001000;

    }
    public static class WinGDI32API
    {
        [DllImport("gdi32.dll")]
        public static extern int StartDoc(IntPtr hdc, [In] ref DOCINFO lpdi);

        [DllImport("gdi32.dll")]
        public static extern int EndDoc(IntPtr hdc);

        [DllImport("gdi32.dll")]
        public static extern int StartPage(IntPtr hDC);

        [DllImport("gdi32.dll")]
        public static extern int EndPage(IntPtr hdc);

        public struct DOCINFO
        {
            public int DISize;
            public string DocName;
            public string OutputFile;
        }

        [DllImport("gdi32.dll")]
        public static extern int GetDeviceCaps(IntPtr hdc, DeviceCap nIndex);

        public const int SP_ERROR = -1;

        public enum DeviceCap
        {
            /// <summary>
            /// Device driver version
            /// </summary>
            DRIVERVERSION = 0,
            /// <summary>
            /// Device classification
            /// </summary>
            TECHNOLOGY = 2,
            /// <summary>
            /// Horizontal size in millimeters
            /// </summary>
            HORZSIZE = 4,
            /// <summary>
            /// Vertical size in millimeters
            /// </summary>
            VERTSIZE = 6,
            /// <summary>
            /// Horizontal width in pixels
            /// </summary>
            HORZRES = 8,
            /// <summary>
            /// Vertical height in pixels
            /// </summary>
            VERTRES = 10,
            /// <summary>
            /// Number of bits per pixel
            /// </summary>
            BITSPIXEL = 12,
            /// <summary>
            /// Number of planes
            /// </summary>
            PLANES = 14,
            /// <summary>
            /// Number of brushes the device has
            /// </summary>
            NUMBRUSHES = 16,
            /// <summary>
            /// Number of pens the device has
            /// </summary>
            NUMPENS = 18,
            /// <summary>
            /// Number of markers the device has
            /// </summary>
            NUMMARKERS = 20,
            /// <summary>
            /// Number of fonts the device has
            /// </summary>
            NUMFONTS = 22,
            /// <summary>
            /// Number of colors the device supports
            /// </summary>
            NUMCOLORS = 24,
            /// <summary>
            /// Size required for device descriptor
            /// </summary>
            PDEVICESIZE = 26,
            /// <summary>
            /// Curve capabilities
            /// </summary>
            CURVECAPS = 28,
            /// <summary>
            /// Line capabilities
            /// </summary>
            LINECAPS = 30,
            /// <summary>
            /// Polygonal capabilities
            /// </summary>
            POLYGONALCAPS = 32,
            /// <summary>
            /// Text capabilities
            /// </summary>
            TEXTCAPS = 34,
            /// <summary>
            /// Clipping capabilities
            /// </summary>
            CLIPCAPS = 36,
            /// <summary>
            /// Bitblt capabilities
            /// </summary>
            RASTERCAPS = 38,
            /// <summary>
            /// Length of the X leg
            /// </summary>
            ASPECTX = 40,
            /// <summary>
            /// Length of the Y leg
            /// </summary>
            ASPECTY = 42,
            /// <summary>
            /// Length of the hypotenuse
            /// </summary>
            ASPECTXY = 44,
            /// <summary>
            /// Shading and Blending caps
            /// </summary>
            SHADEBLENDCAPS = 45,

            /// <summary>
            /// Logical pixels inch in X
            /// </summary>
            LOGPIXELSX = 88,
            /// <summary>
            /// Logical pixels inch in Y
            /// </summary>
            LOGPIXELSY = 90,

            /// <summary>
            /// Number of entries in physical palette
            /// </summary>
            SIZEPALETTE = 104,
            /// <summary>
            /// Number of reserved entries in palette
            /// </summary>
            NUMRESERVED = 106,
            /// <summary>
            /// Actual color resolution
            /// </summary>
            COLORRES = 108,

            // Printing related DeviceCaps. These replace the appropriate Escapes
            /// <summary>
            /// Physical Width in device units
            /// </summary>
            PHYSICALWIDTH = 110,
            /// <summary>
            /// Physical Height in device units
            /// </summary>
            PHYSICALHEIGHT = 111,
            /// <summary>
            /// Physical Printable Area x margin
            /// </summary>
            PHYSICALOFFSETX = 112,
            /// <summary>
            /// Physical Printable Area y margin
            /// </summary>
            PHYSICALOFFSETY = 113,
            /// <summary>
            /// Scaling factor x
            /// </summary>
            SCALINGFACTORX = 114,
            /// <summary>
            /// Scaling factor y
            /// </summary>
            SCALINGFACTORY = 115,

            /// <summary>
            /// Current vertical refresh rate of the display device (for displays only) in Hz
            /// </summary>
            VREFRESH = 116,
            /// <summary>
            /// Horizontal width of entire desktop in pixels
            /// </summary>
            DESKTOPVERTRES = 117,
            /// <summary>
            /// Vertical height of entire desktop in pixels
            /// </summary>
            DESKTOPHORZRES = 118,
            /// <summary>
            /// Preferred blt alignment
            /// </summary>
            BLTALIGNMENT = 119
        }
    }
Here is the code (MethodA) that tries to print the image out to the printer using DrawGdPictureImageOnHDC:

Code: Select all

        private void MethodA()
        {
            try
            {

                //----------------------------------------------------------------------------
                //Printer settings
                //----------------------------------------------------------------------------
                //Get default printer settings
                PrinterSettings ps = new PrinterSettings();

                //Get HDC
                IntPtr hdc = ps.CreateMeasurementGraphics().GetHdc();

                //Width and height of printer area in pixels
                int printerWidth = WinGDI32API.GetDeviceCaps(hdc, WinGDI32API.DeviceCap.HORZRES);
                int printerHeight = WinGDI32API.GetDeviceCaps(hdc, WinGDI32API.DeviceCap.VERTRES);

                //Used to hold document information for the StatDoc function
                WinGDI32API.DOCINFO di = new WinGDI32API.DOCINFO();
                //----------------------------------------------------------------------------

                //----------------------------------------------------------------------------
                //GDPicture settings
                //----------------------------------------------------------------------------
                //Unlock gdPicture            
                GdPicture.LicenseManager oLicenceManager = new GdPicture.LicenseManager();
                oLicenceManager.RegisterKEY("xxx");

                //Initialize gdPicture objects
                GdPicturePDF pdf = new GdPicturePDF();
                GdPictureImaging pictureImage = new GdPictureImaging();

                //Used to hold gdPictureImaging image ID
                int imageID = 0;
                //----------------------------------------------------------------------------

                //Load PDF
                if (pdf.LoadFromFile(@"C:\Temp\gdtest.pdf", true) != GdPictureStatus.OK)
                    throw new InvalidOperationException(string.Format("Unable to load PDF from file. Error status: {0}", pdf.GetStat()));

                //Select first page
                if (!pdf.SelectPage(1))
                    throw new InvalidOperationException(string.Format("Unable to select page. Error status: {0}", pdf.GetStat()));

                //Get HDC dpi
                float dpi = (float)WinGDI32API.GetDeviceCaps(hdc, WinGDI32API.DeviceCap.LOGPIXELSX);

                //Render pdf page to image
                imageID = pdf.RenderPageToGdPictureImageEx(dpi, false);

                if (imageID == 0)
                    throw new InvalidOperationException(string.Format("Unable to render page as image. Error status: {0}", pdf.GetStat()));

                //Create document information for StartDoc function
                di.DocName = "Test";
                di.OutputFile = null;
                di.DISize = Marshal.SizeOf(di);

                //Start printer doc
                WinGDI32API.StartDoc(hdc, ref di);

                //Start printer page
                WinGDI32API.StartPage(hdc);

                //Draw image onto hdc
                pictureImage.DrawGdPictureImageOnHDC(imageID, hdc, 0, 0,
                    WinGDI32API.GetDeviceCaps(hdc, WinGDI32API.DeviceCap.HORZRES),
                    WinGDI32API.GetDeviceCaps(hdc, WinGDI32API.DeviceCap.VERTRES),
                    System.Drawing.Drawing2D.InterpolationMode.Default);

                if (pictureImage.GetStat() != GdPictureStatus.OK)
                    throw new InvalidOperationException(string.Format("Unable to print page. Error status: {0}", pictureImage.GetStat()));

                //End printer page
                WinGDI32API.EndPage(hdc);

                //End printer doc
                WinGDI32API.EndDoc(hdc);

                if (pictureImage.ReleaseGdPictureImage(imageID) != GdPictureStatus.OK)
                    throw new InvalidOperationException(string.Format("Unable to release image. Error status: {0}", pictureImage.GetStat()));

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
Here is the code (MethodB) that prints text to the printer using the same method to get the printer HDC:

Code: Select all

        private void MethodB()
        {
            try
            {

                //----------------------------------------------------------------------------
                //Printer settings
                //----------------------------------------------------------------------------
                //Get default printer settings
                PrinterSettings ps = new PrinterSettings();

                //Get HDC
                IntPtr hdc = ps.CreateMeasurementGraphics().GetHdc();

                //Width and height of printer area in pixels
                int printerWidth = WinGDI32API.GetDeviceCaps(hdc, WinGDI32API.DeviceCap.HORZRES);
                int printerHeight = WinGDI32API.GetDeviceCaps(hdc, WinGDI32API.DeviceCap.VERTRES);

                //Used to hold document information for the StatDoc function
                WinGDI32API.DOCINFO di = new WinGDI32API.DOCINFO();

                //String sent to the printer
                string testText = @"This prints out to the printer";

                //Rect of page to print into
                WinUser32API.RECT rect = new WinUser32API.RECT();
                //----------------------------------------------------------------------------

                //Create document information for StartDoc function
                di.DocName = "Test";
                di.OutputFile = null;
                di.DISize = Marshal.SizeOf(di);

                //Start printer doc
                WinGDI32API.StartDoc(hdc, ref di);

                //Start printer page
                WinGDI32API.StartPage(hdc);

                rect.Top = 0;
                rect.Left = 0;
                rect.Bottom = printerHeight;
                rect.Right = printerWidth;

                //Draw text to printer
                WinUser32API.DrawText(hdc, testText, testText.Length, ref rect, WinUser32API.DT_CENTER | WinUser32API.DT_VCENTER);

                //End printer page
                WinGDI32API.EndPage(hdc);

                //End printer doc
                WinGDI32API.EndDoc(hdc);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
I am not sure why but I believe the issue lies with the code in MethodA's call to:

imageID = _pdf.RenderPageToGdPictureImageEx(dpi, false);

If you check the printers height prior to calling this method with the following:

WinGDI32API.GetDeviceCaps(hdc, WinGDI32API.DeviceCap.VERTRES)

You will get a value, but after this call is made and you check the printers height with the same above method call it will have a value of zero. So after the RenderPageToGdPictureImageEx call, I believe you are correct in that the hdc is not valid so the DrawGdPictureImageOnHDC fails.

Thanks

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest