Cancel Print Leaks Windows
Jeffrey T. Kouzmanoff -- jtk@prairienet.org
Friday, February 23, 1996
Hello MFC fans.
I have a print function in my application that simply starts printing
upon the click of the OK button in the "Print What" dialog.
(Please, no "that's not standard" comments. This is for an "appliance")
When the application prints and is ultimately terminated, Debug Windows
does not report any leaks.
When the user clicks the CANCEL button and the job is aborted, somewhere,
somehow, 3 windows become reported as not being deleted upon app
termination.
By SPYing, I have found that the reported window handles do not match
1) the main app window, the MDIFrame
2) the MDI client
3) the layer 1 dialog
4) the layer 2 dialog (called from dialog 1 when "Print..." selected)
5) the layer 3 dialog (called from 2, asking "print what?")
6) any of the layer 3 dialog controls
7) the "Printing..." modeless dialog
8) any of the "Printing..." dialog's controls
So, where did these windows come from, and why are they undeleted?
Here is a sample of the print code:
NOTE: this is a good piece of code to squirrel away if you want to
implement a "hands off" print task with MFC... IF IT WORKED, that is.
I noticed that the printer abort procedure isn't here, which is necessary.
E-mail me if you'd like complete code.
PrintInfo is an instance of a class that is used to store the printer
device context, etc., for other print routines to access.
.........
// Get the default printer info
CPrintDialog dlgPrint (FALSE);
if (!App.GetPrinterDeviceDefaults (&dlgPrint.m_pd)) {
AfxMessageBox (IDP_ErrGetPrintDefs);
return;
}
// Create a printer device context in which to draw things
HDC hdcPrint = dlgPrint.CreatePrinterDC ();
if (hdcPrint == NULL) {
AfxMessageBox (IDP_ErrCreatePrintDC);
return;
}
// Attach the handle to the printer context to an object of type CDC so
// that this class' members may be used.
PrintInfo.m_DC.Attach (hdcPrint);
// Create the modeless dialog that has the "Printing..." message and
// Cancel button. This sets m_bUserAbortPrint to TRUE when clicked.
CPrintingDlg *pdlgPrinting = new CPrintingDlg (this);
// Abort Proc has message loop. E-MAIL me for more complete code
PrintInfo.m_DC.SetAbortProc (AbortProc);
// Set up DOCINFO structure with which to start the
// print job.
DOCINFO DocInfo;
DocInfo.cbSize = sizeof (DocInfo);
DocInfo.lpszOutput = NULL; // output to go to device, not file
static char BASED_CODE JobName[] = "Whatever";
DocInfo.lpszDocName = JobName;
if (PrintInfo.m_DC.StartDoc (&DocInfo) == SP_ERROR) {
... handle error, e.g., AfxMessage something
goto UglyGoto999;
}
//// Start of Print Job
... startpage / endpage blah blah blah
//// End of print job
////
if (m_bUserAbortPrint) {
// user wants to abort the print job
if (PrintInfo.m_DC.AbortDoc () < 0)
TRACE0 ("AbortDoc error\n");
}
else {
if (PrintInfo.m_DC.EndDoc () < 0)
TRACE0 ("EndDoc error\n");
}
UglyGoto999:
// clean up
pdlgPrinting->DestroyWindow (); // get rid of modeless "printing" dlg
PrintInfo.m_DC.Detach (); // detach the printer DC from the CDC obj.
::DeleteDC (hdcPrint); // delete the DC
-Jeff
Jeffrey T. Kouzmanoff -- jtk@prairienet.org
Monday, February 26, 1996
On Mon, 26 Feb 1996, Chong Zhang wrote:
> The problem seems like happened in
>
> ...start page/end page blah blah blah
>
> section!
>
> If the printing process creates some temprary windows, who knows why, and
> the abort procedure breaks the process, these temprary windows can be
> left behind.
But my printing code is just a bunch of StartPage, EndPage and GDI calls.
Can GDI calls create such windows? How am I supposed to Cancel a print
cleanly? Can GDI objects be misreported as windows rather than fonts by the
debugging version of windows?
-Jeff
Chong Zhang -- cz@dana.ucc.nau.edu
Thursday, February 29, 1996
On Mon, 26 Feb 1996, Jeffrey T. Kouzmanoff wrote:
> On Mon, 26 Feb 1996, Chong Zhang wrote:
>
> > The problem seems like happened in
> >
> > ...start page/end page blah blah blah
> >
> > section!
> >
> > If the printing process creates some temprary windows, who knows why, and
> > the abort procedure breaks the process, these temprary windows can be
> > left behind.
>
> But my printing code is just a bunch of StartPage, EndPage and GDI calls.
> Can GDI calls create such windows? How am I supposed to Cancel a print
> cleanly? Can GDI objects be misreported as windows rather than fonts by the
> debugging version of windows?
>
> -Jeff
>
>
The debug windows should not misreport GDI objects as windows object
because they belong to different segment ( you know that a HANDLE is
actually an offset address within a segment ).
If you sure that no windows are created during startpage and endpage
section, than these windows must be created outside of it and must be
destroied by the standard end printing process which is skiped by the
abort procedure.
Microsoft provides a good sample of printing abort procedure in
VIEWPRNT.CPP which does not jump to anywhere but records the abort
indication within the dialogbox so that the printing routine can exit
from the loop clean.
I wish it helps.
| Вернуться в корень Архива
|