Need some help on a project I'm porting over Topic is solved

If you are using wxDev-C++ for your wxWidgets design, please ask your questions here instead of in IDE Related.
Post Reply
Mixael
Earned a small fee
Earned a small fee
Posts: 13
Joined: Thu Apr 27, 2006 6:24 pm

Need some help on a project I'm porting over

Post by Mixael »

I have been working on a project for work (to make MY life easier :) ), and had originally been doing it in VB6. After finding wxDevcpp, I decided to try it in C++ instead.

A word of warning...I'm relatively new to C++ and REAL new to wxWidgets.

In my VB project, I had a form that the user (me) would fill out, and if it were completely filled out (meter readings over a period of three months, actually), I could print the form itself, with all the data.

Is there a way to do the same thing in wxDevCPP?

Michael
toxicBunny
Super wx Problem Solver
Super wx Problem Solver
Posts: 424
Joined: Tue Jul 12, 2005 8:44 pm
Location: Alabama, USA

Post by toxicBunny »

I don't think there is any way to print a form directly with wxWidgets. However, you could probably take a screen shot of the form as a bitmap and print that. Take a look at the following post for capturing a screen image.

http://forums.wxwidgets.org/viewtopic.p ... c&start=30

For printing the bitmap, take a look at the printing sample.

-Scott
wxMSW 2.6.2, VS 2002, 2003 and 2005, Code::Blocks and mingw, Windows XP Pro
tbreina
Moderator
Moderator
Posts: 1289
Joined: Thu Nov 25, 2004 7:38 pm
Location: Coronado, CA

Post by tbreina »

I don't think there is any way to print a form directly with wxWidgets. However, you could probably take a screen shot of the form as a bitmap and print that. Take a look at the following post for capturing a screen image.
I think NinjaNL knows how to print from a wxTextCtrl widget. You might want to PM him. Of course, the screenshot idea would work too.

-Tony
Everybody's got something to hide except for me and my monkey.
Mixael
Earned a small fee
Earned a small fee
Posts: 13
Joined: Thu Apr 27, 2006 6:24 pm

Post by Mixael »

Okay, thanks. I'll give the method from toxicBunny a shot (well, from the linked post :) )

Failing that, I'll PM NinjaNL. Thanks to both of you!

Michael
tbreina
Moderator
Moderator
Posts: 1289
Joined: Thu Nov 25, 2004 7:38 pm
Location: Coronado, CA

Post by tbreina »

http://forums.wxwidgets.org/viewtopic.p ... wxtextctrl

In this thread, Guru shows how to do it using wxEasyHTMLPrinting. You'll need to do a little manual programming, but it shouldn't be too hard.

-Tony
Everybody's got something to hide except for me and my monkey.
NinjaNL
Moderator
Moderator
Posts: 899
Joined: Sun Oct 03, 2004 10:33 am
Location: Oosterwolde, Netherlands

Post by NinjaNL »

If I read the question correctly, then you seem to have several text controls. If you wish to have all the data in a single text control, then pass the text control as a parameter to the printout.

Sample code:

Code: Select all

/*
 * WxToolButton2Click
 */
void PrintingFromTextCtrlFrm::OnPrintPreview(wxCommandEvent& event)
{
    // Pass two printout objects: for preview, and possible printing.
    wxPrintDialogData printDialogData(* g_printData);

    wxPrintPreview *preview = new wxPrintPreview(new TextCtrlPrintout(WxMemo1), new TextCtrlPrintout(WxMemo1), & printDialogData );
//    wxPrintPreview *preview = new wxPrintPreview(new EditPrint(WxMemo1), new EditPrint(WxMemo1), & printDialogData );

    if (!preview->Ok())
    {
        delete preview;
        wxMessageBox(_T("There was a problem previewing.\nPerhaps your current printer is not set correctly?"), _T("Previewing"), wxOK);
        return;
    }

    wxPreviewFrame *frame = new wxPreviewFrame(preview, this, _T("Demo Print Preview"), wxPoint(100, 100), wxSize(600, 650));
    frame->Centre(wxBOTH);
    frame->Initialize();
    frame->Show();

}
Note that this uses a TextCtrlPrintout. This is sample code, which needs working on to get it to do everything you wqant, but it might point you in the right direction.

Code: Select all

#ifdef __GNUG__
#pragma implementation
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "TxtCtlPrn.h"        // Printout for wxTextCtrl
//int orientation = wxPORTRAIT;

int LeftMargin   = 20; // Default for 1" left margin
int RightMargin  = 20; // Default for 1" right margin
int TopMargin    = 20; // Default for 1" top margin
int BottomMargin = 20; // Default for 1" bottom margin

// NOTE: Adjust the max_lines according to the wxFONT size
int max_lines = 53; // Maximum number of lines per page

bool TextCtrlPrintout::OnPrintPage(int page)
{
    wxDC *dc = GetDC();
    if (dc)
    {

        DrawTextPage(dc, page, LeftMargin, RightMargin, TopMargin, BottomMargin);

        return TRUE;
    }
    else
        return FALSE;
}

bool TextCtrlPrintout::HasPage(int pageNum)
{
    // Calculate the number of pages in this document
    int minPage, maxPage, selPageFrom, selPageTo;
    GetPageInfo(&minPage, &maxPage, &selPageFrom, &selPageTo);
    return (pageNum == minPage) || (pageNum <= maxPage);
}

bool TextCtrlPrintout::OnBeginDocument(int startPage, int endPage)
{
     if (!wxPrintout::OnBeginDocument(startPage, endPage))
         return FALSE;
 
     return TRUE;
    
//        return wxPrintout::OnBeginDocument(startPage, endPage);

}

void TextCtrlPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom,
                                   int *selPageTo)
{
     int lines = m_textctrl->GetNumberOfLines();
     int first_page = 1; // Always starting on page one
     int last_page = 1;  // Default is the first page
 
     *minPage = first_page;     // Always starting on page one
     *selPageFrom = first_page; // Always starting on page one
 
     // Scale the pages by the number of lines
     for(;;)
     {
         if(lines <= max_lines)
             break;
         lines = lines - max_lines;
         last_page++; // Increment the page count
     }
 
     *selPageTo = last_page;
     *maxPage = last_page;
}

void TextCtrlPrintout::DrawTextPage(wxDC *dc)
// This version of DrawTextPage() dumps the entire contents
// of the text frame into the device context.
{
    // Make sure the DC font is set or the program will crash in motif
    dc->SetFont(textFont);

    wxString buf; // Maximum characters per line
    int lines = m_textctrl->GetNumberOfLines();

    wxCoord w, h; // Text width and height
    wxCoord x, y; // Device Context Coordinates
    x = y = w = h = 0;

    dc->SetDeviceOrigin(x, y);

    for(int reps = 0; reps < lines; reps++)
    {

        buf = m_textctrl->GetLineText(reps);

        // Strip off Carriage Returns and Line Feeds
        unsigned len = 0;
        for(unsigned i = 0; (buf[i] != '\r') && (buf[i] != '\n'); i++)
            len++;
        char *s = new char[len];
        s[len] = '\0';
        memmove(s, buf, len);

        // Draw text into the Device Context and increment y postion
        dc->DrawText(s, x , y);
        dc->GetTextExtent(s, &w, &h);
        y = y + h;
    }
}

void TextCtrlPrintout::DrawTextPage(wxDC *dc, int page)
// This version of DrawTextPage() writes the contents of the
// text frame page by page into the device context.
{
    // Make sure the DC font is set or the program will crash in motif
    dc->SetFont(textFont);

    wxString buf; // Maximum characters per line

    wxCoord w, h; // Text width and height
    wxCoord x, y; // Device Context Coordinates
    x = y = w = h = 0;

    dc->SetDeviceOrigin(x, y);

    int end = page * max_lines;  // Last line to write
    int start = end - max_lines; // First line to write
    int total_lines = m_textctrl->GetNumberOfLines();

    for(int reps = start; reps < end; reps++)
    {
        if(reps > total_lines)
            break; // Do not go past the end of text

        buf = m_textctrl->GetLineText(reps);

        // Strip off Carriage Returns and Line Feeds
        unsigned len = 0;
        for(unsigned i = 0; (buf[i] != '\r') && (buf[i] != '\n'); i++)
            len++;
        char *s = new char[len];
        s[len] = '\0';
        memmove(s, buf, len);

        // Draw text into the Device Context and increment y postion
        dc->DrawText(s, x , y);
        dc->GetTextExtent(s, &w, &h);
        y = y + h;
    }
}

void TextCtrlPrintout::DrawTextPage(wxDC *dc, int page,
                                    int leftMargin, int rightMargin,
                                    int topMargin, int bottomMargin)
// This version of DrawTextPage() writes the contents of the
// text frame page by page into the device context with margins.
{
    // Make sure the DC font is set or the program will crash in motif
    dc->SetFont(textFont);

    // Get the logical pixels per inch of screen and printer
    int ppiScreenX, ppiScreenY;
    GetPPIScreen(&ppiScreenX, &ppiScreenY);
    int ppiPrinterX, ppiPrinterY;
    GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);

    // Scale the DC so that the printout roughly represents the
    // the screen scaling.
    float scale = (float)((float)ppiPrinterX/(float)ppiScreenX);

    // Check real page size in case it is reduced by print preview
    int pageWidth, pageHeight;
    wxCoord w, h;
    dc->GetSize(&w, &h);
    GetPageSizePixels(&pageWidth, &pageHeight);

    // Do not change if printer pageWidth == current DC width
    float overallScale = scale * (float)(w/(float)pageWidth);
    dc->SetUserScale(overallScale, overallScale);

    // Calculate conversion factor for converting millimetres into
    // logical units. There are approx. 25.1 mm to the inch. There
    // are ppi device units to the inch. Therefore 1 mm corresponds
    // to ppi/25.1 device units.
    float logUnitsFactor = (float)(ppiPrinterX/(scale*25.1));

    int pageWidthMM, pageHeightMM;
    GetPageSizeMM(&pageWidthMM, &pageHeightMM);

    float leftMarginLogical = (float)(logUnitsFactor*leftMargin);
    float topMarginLogical = (float)(logUnitsFactor*topMargin);

    float bottomMarginLogical = (float)(logUnitsFactor*(pageHeightMM - bottomMargin));

    float rightMarginLogical = (float)(logUnitsFactor*(pageWidthMM - rightMargin));

    wxString buf; // Maximum characters per line

    int end = page * max_lines;  // Last line to write
    int start = end - max_lines; // First line to write
    int total_lines = m_textctrl->GetNumberOfLines();

    wxCoord textW, textH; // Text width and height
    wxCoord xpos = (wxCoord)leftMarginLogical;
    wxCoord ypos = (wxCoord)topMarginLogical;

    for(int reps = start; reps < end; reps++)
    {
        if(reps > total_lines)
            break; // Do not go past the end of text

        buf = m_textctrl->GetLineText(reps);

        // Strip off Carriage Returns and Line Feeds
        unsigned len = 0;
        for(unsigned i = 0; (buf[i] != '\r') && (buf[i] != '\n'); i++)
            len++;
        char *s = new char[len];
        s[len] = '\0';
        memmove(s, buf, len);

        // Draw text into the Device Context and increment ypos postion
        dc->DrawText(s, xpos , ypos);
        dc->GetTextExtent(s, &textW, &textH);
        ypos = ypos + textH;
    }
}

Code: Select all

#ifndef __TXTCTRLPRN_h__
#define __TXTCTRLPRN_h__

#if defined(__GNUG__) && !defined(__APPLE__)
#pragma interface
#endif

#ifdef __BORLANDC__
	#pragma hdrstop
#endif

#ifndef WX_PRECOMP
	#include <wx/wx.h>
	#include <wx/frame.h>
#else
	#include <wx/wxprec.h>
#endif

#include <wx/print.h>
#include <wx/textctrl.h>
// Printer default values


class TextCtrlPrintout: public wxPrintout
{
    public:
//        TextCtrlPrintout(wxTextCtrl *textctrl, wxChar *title = "My printout"): wxPrintout(title)
        TextCtrlPrintout(wxTextCtrl *textctrl, wxChar *title = _T("My printout")): wxPrintout(title)
        {
            m_textctrl = textctrl;
            m_printed = 0;
//            textFont = wxFont(12, wxSWISS, wxNORMAL, wxNORMAL);
            textFont.Create(12, wxSWISS, wxNORMAL, wxNORMAL);
        }
        
        ~TextCtrlPrintout()
        {
        }

     public:
         bool OnPrintPage(int page);
         bool HasPage(int page);
         bool OnBeginDocument(int startPage, int endPage);
         void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom,
                          int *selPageTo);
 
         void DrawTextPage(wxDC *dc); // Write entire contents of text frame
         void DrawTextPage(wxDC *dc, int page); // Write page by page
 
         // Write page by page with left, right, top and bottom margins
         void DrawTextPage(wxDC *dc, int page, int leftMargin, int rightMargin, int topMargin, int bottomMargin);
    private:
        wxTextCtrl *m_textctrl;
        int m_printed;
        wxFont textFont;

};

#endif
Failing that, you may want to create a report of your results, and perhaps use wxReportWriter.
Follow the development of my screenplay authoring program at http://wxscreenplaywriter.blogspot.com/
Post Reply