Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
INTRODUCTION AND RELEVANT INFORMATION:

I am maintaining an old application and I need to implement feature that generates reports based on data calculated from a database. User must also have an additional option of printing the file ( user must be able to choose printer, and must be able to see print preview ).

To improve my chances of getting satisfactory answer, allow me to additionally clarify matters with a small "example":

- User presses a button -> application calculates data; // Done

- Application creates file and populates it with the result; // Done

- User gets informed that report is generated; // Done

- User presses another button that is charged for printing; // Stuck here!

- Print preview pops up and an option to run print dialog. // Stuck here

- User starts the print dialog, chooses the printer and application prints the file;

The application is coded in C++ using raw WinAPI ( no MFC ). I am working on Windows XP.

PROBLEM:

I was able to successfully use OLE Automation to generate/save Word and Excel reports but I can not solve the printing task.

If I use OLE Automation to show Excel's print dialog/print preview, there is a following problem that might occur :

User can simply click "Close Print Preview", or can simply close print property sheet and return to the document which might compromise document's data.

Therefore, I need a solution for generating a print preview for the user, in a way that protects document data.

Furthermore, user should be able to choose the printer that will print the file.

QUESTION:

INTRODUCTORY NOTES:

The question is too broad to be answered in one post so I must limit myself only for seeking advice / general concept / pointing in the right direction.

THE ACTUAL QUESTIONS :

I did the best I could with the OLE Automation and Excel / Word files, but as you can see there are problems with generating a print preview, hence the following questions :

1. Since this is my first time to tackle this kind of task, can you recommend me the proper way to handle it ( general concepts of course )?

2. Is there a chance that there is a workaround for my printing problem ( like sending WM_PRINTCLIENT message to the Word / Excel or something like that )?

REMARKS :

Again, I realize the question is too broad so just give me general concepts / pointers, so I could post separate questions if I get stuck somewhere in the way.

I do not need to use Word / Excel and OLE Automation, it was my choice at the moment.

If you can recommend better solution I will gladly accept. I do not wish to use libraries.

If additional information is required, ask and I will edit my post.
Posted
Comments
enhzflep 1-Jun-14 14:15pm    
I've had a couple of thoughts about this problem over the past several hours, though they still feel rather kludgy.

1) You could populate an excel spreadsheet, then auto-set the width of the cells such that they are wide enough for the data in each column. When this is done, you could then query excel for the column widths and use these to generate (in your application) a printable document. This would get more than a little hairy if the cells contained formulas or were formatted as numbers/date/currency etc.

2. Perhaps you could password protect the sheet after generation and before print-preview. This would alleviate the possibility that the user could alter the data manually.

3. You could generate pdf documents, which are by their nature, not easily edited.

----------------------------------------------
1. This would still get rather 'interesting' when it came to formatting the data, i.e text-colours/text-fonts would require some extra work. Locale-specific currency/number formatting could also be a royal pain in the you-know-what. Also, I don't remember just how excel treats images - whether they actually are contained in the cells, or simply sit above them at whatever size you specify - like buttons, for instance.

2. This would be my preferred option if password protection was feasible from VBA/Automation. If a password could programmatically be applied, you'd have the best of many worlds.
(a) text colour/fonts
(b) number/currency with the correct locale specific formatting
(c) you could have a soft-copy of the hard-copy. This would easily be scale-able to different paper sizes/formats - i.e foolscap or a4.

3) I wrote code to generate PDFs a few years back, which was used to generate timetables for students or staff or rooms or subjects. That would allow me to attach files, 'print' files to the pdf or just create the pdf on the fly from a database COM server. It did have a few bugs, but worked in the majority of cases (about 3 or 4 in 1300 timetables consistently had problems) The code was basically a port of the PHP library, fPdf, with a few extra features. I would not recommend this method personally.
This would provide very few (if any) advantage over generating a print-preview using c++ (only), with the addition of a couple of nasty gotchas.
a) The page-size is fixed, which makes printing in different orientations/paper sizes rather more difficult.
b) You still have to format the tables yourself, by measuring the width of the text in every cell of each column, before setting the column width to the largest value + some value for the margins.
c) PDFs are nasty things to generate and the quantity of code required to do so is rather surprising. ~100kb of source, also a dependence on the zlib library to provide the flate compression method. (My Pdf generation code is also a pain in the backside to debug, in my experience) - you'd be welcome to the code, as it was a 'because I can' excercise that I did at night - but I certainly wouldn't try PDF unless all other avenues were investigated first.

----------------------------------------------

The XAMPP (Apache, MySql, Php, Perl) distribution includes code to generate PDFs from a sample music cd database. This demonstrates how to go about formatting the table and measuring the width of each column. Php is close enough to C/C++ that many things can be simply copy/pasted - the remainder can be dealt with via the Php manual or by browsing StackOverflow.

If password protection of the generated excel/word files wasn't possible, I'd probably just code something myself to create the reports in plain old win32 c++. Dealing with images would be probably the easiest too, since you've got a wide range of available formats thanks to GDI+. Also, you don't need to worry about extracting the pixel-data or of investigating the various PDF stream-types in order to embed jpg images (not sure that png is natively supported in pdfs - my work was based on the 1.2 and
AlwaysLearningNewStuff 1-Jun-14 14:25pm    
Those are all tricky...

I have got an idea, maybe you can help me out : Maybe I could get the window handle of Word's edit control. That way I could try and send WM_PRINTCLIENT hoping that the edit control will paint properly my window.

I have just used Spy++ to check the type of the window - it is not an edit control but a window... Still, I might be able to figure something out...
enhzflep 1-Jun-14 21:40pm    
Tricky is a er, um, rather 'diplomatic' way of putting it. :)
Yup, i just tried with Spy++ too - the best I could get was a window with the class-name of 'XLDESK', though unfortunately, this includes extra chrome like the scroll-bars, the cell/row buttons (A, B, C - 1, 2, 3 etc) and also the worksheet-selection tabs. Doing a 'print-screen' would also include all of the lines that divide cells, although I think you can turn these off.

Another option perhaps worth investigating is to generate a html report. You could generate and save the report and then open it with the user's default web-browser.
Apart from the fact I think I recall you saying you were yet to dabble in web-based programming, this would be quite easy. Table-based data is a cinch to create and display in html - all of the formatting is done for you, fonts are even substituted if the chosen one isn't available on the client machine.

This would probably be the second thing I investigated after making the sheet read-only and password protected.

It's almost certainly a task that would be made easier if you were conversant with .NET programming - they absolutely excel (pardon the pun) at CRUD apps (Create Read Update Delete) aimed at business use, where minimizing time spent programming is more important than minimizing the time spent executing the program. But that's not a useful virtue in your case, where learning the language would need to be done first. Learning enough html to format your reports could probably be done in anywhere from a single morning to a day or two, depending on the complexity of the reports.

HTML can also handle pagination and text-wrapping to the size/orientation of the printed paper.

They sure have thrown you in at the deep-end with this one! :grin:
AlwaysLearningNewStuff 2-Jun-14 7:47am    
Actually we all have to learn HTML some day so why not starting know?

The problem I face with this task is to use GDI/GDI+ to draw to a file. If this was possible I could draw the print preview myself, and then simply use the same drawing functions to draw to a file.

Unfortunately I do not know any file format that can allow me to do this... If HTML would allow me to transfer somehow its window content to my print preview window than it would be an acceptable solution for me. As I have said, a serious developer must learn it someday so why not start now?

Thank you for your suggestions.
enhzflep 2-Jun-14 8:43am    
You're welcome.

HTML really isn't very difficult at all - its often just another tool in the toolbox at the end of the day.

You could always just do all the formatting yourself, and use GDI/GDI+ to do the drawing. GDI+ would give you the ability to output an EMF/WMF file, while GDI would leave you stuck with a large png, jpg etc. Both gdi/gdi+ would let you see exactly what would be printed in a window of your choosing. Naturally, none of these would save a file with actual text in it - you'd be left with a file that had an image of text - fine for human eyes, less useful for machine-reading. Although, using GDI/GDI+ would make viewing the data to be printed relatively easy - just allow the user to see the hdc in a scrolled window.

The HTML option I had in mind would require you to print from the browser, using its print-preview functionality, although, perhaps you could interact with Internet Explorer via COM to make it _appear_ as though it was your application that generated the print preview, when in fact it was IE that was showing the printer selection dialog and the print preview.

Unless you're going to draw the content yourself, you're likely stuck with the print preview window of whichever application does draw the content. It may be doable to steal the print-preview output from another program and present it yourself - but I'd really reccomend against this - it's likely to be fraught with danger, whoever maintains this application next will want to shoot you and it smells like a hack to me. (You may also find that porting to a later OS in the future will cause an angry developer to wish you ill).

The more I think about it, the more I think that I'd either.

a) Output HTML and let the user view/print the report themselves from the browser.
or
b) Do it the standard way - enumerate the available printers in the system, allow the user to select one, create a HDC compatible with that printer, create and select a bitmap large enough for their selected paper-size (and a reasonble DPI) into that HDC, then simply draw your text and images to this hdc. You can send it to the screen for preview or to the printer for a hard-copy. This gives you the most control and the most responsibility. It also makes printing the easiest from the user's perspective. A nice option would be to also allow the output of the report in html format should the user wish to save an easily viewable soft-copy rather than a hard-copy.

Hmmmm. Decisions, decisions!

1 solution

A very nice solution already exists here at Codeproject.com. See this one:

Printing of DataGridView[^]
 
Share this answer
 
Comments
enhzflep 1-Jun-14 8:35am    
Any idea how AlwaysLearningNewStuff would go converting this from a C# .NET application to a win32 c++ one?

While I agree that the article presents a nice way to print/show a print preview of tabular data, I cant help but draw the following analogy:

Question: "Hi, I need to buy a small dog for my son/daughter - I do not want a dog that will grow very large or be aggressive. Any suggestions of a suitable breed?"

Answer: "You should look at Burmese cats - they are quite small and placid."
AlwaysLearningNewStuff 1-Jun-14 10:16am    
Unfortunately, I do not have time to learn .NET and C#... :(

Still, thank you for trying to help...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900