|
In regards to what Mr. Dunn stated, here is how to zero init your structures in case you haven't seen it before in a code example...
INITCOMMONCONTROLSEX InitCtrlEx={0};
|
|
|
|
|
Printing in MFC seems so tricky to do...Right now I'm working on a notepad like program and the print function in it. I haven't been working on the function for a few months already. Seems like I forgot what everything does in it. But the problem I'm having now is I can't get the number of pages to print.
I copied this off some site:
CDC printerDC;
printerDC.Attach (printpage.GetPrinterDC ());
DOCINFO di;
::ZeroMemory (&di, sizeof (DOCINFO));
di.cbSize = sizeof (DOCINFO);
di.lpszDocName = filename;
printerDC.SetMapMode (MM_LOENGLISH);
CPrintInfo docInfo;
docInfo.SetMinPage(docInfo.GetMinPage());
docInfo.SetMaxPage(docInfo.GetMaxPage());
and it doesn't work at all. Anyone have any pointers as to how I can get the minpage and maxpage values? And also can anyone explain the functions for printing? I'm still a bit confused...
Edit: I found some great code on the internet, now all I need is some function to get the number of lines in my editbox...Is that any better than the number of pages?
-- modified at 21:59 Friday 3rd August, 2007
|
|
|
|
|
You can use your OnDraw() functions to print with if you stand on your head just right. Start an MFC (Visual C++ 6.0) Doc/View app deriving from CScrollView. Add the necessary code sections below using the ClassWizard and make sure they resemble the code below. The demo shows how to use the OnDraw for both drawing in a view and to the printer. It uses an arbitrary world coordinate system with MM_ISOTROPIC. It demonstrates how to let the OnDraw know which page is being displayed or printed so OnDraw can adapt it's drawing accordingly. It will fit the drawing to the output device while preserving the documents aspect ratio. I left the centering of the drawing in the device as an exercise for you. (Hint, center/align the viewport and the window with respect to each other).
I also did not reset the m_nPage after printing, error checking etc...
Let me know if I forgot something.
Hope this helps!
//CDocument members...
// Header file .h
protected:
CSize m_DocSize;
// Implementation file .cpp
CSize CYourDoc::GetDocSize() const
{
return m_DocSize;
}
CYourDoc::CYourDoc()
{
// TODO: add one-time construction code here
m_DocSize=CSize(2000,2800);
}
//CScrollView members...
// Header file .h
private:
int m_nPage;
// Implementation file .cpp
CYourView::CYourView()
{
// TODO: add construction code here
SetScrollSizes(MM_TEXT,CSize(0,0)); // Set arbitrary values
m_nPage=1;
}
/***************************************
NOTE: The pInfo parameter is uncommented
****************************************/
void CYourView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* pInfo)
{
// TODO: add extra initialization before printing
pInfo->SetMaxPage(3);
}
void CYourView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
// TODO: Add your specialized code here and/or call the base class
m_nPage=pInfo->m_nCurPage;
CScrollView::OnPrint(pDC, pInfo);
}
void CYourView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
CScrollView::OnPrepareDC(pDC);
// TODO: Add your specialized code here and/or call the base class
// Set up the DC for the current scale factor
int nExtentX;
int nExtentY;
CSize sizeDoc;
CRect rectClient;
pDC->SetMapMode(MM_ISOTROPIC); // Allow scaling with aspect ratio preserved
// Get pertinent rectangle data
GetClientRect(&rectClient);
sizeDoc=GetDocument()->GetDocSize();
sizeDoc.cy=(-sizeDoc.cy); // Y goes down as it increments
pDC->SetWindowExt(sizeDoc); // Window extent is size of document
// Calculate viewport extent
nExtentX=rectClient.Width();
nExtentY=(int)((nExtentX*sizeDoc.cy)/(sizeDoc.cx));
// What kind of device context do we have?
if (pDC->IsPrinting()==TRUE) {
pDC->SetViewportExt(pDC->GetDeviceCaps(HORZRES),-pDC->GetDeviceCaps(VERTRES));
} else {
// Context is for screen
pDC->SetViewportExt(nExtentX,nExtentY);
}
}
void CYourView::ResetScrollBars()
{
CSize sizeDoc;
CClientDC dc(this);
this->OnPrepareDC(&dc); // Update the device context
sizeDoc=GetDocument()->GetDocSize();
dc.LPtoDP(&sizeDoc); // Logical to device
this->SetScrollSizes(MM_TEXT,sizeDoc); // Update scrollbars
}
void CYourView::OnSize(UINT nType, int cx, int cy)
{
CScrollView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
ResetScrollBars();
}
void CYourView::OnDraw(CDC* pDC)
{
CTestPrintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CSize sizeDoc=pDoc->GetDocSize();
CRect rectOutline(0,0,sizeDoc.cx,sizeDoc.cy);
rectOutline.DeflateRect(10,10); // Ensure we can see it
LOGFONT logFont={0};
memcpy(logFont.lfFaceName,"Arial",6);
logFont.lfHeight=300;
CFont font;
font.CreateFontIndirect(&logFont);
CFont* pOldFont=pDC->SelectObject(&font);
CBrush* pOldBrush=(CBrush*)pDC->SelectStockObject(NULL_BRUSH);
CString sMessage;
sMessage.Format("You can add code to center the printout later\nPage %d",m_nPage);
pDC->DrawText(sMessage,&rectOutline,DT_CENTER|DT_WORDBREAK);
pDC->Rectangle(&rectOutline);
pDC->SelectObject(pOldFont);
pDC->SelectObject(pOldBrush);
}
|
|
|
|
|
Ehhh...I'm new at MFC...and I think my original post wasn't very clear. What I need right now is a way to get the number of lines a user types into a CEdit editbox, not a preview and a bunch of other things that look like scrollbar stuff...I already have a pretty good class for printing I got off the net. Just need the number of lines in a CEdit editbox.
|
|
|
|
|
I apologize if that code doesn't help. I had thought you asked for an explanation of how printing and pages work in MFC. A picture paints a thousand words so I thought a little working demo would help explain the paging mechanism in MFC.
Sorry for the misunderstanding.
|
|
|
|
|
No, it's ok. I did ask for an explanation of printing in MFC, and your code shows that pretty well but it doesn't do what I need. Thanks anyway. I get the idea of printing now.
|
|
|
|
|
In regards to your modified post, if you desire to calculate how many pages it will take to print your document, then you need to calculate some metrics to figure that out.
I think I misunderstood your original post. Are you using CEditView for your view class or a CScrollView? If your using CEditView, you really don't need to do anything as it is a mini pre-wrapped Notepad application and will print as is.
|
|
|
|
|
If I remember correctly, CEditView and CScrollView are used for previewing...? I hardly ever use them, not too familiar. What I'm doing here is I'm getting a CString of all the text in the editbox (CEdit), then printing the CString line by line in a loop. That's why I need the number of lines . I'm not using CEditView or CScrollView here.
|
|
|
|
|
Did you try CEdit::GetLineCount() and CEdit::GetLine()
I'm guessing it won't help too much though since the line count is probably based on it's visual representation in the CEdit window. Font metrics are quite tricky when attempting a WYSIWYG application on any arbitrary device; Especially with line breaks and font grid fitting involved.
However, it may be what your after so I thought I'd post it if you haven't come across it in MSDN yet.
Hope that helps.
|
|
|
|
|
Ever thought of Counting the Lines? (as in counting the number of'\n' chars in the CString? )
LateNightsInNewry
|
|
|
|
|
Hmm...yeah, I did think of that, but what if the user turns word wrap on/off?
|
|
|
|
|
How to create the formatting bar at run time as provided in this site for bold,italic and underline
Thnx & Regards
Manoj Bisht
|
|
|
|
|
The Knowledge wrote: How to create the formatting bar at run time as provided in this site for bold,italic and underline
Care to explain a bit further? What is your VC++/MFC code (not) doing?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
|
Hey Friends
Any idea how i can create a wav file so that
Output = 1.wav(in background & repeated) + 2.wav (in foreground & repeated)
Regards
|
|
|
|
|
If the wave files both contain PCM data, you can perform a crude mix by grabbing a sample from each file and summing them in the ratio you want. If you want a 70/30 mix, multiply the sample from 1.wav by 0.7 and the sample from 2.wav by 0.3. Add the two values and write to a new wave file. If the files have different sampling frequencies, bit depths, or numbers of channels, you'll have to do some processing to make them equivalent to each other before summing the samples.
|
|
|
|
|
|
This is allways something wich i have had trouble with, usualy i end up doing some ugly trick to make it work.. But this time i cant.. (well ive been spending around 3 days trying..) I need a thread which is connected to the main class of my MFC Dialog based application. I looked at Code Project:Using AfxBeginThread...[^] In which i end up createing a new static function that seems to work with some functions.. But when i tried calling the function i wanted it to run, it couldnt since it wasnt a static function.. So i tried making it a static function, but then i got loads of error messages...
So how would i go about creating and running a thread that is connected to the main class (like "CThreadDemoDlg::OnStart()" ) ?
The function doesnt need any params or other advanced features, maybe i should start it using a differnt function?
Or how should i go about this?
thanks!
PS: Im not really that good at the terminology for c++, or c++ programming itself, so nothing too hightech or advanced unless its a must do..
//Johannes
|
|
|
|
|
Well this is not a MFC thread but it can work in MFC applications and/or maybe it will help give you the idea
class base_w32thread{
protected:
HANDLE _handle;
DWORD _dwTID;
base_w32thread():_handle(0), _dwTID(0L){}
virtual ~base_w32thread()=0;
public:
bool start(LPSECURITY_ATTRIBUTES psecattrs = NULL, DWORD dwCreateFlags = 0L);
operator HANDLE(){ return _handle; }
protected:
virtual void run()=0;
virtual void onEndThread(){}
static long WINAPI threadfnc( LPARAM lp);
};
#include "StdAfx.h"
#include "base_w32thread.h"
#include <winbase.h>
#include <assert.h>
base_w32thread::~base_w32thread(){}
bool base_w32thread::start(LPSECURITY_ATTRIBUTES psecattrs, DWORD dwCreateFlags){
assert( !_handle);
if( _handle)
return false;
_handle = ::CreateThread( psecattrs, 0,
(LPTHREAD_START_ROUTINE)threadfnc, this, dwCreateFlags, &_dwTID);
return (_handle)?true:false;
}
long WINAPI base_w32thread::threadfnc( LPARAM lp){
assert( lp);
base_w32thread* pThis = (base_w32thread*)lp;
if( pThis)
pThis->run();
pThis->_handle = 0L;
pThis->onEndThread();
return 0L;
}
|
|
|
|
|
What's wrong with:
void CMyDlg::Process( void )
{
}
...
UINT CMyDlg::Process( LPVOID pParam )
{
CMyDlg *pDlg = (CMyDlg *) pParam;
pDlg->Process();
return 0;
}
...
AfxBeginThread(Process, this);
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
The thread procedure accepts a void pointer which you can pass when you create the thread.
If you pass a pointer to an object of a class then you will have access to that object from the
thread. If the thread proc is a static member function of that class, you have complete access
(to public/protected/private members).
class CThreadDemoDlg : public CDialog
{
<font face="Courier New"> static UINT __cdecl MyThreadProc(LPVOID pParam);</font>
protected:
<font face="Courier New">CWinThread *pAnotherThread;
</font>public:
void SomeThreadStarterFunc();
};
<font face="Courier New">void </font><font face="Courier New">CThreadDemoDlg::</font><font face="Courier New">SomeThreadStarterFunc()
{
pAnotherThread = AfxBeginThread(&</font><font face="Courier New">CThreadDemoDlg::MyThreadProc, this);
}
UINT __cdecl </font><font face="Courier New">CThreadDemoDlg::MyThreadProc(LPVOID pParam)
{
</font><font face="Courier New">CThreadDemoDlg *pMyDlg = (</font><font face="Courier New">CThreadDemoDlg *)pParam</font><font face="Courier New">;
...</font><font face="Courier New"><font><font></font></font>
}</font>
Mark
Last modified: 25mins after originally posted --
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thank you all for you great replies
Im trying out Mark's code right now, but its giving me an error message i really dont understand..
On this line:
CThreadDemoDlg *pMyDlg = (CThreadDemoDlg *pParam);
error C2146: syntax error : missing ')' before identifier 'pParam'
error C2059: syntax error : ')'
Ive renamed all the classes to the class on my program, so its not that... What could this be?
Thank you all!
//Johannes
|
|
|
|
|
Fixed. Sorry about that
It should be
<font face="Courier New">CThreadDemoDlg *pMyDlg = (</font><font face="Courier New">CThreadDemoDlg *)pParam</font><font face="Courier New">;</font>
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Ah yes now it compiles, thanks.
But when i add a function to it (one that is connected to CThreadDemoDlg) i get the cant call a nonstatic member function..
error C2352: 'CThreadDemoDlg::SomeFunction' : illegal call of non-static member function
see declaration of 'SomeFunction'
So how should i go about calling the function?
thanks again!
//Johannes
|
|
|
|
|
Johpoke wrote: So how should i go about calling the function?
Can you at least bother to show the code that is producing this error?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|