|
Introduction
If you have a dialog based application and want to print, then you cannot take advantage of the Doc/View framework that MFC provides to do all the dirty work for you.
The code presented below demonstrates the typical steps needed to:
- prompt the user for the printing characteristics such as printer and paper
size (via a call to
CPrintDialog::DoModal)
- Setup a printer DC and printing DOCINFO structure
- Use callbacks to adjust settings such as start and end pages to print, or
printing sizes
- Print all pages to be printed
- Cleanup
The callbacks
In order to keep the MFC Doc/View feel I recomend providing helper callback functions OnBeginPrinting, OnEndPrinting and OnPrint similar to the CView versions. A CDC and a CPrintInfo object is passed into each of these functions. You will have to provide these functions yourself. Typically you would undertake any initialisation neessary (such as creating GDI objects) in OnBeginPrinting. Your OnPrint function would be where you do the actual printing/drawing, and your OnEndPrinting function performs any cleanup necessary (such as deleting GDI objects created in OnBeginPrinting). You can call these functions whatever you want - I've used these names to be consistant with the CView names, and they are only used to show where the various initialisation/printing/cleanup code should be inserted by you. Typical
implementations would look like: void OnBeginPrinting(CDC *pDC, CPrintInfo* pInfo)
{
}
void OnPrint(CDC *pDC, CPrintInfo* pInfo)
{
}
void OnEndPrinting(CDC *pDC, CPrintInfo* pInfo)
{
}
The Printing code
void CMyDialog::Print()
{
CDC dc;
CPrintDialog printDlg(FALSE);
if (printDlg.DoModal() == IDCANCEL)
return;
dc.Attach(printDlg.GetPrinterDC());
dc.m_bPrinting = TRUE;
CString strTitle;
strTitle.LoadString(AFX_IDS_APP_TITLE);
DOCINFO di;
::ZeroMemory (&di, sizeof (DOCINFO));
di.cbSize = sizeof (DOCINFO);
di.lpszDocName = strTitle;
BOOL bPrintingOK = dc.StartDoc(&di);
CPrintInfo Info;
Info.m_rectDraw.SetRect(0,0,
dc.GetDeviceCaps(HORZRES),
dc.GetDeviceCaps(VERTRES));
OnBeginPrinting(&dc, &Info);
for (UINT page = Info.GetMinPage();
page <= Info.GetMaxPage() && bPrintingOK;
page++)
{
dc.StartPage();
Info.m_nCurPage = page;
OnPrint(&dc, &Info);
bPrintingOK = (dc.EndPage() > 0);
}
OnEndPrinting(&dc, &Info);
if (bPrintingOK)
dc.EndDoc();
else
dc.AbortDoc();
dc.DeleteDC();
}
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 80 (Total in Forum: 80) (Refresh) | FirstPrevNext |
|
 |
|
|
Howdy,
I see that the code tests if the printing is OK based on whether the dc.EndPage() function returns > 0.
Say for example my OnPrint function fails to to a StretchBlt - I'd like to somehow make the EndPage return zero.
--- Is there a way to do this, or should I just call dc.AbortDoc()? ---
Calling AbortDoc seems to be incorrect, as the bPrintingOK flag then tells us to AbortDoc anyway.
Cheers,
Dave
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
what is AFX_IDS_APP_TITLE? How can i set this value.
My Application is dialog based. I want to print some set of documents without opening.
I have the documents names only in my application. Where can i set these documents name in this program? How can i get print dialog and settings for these documents?
Waiting for reply.
Thank You.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
kamal wrote: what is AFX_IDS_APP_TITLE? How can i set this value.
Did you read the article? See the text in bold.
CString strTitle; // Get the application title strTitle.LoadString(AFX_IDS_APP_TITLE);
AFX_IDS_APP_TITLE, is the resource constant for the Application's title.
I'd love to help, but unfortunatley I have prior commitments monitoring the length of my grass. :Andrew Bleakley:
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
thanks!..... but,
1. i want to print a document by location name like d:\abcd.doc 2. i want to set the properties for that document and printer also. 3. my application is fully dialog based.
reply me.

|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
kamal wrote: 1. i want to print a document by location name like d:\abcd.doc
So what does this have to do with your original question?
Word Documents are in a propriety format, if you want to print a word document your going to need to delve into word /office automation.
I'd love to help, but unfortunatley I have prior commitments monitoring the length of my grass. :Andrew Bleakley:
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
hi douglas,
i used word/office automation in my application.
its solved all my needs. thanks......
bye. kamalraj.m
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
kamal wrote: its solved all my needs. thanks......
Your welcome.
I'd love to help, but unfortunatley I have prior commitments monitoring the length of my grass. :Andrew Bleakley:
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi,
This is really a wonderful sample. It worked very well with my application. I have a small question. I have integrated the code given in my application and called my painting function for printing. Then used Adobe Professional as printer to print the output to a pdf file. When I opened the file, I could see the text only at 1000% or above. The font is so small that, I could not see anything at 100% zoom. Can anybody know why is this happening like this? I could see it properly on screen (I mean, when the dc is being drawn with paintdc).
Thanks,
KVRN Kiran Kumar.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi there!
Do you know how can I print a CRichEditView from a CWinThread (not the main thread)?
The idea is to have a thread pool, to perform some tasks, one of them can be printing a document in RTF, and to do this I'm using the CRichEditView, so I can count pages, format text, etc.
I'm using a Print function in my RichEditView class, that does something like:
CFrameWnd *pFrame=new CFrameWnd; if (!pFrame->Create(NULL, "Frame_Report")) return;
if (Create(NULL, "Report", WS_CHILD|WS_VISIBLE, CRect(0,0,1,1), pFrame, 0)) { SendMessage(WM_COMMAND,(WPARAM)ID_FILE_PRINT_DIRECT,0); }
In the debug version I get several asserts, in the release the app crashes... The good thing is that I get the doc printed! 
Do you have any suggestion?
ALMC
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
BOOL CMyWinThread::InitInstance() { m_pFrame = new CMyMainFrame();
if(!m_pFrame) return FALSE;
m_pFrame->m_pClient = m_pClient; m_pMainWnd = m_pFrame;
if(!m_pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL)) return false;
m_pFrame->ActivateFrame(SW_SHOW); m_pFrame->SetForegroundWindow(); m_pFrame->UpdateWindow();
return TRUE; }
int CMyMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CPersistentFrame::OnCreate(lpCreateStruct) == -1) return -1; m_pDoc = new CDoc();// CRichEditDoc m_pView = new CView();// CRichEditView
if (!m_pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL)) { TRACE0("Failed to create view window\n"); return -1; } m_pDoc->AddView(m_pView);
.... }
void CMyMainFrame::OnDestroy() { m_pDoc->RemoveView(m_pView); m_pView->DestroyWindow(); // !!! NOT delete m_pDoc and delete m_pView
CPersistentFrame::OnDestroy();
}
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi,
Refering to Chris Maunder's article "Printing without the Document / View Framework", in the OnPrint(CDC* pDC, CPrintInfo* pInfo) function he states to "do your drawing/printing exactly as you would in a CView::OnDraw() function". But the first thing CMyView::OnDraw function does is CMyDocument pDoc=GetDocument() (which I need to access the path of the document). When I try this in Chris Maunder's OnPrint(CDC* pDC, CPrintInfo* pInfo) the application compiles but it bombs during linking. Does anyone see where I'm confused?
Buck

|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi Chris,
When I do a printing using CDC::StartPage()/CDC::EndPage(), the printer will not starting printing until the it hits/executes CDC::EndDoc(). Whereas when you are using StartPagePrinter()/EndPagePrinter(), the printer will start printing as soon as it hits EndPagePrinter().
That means if I have 1000page spool file and my printer is set to "Start Printing Immediately"; using CDC::StartPage()/CDC::EndPage(), I have to wait until 1000page is completely spooled before it starts printing. However, if I am using StartPagePrinter()/EndPagePrinter(), as soon as the first page is completely spooled, it starts printing.
Is there any way I can force to do immediate printing using CDC::StartPage()/CDC::EndPage()?
Thanks for your help in advance...
Cheers...
|
| Sign In·View Thread·PermaLink | 2.00/5 (3 votes) |
|
|
|
 |
|
|
Hy,
This code sniplet working good in my application. Also I would call just the PREVIEW part of Print/Preview.
How can I call directly the preview?
Regards, Zoltan
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
How, specifically do I specify which printer to use. I don't want the default printer, I don't want the user to specify it, and I've tried using the EnumPrinter class, which doesn't work for the code above. Well I shouldn't it doesnt work. It does change the default printer within the App class, but not in this printer class or system wide. There must be a couple lines of code that will do this. Please somebody must know how to do this.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I want to change my page size to 89mm x 24mm, for printing labels. Currently, if I want to just pring one label, i have to print off an entire 11" sheet (due to the default page size being 8.5 x 11). I want the dot matrix printer to stop after 24mm. I want the program to do this so that the user doesn't have to. I'd also like to specify which printer to use. How specifically do I do this, and based upon the functions above, where do i put the code? Thanks.
|
| Sign In·View Thread·PermaLink | 2.50/5 (3 votes) |
|
|
|
 |
|
|
 |
|
|
Hi, how can I change the values on the CPrintDialog box. I will select another type of paper or the orientation automaticaly, and at the moment this selection must to be manualy every time that a document was printed.
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
There are two errors in this article
after the line
if (printDlg.DoModal() == IDCANCEL) // Get printer settings from user return; you must put
info.SetMinPage(info.GetFromPage()); info.SetMaxPage(info.GetToPage());or the selected range of pages will not print correctly
in the line
for (UINT page = Info.GetMinPage(); page <= Info.GetMaxPage() && bPrintingOK; page++) you must add && info.m_bContinuePrinting so you cen stop printing in OnPrint function when you don't know max number of pages
|
| Sign In·View Thread·PermaLink | 4.25/5 (4 votes) |
|
|
|
 |
|
|
Hi,
I am having a csrollview where some data is being rendered. I want this data to be printed..I am unable to find anything on it.. can anyone help me out.. there is also a small problem.. like I have the vertical and horizontal scrollbars attched to the same.. but the vertical scrollbar is not working the way it should.. I mean if i drag the bar by mouse it either goes up (max) or below (min). I want to drag it by mouse and remain there where i leave.. Hope that both can be solved.. Looking forward to a solution from you people. Thanks a lot in advance..
Regards,
Himanshu
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
hai I have set of graphs in one tabbed window. I have to print all of these graphs. At present i can print graphs by keeping print option for each graph. My need is i have to print all of these graphs in one click. I tried it. But i am getting print dialog box each time before printing each graph.How to avoid print dialog box appearing each time.
Regards sakthi
|
| Sign In·View Thread·PermaLink | 1.50/5 (2 votes) |
|
|
|
 |
|
|
Hi Sakthi,
Do you mind to shoot some sample code? If yes, you might want to pay attention on DoModal() function.
For example: CPrintDialog printDlg(FALSE); printDlg.DoModal(); //pay attention on this part. This is causing print dialog box to appear.
Cheers...
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Just do this:
CPrintDialog printDlg( FALSE ); printDlg.GetDefaults();
dc.Attach( printDlg.GetPrinterDC() ); // Get and attach a printer DC
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hey,
I am using this code, and when I print on a regular printer it prints fine, but when I try to print on a laster printer, it prints all wrong, text gets pushed close together and text gets printed on top of each other.
Is there something the matter with my code or does it have to do with Laser Printers?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Most laser printers have a higher resolution. If you used absolut coordinates in your code and didn't set the GDI-Mapping-Mode to a DPI-independent one, your result is smaller than on an other printer with less DPIs.
|
| Sign In·View Thread·PermaLink | 1.50/5 (2 votes) |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|