dotnet drawing api:
With the code below, I get either a generic error in GDI+ or an out of memory error when trying to preview a report, using the .NET PrintDocument. This error usually shows up around page 4913 at roughly 275,000 lines or so. I'm attempting to print 58 lines per page. When printing (to a pdf printer) everything seems to work fine, but previewing causes issues. Can anyone help resolve this issue or propose a workaround? Thank you for your time, Davis Public Module Main Sub Main() Dim dlg As New System.windows.forms.PrintPreviewDialog dlg.Document = New ReportDocument dlg.ShowDialog() End Sub End Module Public Class ReportDocument Inherits System.Drawing.printing.PrintDocument Private miPageNumber As Int32 Private mFont As System.Drawing.Font Private mBrush As System.Drawing.Brush Private miCounter As Int32 = 0 Private miLinesPerPage As Int32 = 58 Private miMaxLines As Int32 = 1000000 Public Sub New() mFont = New System.Drawing.Font("Tahoma", 10) mBrush = System.Drawing.Brushes.Black End Sub Private Sub PrintDoc_PrintPage( _ ByVal sender As Object, _ ByVal e As System.Drawing.Printing.PrintPageEventArgs _ ) Handles MyBase.PrintPage Dim iTop As Int32 = 0 Dim iLineCount As Int32 = 0 miPageNumber += 1 For iLineCount = 0 To miLinesPerPage e.Graphics.DrawString("Line number: " & miCounter.ToString, mFont, mBrush, 10, iTop) iTop += 15 miCounter += 1 Next If miCounter < miMaxLines Then e.HasMorePages = True End Sub
[quoted text, click to view] > Only print the relevant pages in preview? You're effectively drawing a > 4913 page bitmap in memory. A simple back of the envelope calc showed me > that each page is probably taking up about 240KB x 4913 = 1.2GB, which the > maximum amount of RAM that a .NET application can use.
Is there a RAM limit? Then, he can print the document, but not preview it? The preview class should be able to preview everything that could be printed, no matter the size. If it can not it is a BUG. The print document class should save those metafiles to disk, instead of keeping them in memory. In the meantime, if that is the case, you will have to use other way to preview. Best Regards, Alejandro Lapeyre "Sean Hederman" <email.jpg@codingsanity.blogspot.com> escribió en el mensaje news:d2ipen$pfq$1@ctb-nnrp2.saix.net... [quoted text, click to view] > Only print the relevant pages in preview? You're effectively drawing a > 4913 page bitmap in memory. A simple back of the envelope calc showed me > that each page is probably taking up about 240KB x 4913 = 1.2GB, which the > maximum amount of RAM that a .NET application can use. > > "DavisLG" <DavisLG@discussions.microsoft.com> wrote in message > news:4921A23C-0F44-42FA-B71C-A4F1BA6F7CF9@microsoft.com... >> With the code below, I get either a generic error in GDI+ or an out of >> memory >> error when trying to preview a report, using the .NET PrintDocument. >> This >> error usually shows up around page 4913 at roughly 275,000 lines or so. >> I'm >> attempting to print 58 lines per page. When printing (to a pdf printer) >> everything seems to work fine, but previewing causes issues. >> >> Can anyone help resolve this issue or propose a workaround? >> >> Thank you for your time, >> >> Davis >> >> Public Module Main >> >> Sub Main() >> >> Dim dlg As New System.windows.forms.PrintPreviewDialog >> dlg.Document = New ReportDocument >> dlg.ShowDialog() >> >> End Sub >> >> End Module >> >> Public Class ReportDocument >> Inherits System.Drawing.printing.PrintDocument >> >> Private miPageNumber As Int32 >> Private mFont As System.Drawing.Font >> Private mBrush As System.Drawing.Brush >> Private miCounter As Int32 = 0 >> Private miLinesPerPage As Int32 = 58 >> Private miMaxLines As Int32 = 1000000 >> >> Public Sub New() >> mFont = New System.Drawing.Font("Tahoma", 10) >> mBrush = System.Drawing.Brushes.Black >> End Sub >> >> Private Sub PrintDoc_PrintPage( _ >> ByVal sender As Object, _ >> ByVal e As System.Drawing.Printing.PrintPageEventArgs _ >> ) Handles MyBase.PrintPage >> >> Dim iTop As Int32 = 0 >> Dim iLineCount As Int32 = 0 >> >> miPageNumber += 1 >> >> For iLineCount = 0 To miLinesPerPage >> e.Graphics.DrawString("Line number: " & miCounter.ToString, mFont, >> mBrush, 10, iTop) >> iTop += 15 >> miCounter += 1 >> Next >> >> If miCounter < miMaxLines Then e.HasMorePages = True >> >> End Sub >> >> End Class > >
Only print the relevant pages in preview? You're effectively drawing a 4913 page bitmap in memory. A simple back of the envelope calc showed me that each page is probably taking up about 240KB x 4913 = 1.2GB, which the maximum amount of RAM that a .NET application can use. [quoted text, click to view] "DavisLG" <DavisLG@discussions.microsoft.com> wrote in message news:4921A23C-0F44-42FA-B71C-A4F1BA6F7CF9@microsoft.com... > With the code below, I get either a generic error in GDI+ or an out of > memory > error when trying to preview a report, using the .NET PrintDocument. > This > error usually shows up around page 4913 at roughly 275,000 lines or so. > I'm > attempting to print 58 lines per page. When printing (to a pdf printer) > everything seems to work fine, but previewing causes issues. > > Can anyone help resolve this issue or propose a workaround? > > Thank you for your time, > > Davis > > Public Module Main > > Sub Main() > > Dim dlg As New System.windows.forms.PrintPreviewDialog > dlg.Document = New ReportDocument > dlg.ShowDialog() > > End Sub > > End Module > > Public Class ReportDocument > Inherits System.Drawing.printing.PrintDocument > > Private miPageNumber As Int32 > Private mFont As System.Drawing.Font > Private mBrush As System.Drawing.Brush > Private miCounter As Int32 = 0 > Private miLinesPerPage As Int32 = 58 > Private miMaxLines As Int32 = 1000000 > > Public Sub New() > mFont = New System.Drawing.Font("Tahoma", 10) > mBrush = System.Drawing.Brushes.Black > End Sub > > Private Sub PrintDoc_PrintPage( _ > ByVal sender As Object, _ > ByVal e As System.Drawing.Printing.PrintPageEventArgs _ > ) Handles MyBase.PrintPage > > Dim iTop As Int32 = 0 > Dim iLineCount As Int32 = 0 > > miPageNumber += 1 > > For iLineCount = 0 To miLinesPerPage > e.Graphics.DrawString("Line number: " & miCounter.ToString, mFont, > mBrush, 10, iTop) > iTop += 15 > miCounter += 1 > Next > > If miCounter < miMaxLines Then e.HasMorePages = True > > End Sub > > End Class
Thanks for everyone's answers. It appears to be an issue w/ the GDI 9999 handles limit. I up'd the available handles to 18000 and can now get up to around 16000 pages, but this is still not enough, as it only gets me to about 600000 lines, and we may have a printdocument of around 1000000 lines or so. I did find the GDI32 API Calls, DeleteObject, SelectObject, DeleteDC, etc, but have not found an example of how to implement these w/ the PrintDocument graphics object. I've seen plenty of examples implementing these w/ icons and such. Could someone explain how to use (or preferable show some example code) on how to use these APIs w/ my current test app. Thank you ,
[quoted text, click to view] "Sean Hederman" wrote: > Only print the relevant pages in preview? You're effectively drawing a 4913 > page bitmap in memory. A simple back of the envelope calc showed me that > each page is probably taking up about 240KB x 4913 = 1.2GB, which the > maximum amount of RAM that a .NET application can use.
We actually need to preview all the pages, b/c they may decide to export the report from the previewer. We're using C1 (ComponentOne) for the previewer. We decided to go w/ the .NET PrintDocument for everything else b/c of the complexity of our reports. Thanks,
[quoted text, click to view] "Alejandro Lapeyre" wrote: > > Only print the relevant pages in preview? You're effectively drawing a > > 4913 page bitmap in memory. A simple back of the envelope calc showed me > > that each page is probably taking up about 240KB x 4913 = 1.2GB, which the > > maximum amount of RAM that a .NET application can use. > > Is there a RAM limit?
Not having a problem w/ a RAM limit, from what I can tell. Seems to be the GDI Object Handles limit. [quoted text, click to view] > > Then, he can print the document, but not preview it?
Yes, I can print fine, but not preview everything. [quoted text, click to view] > The preview class should be able to preview everything that could be > printed, no matter the size. If it can not it is a BUG. > The print document class should save those metafiles to disk, instead of > keeping them in memory.
[quoted text, click to view] > > In the meantime, if that is the case, you will have to use other way to > preview. > > Best Regards, > Alejandro Lapeyre > >
Thanks,
[quoted text, click to view] > Not at all. In both cases you're printing to a device context. The printer > DC spools it's data to the printer and disposed of it, whilst the memory > DC can only spool into memory. Since it has no way to know which pages are > required or not, it cannot remove them to memory. If you want to spool the > pages to disk, simply create a Bitmap, draw some of the pages to that, and > save it yourself. One cannot expect that completely different systems > should behave in exactly the same way. .NET does a good job of hiding the > differences from you in order to make your life easier, but it cannot make > decisions such as caching for you. >
The print preview does print to a device context, but its supporting image is not a bitmap, it is a metafile. So the implementors could save a page metafile to a temp file and reload it as necessary. When the print method is used, every page metafile is "played" to the pinter device context. The print preview class should be able to preview everything that could be printed, if it can not it is a BUG. Best Regards, Alejandro Lapeyre [quoted text, click to view] >> In the meantime, if that is the case, you will have to use other way to >> preview. >> >> Best Regards, >> Alejandro Lapeyre >> >> >> "Sean Hederman" <email.jpg@codingsanity.blogspot.com> escribió en el >> mensaje news:d2ipen$pfq$1@ctb-nnrp2.saix.net... >>> Only print the relevant pages in preview? You're effectively drawing a >>> 4913 page bitmap in memory. A simple back of the envelope calc showed me >>> that each page is probably taking up about 240KB x 4913 = 1.2GB, which >>> the maximum amount of RAM that a .NET application can use. >>> >>> "DavisLG" <DavisLG@discussions.microsoft.com> wrote in message >>> news:4921A23C-0F44-42FA-B71C-A4F1BA6F7CF9@microsoft.com... >>>> With the code below, I get either a generic error in GDI+ or an out of >>>> memory >>>> error when trying to preview a report, using the .NET PrintDocument. >>>> This >>>> error usually shows up around page 4913 at roughly 275,000 lines or so. >>>> I'm >>>> attempting to print 58 lines per page. When printing (to a pdf printer) >>>> everything seems to work fine, but previewing causes issues. >>>> >>>> Can anyone help resolve this issue or propose a workaround? >>>> >>>> Thank you for your time, >>>> >>>> Davis >>>> >>>> Public Module Main >>>> >>>> Sub Main() >>>> >>>> Dim dlg As New System.windows.forms.PrintPreviewDialog >>>> dlg.Document = New ReportDocument >>>> dlg.ShowDialog() >>>> >>>> End Sub >>>> >>>> End Module >>>> >>>> Public Class ReportDocument >>>> Inherits System.Drawing.printing.PrintDocument >>>> >>>> Private miPageNumber As Int32 >>>> Private mFont As System.Drawing.Font >>>> Private mBrush As System.Drawing.Brush >>>> Private miCounter As Int32 = 0 >>>> Private miLinesPerPage As Int32 = 58 >>>> Private miMaxLines As Int32 = 1000000 >>>> >>>> Public Sub New() >>>> mFont = New System.Drawing.Font("Tahoma", 10) >>>> mBrush = System.Drawing.Brushes.Black >>>> End Sub >>>> >>>> Private Sub PrintDoc_PrintPage( _ >>>> ByVal sender As Object, _ >>>> ByVal e As System.Drawing.Printing.PrintPageEventArgs _ >>>> ) Handles MyBase.PrintPage >>>> >>>> Dim iTop As Int32 = 0 >>>> Dim iLineCount As Int32 = 0 >>>> >>>> miPageNumber += 1 >>>> >>>> For iLineCount = 0 To miLinesPerPage >>>> e.Graphics.DrawString("Line number: " & miCounter.ToString, mFont, >>>> mBrush, 10, iTop) >>>> iTop += 15 >>>> miCounter += 1 >>>> Next >>>> >>>> If miCounter < miMaxLines Then e.HasMorePages = True >>>> >>>> End Sub >>>> >>>> End Class >>> >>> >> >> > >
[quoted text, click to view] "Alejandro Lapeyre" <AlejandroLapeyre@jotmail.com> wrote in message news:OWZmScoNFHA.2392@TK2MSFTNGP10.phx.gbl... >> Only print the relevant pages in preview? You're effectively drawing a >> 4913 page bitmap in memory. A simple back of the envelope calc showed me >> that each page is probably taking up about 240KB x 4913 = 1.2GB, which >> the maximum amount of RAM that a .NET application can use. > > Is there a RAM limit?
Yes, .NET applications are limited to 1.2GB on Win32. Standard Windows EXE's are limited to 2GB. I'm not sure why .NET is less, but I think I remember seeing somewhere that this would be resolved in Whidbey. [quoted text, click to view] > Then, he can print the document, but not preview it? > The preview class should be able to preview everything that could be > printed, no matter the size. If it can not it is a BUG. > The print document class should save those metafiles to disk, instead of > keeping them in memory.
Not at all. In both cases you're printing to a device context. The printer DC spools it's data to the printer and disposed of it, whilst the memory DC can only spool into memory. Since it has no way to know which pages are required or not, it cannot remove them to memory. If you want to spool the pages to disk, simply create a Bitmap, draw some of the pages to that, and save it yourself. One cannot expect that completely different systems should behave in exactly the same way. .NET does a good job of hiding the differences from you in order to make your life easier, but it cannot make decisions such as caching for you. [quoted text, click to view] > In the meantime, if that is the case, you will have to use other way to > preview. > > Best Regards, > Alejandro Lapeyre > > > "Sean Hederman" <email.jpg@codingsanity.blogspot.com> escribió en el > mensaje news:d2ipen$pfq$1@ctb-nnrp2.saix.net... >> Only print the relevant pages in preview? You're effectively drawing a >> 4913 page bitmap in memory. A simple back of the envelope calc showed me >> that each page is probably taking up about 240KB x 4913 = 1.2GB, which >> the maximum amount of RAM that a .NET application can use. >> >> "DavisLG" <DavisLG@discussions.microsoft.com> wrote in message >> news:4921A23C-0F44-42FA-B71C-A4F1BA6F7CF9@microsoft.com... >>> With the code below, I get either a generic error in GDI+ or an out of >>> memory >>> error when trying to preview a report, using the .NET PrintDocument. >>> This >>> error usually shows up around page 4913 at roughly 275,000 lines or so. >>> I'm >>> attempting to print 58 lines per page. When printing (to a pdf printer) >>> everything seems to work fine, but previewing causes issues. >>> >>> Can anyone help resolve this issue or propose a workaround? >>> >>> Thank you for your time, >>> >>> Davis >>> >>> Public Module Main >>> >>> Sub Main() >>> >>> Dim dlg As New System.windows.forms.PrintPreviewDialog >>> dlg.Document = New ReportDocument >>> dlg.ShowDialog() >>> >>> End Sub >>> >>> End Module >>> >>> Public Class ReportDocument >>> Inherits System.Drawing.printing.PrintDocument >>> >>> Private miPageNumber As Int32 >>> Private mFont As System.Drawing.Font >>> Private mBrush As System.Drawing.Brush >>> Private miCounter As Int32 = 0 >>> Private miLinesPerPage As Int32 = 58 >>> Private miMaxLines As Int32 = 1000000 >>> >>> Public Sub New() >>> mFont = New System.Drawing.Font("Tahoma", 10) >>> mBrush = System.Drawing.Brushes.Black >>> End Sub >>> >>> Private Sub PrintDoc_PrintPage( _ >>> ByVal sender As Object, _ >>> ByVal e As System.Drawing.Printing.PrintPageEventArgs _ >>> ) Handles MyBase.PrintPage >>> >>> Dim iTop As Int32 = 0 >>> Dim iLineCount As Int32 = 0 >>> >>> miPageNumber += 1 >>> >>> For iLineCount = 0 To miLinesPerPage >>> e.Graphics.DrawString("Line number: " & miCounter.ToString, mFont, >>> mBrush, 10, iTop) >>> iTop += 15 >>> miCounter += 1 >>> Next >>> >>> If miCounter < miMaxLines Then e.HasMorePages = True >>> >>> End Sub >>> >>> End Class >> >> > >
[quoted text, click to view] "Alejandro Lapeyre" wrote: > I have been checking the PrintController, PreviewPrintController, and > PreviewPageInfo classes. > > You could implement a class that inherits from PreviewPrintController > > PreviewPrintController contains a GetPreviewPageInfo() method that returns > an array of PreviewPageInfo. > > PreviewPageInfo contains the image information for one page. > > And here is the problem: you can not inherit from PreviewPageInfo, so there > is no way to cache the image in a file, and recreate as needed. > > *************************************** > To whom it may concern: > PreviewPageInfo Should be > Inheritable!*************************************** > > This is a design error. > > The solution, then is to recreate the functionality. I have already done > this in VB5, so it should not be that difficult to do it in .net :-) > > > Best Regards, > Alejandro Lapeyre >
It must be Friday. Could you explain the answer in a more details for dummies? I'm not quite understanding. Where and how would I implement this inherited class? Thank you,
[quoted text, click to view] "Alejandro Lapeyre" wrote: > The short form is this: > > The PrintPreviewControl is *limited* in the quantity of pages it can handle. > You can *not* handle this situation with the given classes. > > The solution here is to use your own classes to do the print preview. > It is not difficult to do. > > Best Regards, > Alejandro Lapeyre >
Ah, thank you , this is exactly what I've been wanting to do, but having little experience with gdi and gdi+ I'm not sure where to begin. I understand that I need to inherit from PreviewPrintController . I'll begin w/ that. Thank you,
I have been checking the PrintController, PreviewPrintController, and PreviewPageInfo classes. You could implement a class that inherits from PreviewPrintController PreviewPrintController contains a GetPreviewPageInfo() method that returns an array of PreviewPageInfo. PreviewPageInfo contains the image information for one page. And here is the problem: you can not inherit from PreviewPageInfo, so there is no way to cache the image in a file, and recreate as needed. *************************************** To whom it may concern: PreviewPageInfo Should be Inheritable!*************************************** This is a design error. The solution, then is to recreate the functionality. I have already done this in VB5, so it should not be that difficult to do it in .net :-) Best Regards, Alejandro Lapeyre "Davis" <Davis@discussions.microsoft.com> escribió en el mensaje news:3A826EA3-EB2A-4FB6-97D7-401EE3E0A987@microsoft.com... [quoted text, click to view] > > > "Alejandro Lapeyre" wrote: > >> > Only print the relevant pages in preview? You're effectively drawing a >> > 4913 page bitmap in memory. A simple back of the envelope calc showed >> > me >> > that each page is probably taking up about 240KB x 4913 = 1.2GB, which >> > the >> > maximum amount of RAM that a .NET application can use. >> >> Is there a RAM limit? > > Not having a problem w/ a RAM limit, from what I can tell. Seems to be the > GDI Object Handles limit. > >> >> Then, he can print the document, but not preview it? > > Yes, I can print fine, but not preview everything. > >> The preview class should be able to preview everything that could be >> printed, no matter the size. If it can not it is a BUG. >> The print document class should save those metafiles to disk, instead of >> keeping them in memory. > > >> >> In the meantime, if that is the case, you will have to use other way to >> preview. >> >> Best Regards, >> Alejandro Lapeyre >> >> > > > Thanks, > > Davis
The short form is this: The PrintPreviewControl is *limited* in the quantity of pages it can handle. You can *not* handle this situation with the given classes. The solution here is to use your own classes to do the print preview. It is not difficult to do. Best Regards, Alejandro Lapeyre "Davis" <Davis@discussions.microsoft.com> escribió en el mensaje news:20DE522A-D448-4D9D-833B-024BF1B99B6E@microsoft.com... [quoted text, click to view] > > > "Alejandro Lapeyre" wrote: > >> I have been checking the PrintController, PreviewPrintController, and >> PreviewPageInfo classes. >> >> You could implement a class that inherits from PreviewPrintController >> >> PreviewPrintController contains a GetPreviewPageInfo() method that >> returns >> an array of PreviewPageInfo. >> >> PreviewPageInfo contains the image information for one page. >> >> And here is the problem: you can not inherit from PreviewPageInfo, so >> there >> is no way to cache the image in a file, and recreate as needed. >> >> *************************************** >> To whom it may concern: >> PreviewPageInfo Should be >> Inheritable!*************************************** >> >> This is a design error. >> >> The solution, then is to recreate the functionality. I have already done >> this in VB5, so it should not be that difficult to do it in .net :-) >> >> >> Best Regards, >> Alejandro Lapeyre >> > > It must be Friday. Could you explain the answer in a more details for > dummies? I'm not quite understanding. Where and how would I implement > this > inherited class? > > Thank you, > > Davis
Davis, [quoted text, click to view] > Ah, thank you , this is exactly what I've been wanting to do, but having > little experience with gdi and gdi+ I'm not sure where to begin. I > understand that I need to inherit from PreviewPrintController . I'll begin > w/ > that.
No. You will not be able to resolve this issue inheriting from PreviewPrintController. You will have to replace it. A linear approach would be something like this: For every page you have to preview/print: create a metafile create a graphics object from this metafile Draw your page using this graphics object. dispose this graphics object save the metafile to a temporary file (tempXXX.emf) Where xxx is the page Number. dispose the metafile. Then Create a form with some buttons to change page When requested open the tempPageNum metafile and draw it. When this is working you may improve this. (The most obvius improvement is not to print the whole work, but only the pages as needed by the preview form): Best Regards Alejandro Lapeyre "Davis" <Davis@discussions.microsoft.com> escribió en el mensaje news:891E541A-0660-4D6E-B17D-D7BF226CC61B@microsoft.com... [quoted text, click to view] > > > "Alejandro Lapeyre" wrote: > >> The short form is this: >> >> The PrintPreviewControl is *limited* in the quantity of pages it can >> handle. >> You can *not* handle this situation with the given classes. >> >> The solution here is to use your own classes to do the print preview. >> It is not difficult to do. >> >> Best Regards, >> Alejandro Lapeyre >> > > Ah, thank you , this is exactly what I've been wanting to do, but having > little experience with gdi and gdi+ I'm not sure where to begin. I > understand that I need to inherit from PreviewPrintController . I'll begin > w/ > that. > > Thank you, > > Davis
Don't see what you're looking for? Try a search.
|