Print Preview not working for CEditView

I have a CEditView-derived class, using GetEditCtrl().SetWindowText(m_sWindowText) in OnUpdate to set the contents. But when I try to print or preview, nothing shows up.

Shouldn't this be handled automatically by CEditView?

I downloaded a simple example of CEditView which works, but I am unable to find the difference!

I guess one option would be to override one printing function and use TextOut for printing, but that's no good solution. I want to get CEditView do what it should do without cluttering my code!

Since this is urgent for me, I set it to 500points.
LVL 8
Knut HunstadAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AndyAinscowFreelance programmer / ConsultantCommented:
The following samples (come with Visual C++) demonstrate printing and previewing.
CHKBOOK
SUPERPAD
SCRIBBLE
AndyAinscowFreelance programmer / ConsultantCommented:
I've just done a simple app, SDI, CEditView and it DOES print and preview automatically.
Did you add the print preview option to an existing project or was the project created with print preview as an option.  Also when the project was created did you change the default view class to CEditView in the wizard or by hand after the project was created?
AndyAinscowFreelance programmer / ConsultantCommented:
This is the code generated.

// zzzView.h : interface of the CZzzView class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_ZZZVIEW_H__1B066635_F8C3_4B3B_9CD1_FE43EEE707E7__INCLUDED_)
#define AFX_ZZZVIEW_H__1B066635_F8C3_4B3B_9CD1_FE43EEE707E7__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


class CZzzView : public CEditView
{
protected: // create from serialization only
      CZzzView();
      DECLARE_DYNCREATE(CZzzView)

// Attributes
public:
      CZzzDoc* GetDocument();

// Operations
public:

// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CZzzView)
      public:
      virtual void OnDraw(CDC* pDC);  // overridden to draw this view
      virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
      virtual void OnInitialUpdate();
      protected:
      virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
      virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
      virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
      //}}AFX_VIRTUAL

// Implementation
public:
      virtual ~CZzzView();
#ifdef _DEBUG
      virtual void AssertValid() const;
      virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
      //{{AFX_MSG(CZzzView)
            // NOTE - the ClassWizard will add and remove member functions here.
            //    DO NOT EDIT what you see in these blocks of generated code !
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
};

#ifndef _DEBUG  // debug version in zzzView.cpp
inline CZzzDoc* CZzzView::GetDocument()
   { return (CZzzDoc*)m_pDocument; }
#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_ZZZVIEW_H__1B066635_F8C3_4B3B_9CD1_FE43EEE707E7__INCLUDED_)




// zzzView.cpp : implementation of the CZzzView class
//

#include "stdafx.h"
#include "zzz.h"

#include "zzzDoc.h"
#include "zzzView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CZzzView

IMPLEMENT_DYNCREATE(CZzzView, CEditView)

BEGIN_MESSAGE_MAP(CZzzView, CEditView)
      //{{AFX_MSG_MAP(CZzzView)
            // NOTE - the ClassWizard will add and remove mapping macros here.
            //    DO NOT EDIT what you see in these blocks of generated code!
      //}}AFX_MSG_MAP
      // Standard printing commands
      ON_COMMAND(ID_FILE_PRINT, CEditView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_DIRECT, CEditView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_PREVIEW, CEditView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CZzzView construction/destruction

CZzzView::CZzzView()
{
      // TODO: add construction code here

}

CZzzView::~CZzzView()
{
}

BOOL CZzzView::PreCreateWindow(CREATESTRUCT& cs)
{
      // TODO: Modify the Window class or styles here by modifying
      //  the CREATESTRUCT cs

      BOOL bPreCreated = CEditView::PreCreateWindow(cs);
      cs.style &= ~(ES_AUTOHSCROLL|WS_HSCROLL);      // Enable word-wrapping

      return bPreCreated;
}

/////////////////////////////////////////////////////////////////////////////
// CZzzView drawing

void CZzzView::OnDraw(CDC* pDC)
{
      CZzzDoc* pDoc = GetDocument();
      ASSERT_VALID(pDoc);
      // TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CZzzView printing

BOOL CZzzView::OnPreparePrinting(CPrintInfo* pInfo)
{
      // default CEditView preparation
      return CEditView::OnPreparePrinting(pInfo);
}

void CZzzView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
      // Default CEditView begin printing.
      CEditView::OnBeginPrinting(pDC, pInfo);
}

void CZzzView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
      // Default CEditView end printing
      CEditView::OnEndPrinting(pDC, pInfo);
}

/////////////////////////////////////////////////////////////////////////////
// CZzzView diagnostics

#ifdef _DEBUG
void CZzzView::AssertValid() const
{
      CEditView::AssertValid();
}

void CZzzView::Dump(CDumpContext& dc) const
{
      CEditView::Dump(dc);
}

CZzzDoc* CZzzView::GetDocument() // non-debug version is inline
{
      ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CZzzDoc)));
      return (CZzzDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CZzzView message handlers

void CZzzView::OnInitialUpdate()
{
      CEditView::OnInitialUpdate();
      
GetEditCtrl().SetWindowText("hello world")      ;
}
Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

Knut HunstadAuthor Commented:
Sorry, I should have said so, but in addition to the simple sample I mentioned, I did the exact same thing (creating an app with a CEditView from scratch). The problem is I can't see the difference to my code...

My code was originally written as a CScrollView, but contains only text. When trying to get the printing to work, I found several  articles indicating that I should use CEditView and everything would be fine. So I changed to CEditView manually.

The only thing I don't have which is in the scratch example, are the OnNnnPrinting functions, but they don't do anything as far as I can tell.

Im working on this right now, I'll write here immediately if I find out something...
AndyAinscowFreelance programmer / ConsultantCommented:
I suspect somewhere you have a mix of CEditView and CSrollView.

eg
BEGIN_MESSAGE_MAP(CZzzView, CEditView)
      //{{AFX_MSG_MAP(CZzzView)
            // NOTE - the ClassWizard will add and remove mapping macros here.
            //    DO NOT EDIT what you see in these blocks of generated code!
      //}}AFX_MSG_MAP
      // Standard printing commands
      ON_COMMAND(ID_FILE_PRINT, CEditView::OnFilePrint)            <----- check calls like this are to CEditView NOT CScrollView
      ON_COMMAND(ID_FILE_PRINT_DIRECT, CEditView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_PREVIEW, CEditView::OnFilePrintPreview)
END_MESSAGE_MAP()
Knut HunstadAuthor Commented:
You have good suggestions, unfortunately I have none of these! I rechecked the code and also did a search in all my code, but there is no CScrollView or CView to be found anywhere (except the CView that should be there, parameter of OnUpdate e.g.), everything is updated to CEditView.

Since this is a project for externals, I can't publish the code, either, but still appreciate any suggestions that may come!
AndyAinscowFreelance programmer / ConsultantCommented:
OK.  First step.
Put a breakpoint in the code and check certain functions are being called.

void CZzzView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
     // Default CEditView begin printing.
     CEditView::OnBeginPrinting(pDC, pInfo);    <---- Breapoint here (F9 key)
}

now try to print.  Does it stop at the breakpoint?

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Knut HunstadAuthor Commented:
Wow, you are working hard, thank you for your time :-)

Ok, so I have:

void CMyView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
   CEditView::OnBeginPrinting(pDC, pInfo); // Breakpoint here, stops correctly when doing a preview
   CString sText;
   GetEditCtrl().GetWindowText(sText);
   CString sLength;
   sLength.Format("%d", sText.GetLength());
   AfxMessageBox(sLength); // sLength is 4754, which is correct
}

still nothing in the preview...
Knut HunstadAuthor Commented:
Getting close! I am debugging into OnBeginPrinting and it seems to be a font problem, the function GetFont fails. I'll be back shortly...
Knut HunstadAuthor Commented:
No, this was because I have started commenting out anything special, including SetPrinterFont. With that in place again, I now see that the LockBuffer function returns only gibberish. Still searching...
Knut HunstadAuthor Commented:
Ok, so now I try:

   GetEditCtrl().SetWindowText(m_sWindowText);
   LPCTSTR lpszText=LockBuffer();
   UnlockBuffer();

and lpszText contains only the first character of the text. Trying to find out why...
Knut HunstadAuthor Commented:
I found several places on the net stating that CEditView doesn't work without Unicode, and have confirmed the problem. It is the GetHandle/LocalLock-combination that returns a WCHAR*, not a char*, that create the problem for me.

I am currently working on a fix for this, by copying all the code from CEditView into a new class. I'll post it when I get through...
AndyAinscowFreelance programmer / ConsultantCommented:
The basic code I posted earlier (from the wizard) was from a non-unicode app.  That worked.

CEditView::LockBuffer
LPCTSTR LockBuffer( ) const;

Return Value

A pointer to the edit control’s buffer.

Remarks

Call this member function to obtain a pointer to the buffer. The buffer should not be modified.



This should return a non-unicode string for non-unicode apps and a unicode string for unicode apps (I think)
Knut HunstadAuthor Commented:
Yes, it should, but it doesn't! At least not in 7.0.9955...

If I compile my scratch application with Unicode, it works fine, but with "Multi-byte character set" only the first letter shows up in the print and print preview...
AndyAinscowFreelance programmer / ConsultantCommented:
I take it a unicode app is not suitable for you?
Knut HunstadAuthor Commented:
There is no reason it shouldn't be, just carelessness when starting the project (seems Multi-byte is default). And I have a tight deadline (yesterday) and don't want to change too much. A quick try with Unicode gave a lot of errors, but I'll look into them and see if most can't be fixed with search/replace. _If_ I can't find a workaround within the next half hour...

Making my own CEditViewAnsi turned out to be too tedious...
AndyAinscowFreelance programmer / ConsultantCommented:
replace LPSTR with LPTSTR and so on (note the extra T in the middle).  Use TCHAR where char was.  That should cure most if not all of the compile errors.

Project settings - link tab, category OUTPUT (combo box) you will need wWinMainCRTStartup as the EntryPoint symbol
Knut HunstadAuthor Commented:
Ok, I've got it working by changing to Unicode! Took me about two hours, but it's worth it since I now can use CEditView and with very little code get nice views and prints of my text. The EntryPoint was changed automatically when selecting unicode, BTW.

No question who gets points here, it was really helpful! Thanks Andy!

If I can bother you with one last question out of curiosity and to set things straight for others who might look at this question: you say that you got Print Preview in CEditView working with non-unicode? Are you _sure_ and if so, what version of MSVC where you using? As I said, on my version there is an error in the LockBuffer function when not using unicode...
AndyAinscowFreelance programmer / ConsultantCommented:
Thanks for the points and grade.

Visual Studio 6.  
SDI app, changed CView to CEditView as last step of wizard. Default is non-unicode.  
The only code I did was to handle the OnInitialUpdate and put some text into the control.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.