005
26.11.2002, 19:27 Uhr
Uwe
C/C++ Master (Administrator)
|
Hallo Flo, hat zwar etwas länger gedauert aber...
Projektformat Dialoganwendung mit zwei Schaltflächen: IDC_OPEN_FILE und IDC_PRINT_FILE. Hinzufügen einer von CDocument abgeleiteten Klasse, in dieser alles was notwendig ist "public:" machen. Variable:
C++: |
public: CStringList filelines_str ;
|
Funktion
C++: |
void CMyDoc::OpenFile() { mydlg d;
if ( d.DoModal( ) == IDOK ){ CStdioFile fr ( d.filepath_str, CFile::modeRead ) ;//| CFile::typeText ) ; filelines_str.RemoveAll( ) ; CString str ; while ( fr.ReadString ( str ) ){ filelines_str.AddTail ( str ) ; } SetTitle ( d.filename_str ) ; }
}
|
hinzufügen. "mydlg" ist von CDialog abgeleitet und dient der Auswahl der entsprechenden zu druckenden Datei. In diesem ist ein Eingabefeld (IDC_FILE_PHATH) und ein Button (IDC_BROWSE). Dem Eingabefeld ist
C++: |
CString filepath_str;
|
zugeordnet. Weithin existiert eine
C++: |
CString filename_str ;
|
Variable, welch public ist.
C++: |
BOOL mydlg::OnInitDialog() { filepath_str = "Enter filename here or browse" ; return CDialog::OnInitDialog( ) ; }
void mydlg::OnBrowse() { CFileDialog f ( TRUE, NULL, NULL, NULL, "Text Files(*.txt)|*.txt|CPP Files(*.cpp,*.h)|*.cpp;*.h||" ) ;
if ( f.DoModal( ) == IDOK ){ CString s = f.GetPathName( ) ; filename_str = f.GetFileName( ) ; SetDlgItemText ( IDC_FILE_PHATH, s ) ; } }
|
Variablenliste der Hauptdialogklasse:
C++: |
private: CMyDoc mydoc ; CFont scr_font, prn_font ; int scr_ht, scr_wd, prn_ht, prn_wd, linesperpage, charsperline, max_page ; CStringList prn_str ;
|
C++: |
ON_BN_CLICKED(IDC_PRINT, OnPrintIt)
|
Dafür die Behandlung:
C++: |
void CPrintItDlg::OnPrintIt() { CDC dc; CPrintDialog printDlg(FALSE);
if (printDlg.DoModal() == IDCANCEL) return;
dc.Attach(printDlg.GetPrinterDC()); dc.m_bPrinting = TRUE;
DOCINFO di; ::ZeroMemory (&di, sizeof (DOCINFO)); di.cbSize = sizeof (DOCINFO); di.lpszDocName = "Database";
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.Detach();
}
|
Und der Rest:
C++: |
void CPrintItDlg::OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo) { pDC -> SetMapMode ( MM_LOENGLISH ) ; prn_font.CreatePointFont ( 100, "Arial", pDC ) ; CFont *prevfont = pDC -> SelectObject ( &prn_font ) ;
TEXTMETRIC tm ; pDC -> GetTextMetrics ( &tm) ; prn_ht = tm.tmHeight + tm.tmExternalLeading ; prn_wd = tm.tmAveCharWidth + 1 ;
// total number of pixels per page in device coordinates int vertpixels = pDC -> GetDeviceCaps ( VERTRES ) ; int horzpixels = pDC -> GetDeviceCaps ( HORZRES ) ;
// convert into logical coordinates CSize sz ( horzpixels, vertpixels ) ; pDC -> DPtoLP ( &sz ) ;
linesperpage = sz.cy / prn_ht ; charsperline = sz.cx / prn_wd ; // make space for header and footer linesperpage = linesperpage - 10 ;
CString tempstr ; POSITION temppos = mydoc.filelines_str.GetHeadPosition( ) ; int tempcount = mydoc.filelines_str.GetCount( ) ; for ( int i = 0 ; i < tempcount ; i++ ) { tempstr = mydoc.filelines_str.GetNext ( temppos ) ; prn_str.AddTail ( tempstr ) ; }
POSITION pos = prn_str.GetHeadPosition( ) ; POSITION pos_prev1, pos_prev2 ; int count = prn_str.GetCount( ) ;
CString str, pa ; for ( i = 0 ; i < count ; i++ ) { if ( pos == NULL ) break ;
pos_prev1 = pos_prev2 = pos ; str = prn_str.GetNext ( pos ) ;
str.Replace ( "\t", " " ) ;
int len = str.GetLength( ) ; if ( len > charsperline ) { int linecount = max ( 1, ( len + ( charsperline - 1 ) ) / charsperline ) ; CString left_str ; int remain_len, left_len = 0 ; for ( int j = 0 ; j < linecount ; j++ ) { left_str = str.Left ( charsperline ) ; prn_str.InsertAfter ( pos_prev2, left_str ) ; left_len += left_str.GetLength( ) ; remain_len = len - left_len ; prn_str.GetNext ( pos_prev2 ) ; str = str.Right ( remain_len ) ; } str = "" ;
pa = prn_str.GetAt ( pos_prev1 ) ; prn_str.RemoveAt ( pos_prev1 ) ; pa.FreeExtra( ) ; } else { prn_str.InsertAfter ( pos_prev1, str ) ; pa = prn_str.GetAt ( pos_prev1 ) ; prn_str.RemoveAt ( pos_prev1 ) ; pa.FreeExtra( ) ; } }
count = prn_str.GetCount( ) ; max_page = max ( 1, ( count + ( linesperpage - 1 ) ) / linesperpage ) ; pDC -> SelectObject ( prevfont ) ; pInfo -> SetMaxPage ( max_page ) ; }
void CPrintItDlg::OnPrint(CDC *pDC, CPrintInfo *pInfo) { CFont* prevfont = pDC -> SelectObject ( &prn_font ) ;
TEXTMETRIC tm ; pDC -> GetTextMetrics ( &tm ) ;
// center coordinate int horzpixels = pDC -> GetDeviceCaps ( HORZRES ) ; CSize sz ( horzpixels, 0 ) ; pDC -> DPtoLP ( &sz ) ; int center = sz.cx / 2 ;
// printheader CString title = mydoc.GetTitle( ) ; UINT l = center - ( ( title.GetLength( ) / 2 ) * tm.tmAveCharWidth ) ; pDC -> TextOut ( l, 0, title ) ;
// printpage int count = prn_str.GetCount( ) ;
int start = ( ( pInfo -> m_nCurPage ) - 1 ) * linesperpage ; int end = start + linesperpage ; POSITION pos = prn_str.FindIndex ( linesperpage * ( ( pInfo -> m_nCurPage ) - 1 ) ) ; for ( int i = start, y = - ( prn_ht * 5 ) ; i < end && i < count ; i++ ) { pDC -> TextOut ( 10, y, ( CString ) prn_str.GetNext ( pos ) ) ; y -= prn_ht ; }
// printfooter CString pagenumber ; pagenumber.Format ( "%2d / %2d", pInfo -> m_nCurPage, max_page ) ; l = center - ( ( pagenumber.GetLength( ) / 2 ) * tm.tmAveCharWidth ) ; pDC -> TextOut ( l, - ( linesperpage + 5 + 3 ) * prn_ht, pagenumber ) ;
pDC -> SelectObject ( prevfont ) ; }
void CPrintItDlg::OnEndPrinting(CDC *pDC, CPrintInfo *pInfo) { prn_str.RemoveAll( ) ; prn_font.DeleteObject( ) ; }
|
Formatierung der Seite ist Dir überlassen. Bei Bedarf schick ich Dir das Projekt. Mit 'ner View was zu basteln geht nich gut ;-) -- "Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind."
Bis dann... Uwe |