1

With the help of BCX I managed to create some C++ code that will allow you to send text to your printer and specify the font and other things. Play around with the options to suit your own needs. I have to admire the genius behind BCX, even though it spits out more code than you want! NOTICE: Please experiment with this code, modify it, improve it, and claim it as yours!!!!

// send text to a printer via the LPT1 or USB port
// this program allows you to set tons of printer options
// in the PrinterOpen() and PrinterWrite() functions
// link with gdi32.lib or in case of Dev-C++ with libgdi32.a
// Project>>Project Options>>Parameters>>Add Lib>>libgdi32.a
// BCX generated C code heavily modified for Dev C++
// this is a Console Application    vegaseat   21dec2004

#include <iostream>
#include <windows.h>

static HDC     Prn_hDC;
static long    Prn_FontMetrix;
static long    Prn_LineCtr;
static long    Prn_PrinterOn;
static HFONT   Prn_hFont;
static HFONT   Prn_hFontOld;
static DOCINFO Prn_di;
static LOGFONT Prn_Lf;
static TEXTMETRIC Prn_tm;
static char    Prn_Text[2048];
static char    Prn_Buffer[2048];

// prototypes
char *BCX_TmpStr(size_t);
char *mid (char*, int, int=-1);
char *left (char*, int);
char *extract (char*, char*);
char *str (double);
int  PrinterOpen  (void);
void PrinterWrite (char*);
void EjectPage    (void);
void PrinterClose (void);


using namespace std;

int main()
{
  int k;
	
  cout << "Make sure your printer is connected and on!\n";
	
  PrinterOpen();
  
  // use five lines as top margin
  for(k = 0; k < 5; k++)
    PrinterWrite(" ");
    
  // print next 50 lines of goofy text
    for(k = 1; k <= 50; k++)
  {
    sprintf(Prn_Buffer,"%s %2d %s","Printing line number", k,"    Zzzzzz ...");
    PrinterWrite(Prn_Buffer);
  }
  //EjectPage();  // optional to clear out the printer
  
  PrinterClose();
  
  cin.get();  // wait
  return 0;
}


// circular storage to minimize memory leaks
char *BCX_TmpStr (size_t Bites)
{
  static int StrCnt;
  static char *StrFunc[2048];
  StrCnt = (StrCnt + 1) & 2047;
  if (StrFunc[StrCnt]) free (StrFunc[StrCnt]);
  return StrFunc[StrCnt] = (char*)calloc(Bites+128,sizeof(char));
}


// needed for word wrap feature
char *left (char *S, int length)
{
  register int tmplen = strlen(S);
  char *strtmp = BCX_TmpStr(tmplen);
  strcpy (strtmp,S);
  if (length > tmplen)
    strtmp[tmplen] = 0;
  else
    strtmp[length] = 0;
  return strtmp;
}


// needed for word wrap feature
char *mid (char *S, int start, int length)
{
  register int tmplen = strlen(S);
  char *strtmp;
  if (start > tmplen || start < 1) return BCX_TmpStr(1);
  if (length < 0) length = tmplen - start + 1;
  strtmp = BCX_TmpStr(length);
  strncpy(strtmp,&S[start-1],length);
  strtmp[length] = 0;
  return strtmp;
}


char *extract (char *mane, char *match)
{
  register char *a;
  register char *strtmp = BCX_TmpStr(strlen(mane));
  strcpy(strtmp,mane);
  a = strstr(mane,match);
  if (a) strtmp[a-mane] = 0;
  return strtmp;
}


char *str (double d)
{
  register char *strtmp = BCX_TmpStr(16);
  sprintf(strtmp,"% .15G",d);
  return strtmp;
}


//
// set all the printer options including font
//
int PrinterOpen (void)
{
  int  PointSize = 12;
  char zPrinter[2048];
  
  GetProfileString("WINDOWS","DEVICE","",zPrinter,127);
  // extract up to the comma
  strcpy(zPrinter, (char*)extract(zPrinter,","));
  strcpy(Prn_Text,"Printing ...");
  Prn_hDC = CreateDC("",zPrinter,"",0);
  if (!Prn_hDC) return 0;
  Prn_di.cbSize = sizeof(Prn_di);
  Prn_di.lpszDocName = Prn_Text;
  StartDoc(Prn_hDC,&Prn_di);
  StartPage(Prn_hDC);
  SetTextAlign(Prn_hDC,TA_BASELINE | TA_NOUPDATECP | TA_LEFT);
  SetBkMode(Prn_hDC,TRANSPARENT);
  //
  // Prn_Lf deals with the font, got to play with this, if you
  // want a smaller or larger font size!  Don't forget to change
  // max lines and max char/line in PrinterWrite() accordingly
  //
  Prn_Lf.lfHeight = PointSize*GetDeviceCaps(Prn_hDC,LOGPIXELSY)/72;
  Prn_Lf.lfWidth = 0;
  Prn_Lf.lfEscapement = 0;
  Prn_Lf.lfOrientation = 0;
  Prn_Lf.lfWeight = FW_NORMAL;
  Prn_Lf.lfItalic = 0;
  Prn_Lf.lfUnderline = 0;
  Prn_Lf.lfStrikeOut = 0;
  Prn_Lf.lfCharSet = ANSI_CHARSET;
  Prn_Lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
  Prn_Lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  Prn_Lf.lfQuality = PROOF_QUALITY;
  Prn_Lf.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
  strcpy(Prn_Lf.lfFaceName,TEXT("Courier New"));
  Prn_hFont = CreateFontIndirect(&Prn_Lf);
  Prn_hFontOld = (HFONT)SelectObject(Prn_hDC,Prn_hFont);
  GetTextMetrics(Prn_hDC,&Prn_tm);
  Prn_FontMetrix = Prn_Lf.lfHeight;
  Prn_PrinterOn = 1;
  return 1;
}


void PrinterWrite (char *TextIn)
{
  int LPP = 60;  // max line numbers depending on font size
  int CPL = 80;  // max char/line depending on font size
  char sTemp[2048] = {0};
  if (!Prn_PrinterOn)
  {
    MessageBox (GetActiveWindow(),"Printer Problem!","",0);
    return;
  }
  strcpy(sTemp,TextIn);
  while(1)
  {
    // split text if it exceeds max line characters
	  if (strlen(sTemp) > CPL)
    {
      strcpy(Prn_Text, (char*)left(sTemp,CPL));
      strcpy(sTemp, (char*)mid(sTemp,CPL+1));
    }
    else
    {
      strcpy(Prn_Text,sTemp);
      *sTemp = 0;
    }
    Prn_LineCtr++;
    if (Prn_LineCtr >= LPP)
    {
      // max lines exceeded, eject this page for next page
	    EndPage(Prn_hDC);
      Prn_LineCtr = 0;
      StartPage(Prn_hDC);
    }
    TextOut(Prn_hDC,20,Prn_FontMetrix*Prn_LineCtr,Prn_Text,strlen(Prn_Text));
    if(sTemp[0] == 0) break;
  }
}


void PrinterClose (void)
{
  if (!Prn_PrinterOn) return;
  SelectObject(Prn_hDC,Prn_hFontOld);
  DeleteObject(Prn_hFont);
  EndPage(Prn_hDC);
  EndDoc(Prn_hDC);
  DeleteDC(Prn_hDC);
  Prn_LineCtr = 0;
  Prn_PrinterOn = 0;
}


void EjectPage(void)
{
  EndPage(Prn_hDC);
  Prn_LineCtr = 0;
  StartPage(Prn_hDC);
}
2
Contributors
1
Reply
2
Views
12 Years
Discussion Span
Last Post by cybercode
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.