Theos PowerBasic Museum 2017

General Category => General Discussion => Topic started by: Sam Jackson on September 29, 2013, 03:20:46 AM

Title: Printing from within a C console program.
Post by: Sam Jackson on September 29, 2013, 03:20:46 AM
Greetings all. I couldn't find a better place on the board so I'm posting here. Hope I'm not stepping on any toes.
My question is: Is there a way to print to the default printer from within a C console application? The closest thing I've been able to find is to print to a file and then use the system()  function to print the file.

I'm used to working in PowerBasic and it is very easy to print:
XPRINT ATTACH DEFAULT
XPRINT "Stuff..."
XPRINT CLOSE

Thanks for any input you can provide.
Title: Re: Printing from within a C console program.
Post by: Brice Manuel on September 29, 2013, 05:23:19 AM
How To: Print Using the GDI Print API (http://msdn.microsoft.com/en-us/library/gg263344(v=vs.85).aspx)

How To: Send Data Directly to a GDI Printer (http://msdn.microsoft.com/en-us/library/dd162959(v=vs.85).aspx)

PrintFile: Easy file printing in Windows (http://www.lerup.com/printfile/)
Title: Re: Printing from within a C console program.
Post by: Sam Jackson on September 29, 2013, 05:52:55 PM
Thanks for your reply Brice.
I do know how to print from a Windows Application. I'm looking to print from a console application using the C language.
Title: Re: Printing from within a C console program.
Post by: Michael Mattias on October 14, 2013, 04:05:06 PM
>I'm looking to print from a console application using the C language

You want to WIndows' print from a 'c' program?

If you are familiar with 'XPRINT' as you say, why not put your print logic into a PB-created Dynamic Link Library and write a little wrapper function - using the XPRINT familiy of statements - for the actual "print"  command and call that?

Or, download Gary Beene's print library. He has DLL source right in that package.

MCM



Title: Re: Printing from within a C console program.
Post by: James C. Fuller on October 14, 2013, 05:07:27 PM

Although it may be easier this is what bc9Basic (inherited from BCX) spits out for this:
bc9Basic Code



$ONEXIT "GWGCC.BAT $FILE$ -m32 con"

PRINTER OPEN "Courier New",12,DEFAULT_CHARSET

FOR INTEGER i = 1 to 50
  LPRINT "This is line number ", i , ".  BCX matures again!"
NEXT

LPRINT CHR$(12)  ' Form Feed(eject from paper printer)

PRINTER CLOSE



c code


// *********************************************************************
//    Created with bc9Basic - BASIC To C/C++ Translator (V) 9.1.6.5 (2013/10/04)
//                 BCX (c) 1999 - 2009 by Kevin Diggins
// *********************************************************************
//              Translated for compiling with a C Compiler
//                           On MS Windows
// *********************************************************************
#include <windows.h>    // Win32 Header File
#include <windowsx.h>   // Win32 Header File
#include <commctrl.h>   // Win32 Header File
#include <commdlg.h>    // Win32 Header File
#include <mmsystem.h>   // Win32 Header File
#include <shellapi.h>   // Win32 Header File
#include <shlobj.h>     // Win32 Header File
#include <richedit.h>   // Win32 Header File
#include <objbase.h>    // Win32 Header File
#include <ocidl.h>      // Win32 Header File
#include <winuser.h>    // Win32 Header File
#include <olectl.h>     // Win32 Header File
#include <oaidl.h>      // Win32 Header File
#include <ole2.h>       // Win32 Header File
#include <oleauto.h>    // Win32 Header File
#include <winsock.h>    // Win32 Header File
#include <process.h>    // dos
#include <conio.h>      // dos
#include <direct.h>     // dos
#include <io.h>         // dos
#include <wchar.h>      // dos/linux
#include <ctype.h>      // dos/linux
#include <fcntl.h>      // dos/linux
#include <math.h>       // dos/linux
#include <stdio.h>      // dos/linux
#include <string.h>     // dos/linux
#include <stddef.h>     // dos/linux
#include <stdlib.h>     // dos/linux
#include <setjmp.h>     // dos/linux
#include <time.h>       // dos/linux
#include <stdarg.h>     // dos/linux
#include <sys/types.h> 
#include <sys/stat.h>   


// ***************************************************
// Compiler Defines
// ***************************************************

// C++
#if defined( __cplusplus )
  #define overloaded
  #define C_EXPORT EXTERN_C __declspec(dllexport)
  #define C_IMPORT EXTERN_C __declspec(dllimport)
#else
  #define C_EXPORT __declspec(dllexport)
  #define C_IMPORT __declspec(dllimport)
#endif


// *************************************************
//        User's GLOBAL ENUM blocks
// *************************************************

// *************************************************
//            System Defined Constants
// *************************************************

typedef const char* ccptr;
#define CCPTR const char*
#define cfree free
#define WAITKEY system("pause")
#define cSizeOfDefaultString 2048

// *************************************************
//            User Defined Constants
// *************************************************


// *************************************************
//               Standard Prototypes
// *************************************************

char*   BCX_TmpStr(size_t,size_t   ,int   );
char*   mid (const char*, int, int   );
char*   left (const char*,int);
char*   extract (const char*,const char*);
char*   str (double);
char*   chr(int);
char    *_strstr_(char*,char*);
int  PrinterOpen  (char *               ,int   ,int                );
void PrinterWrite (char*, int   , int    );
void EjectPage    (void);
void PrinterClose (void);
// *************************************************
//          User Defined Types And Unions
// *************************************************


// *************************************************
//                System Variables
// *************************************************


// *************************************************
//            User Global Variables
// *************************************************

static PCHAR   *g_argv;
static int     g_argc;
static HDC     BcxPtr_hDC;
static long    BcxPtr_FontMetrix;
static long    BcxPtr_LineCtr;
static long    BcxPtr_PrinterOn;
static HFONT   BcxPtr_hFont;
static HFONT   BcxPtr_hFontOld;
static DOCINFO BcxPtr_di;
static LOGFONT BcxPtr_Lf;
static TEXTMETRIC BcxPtr_tm;
static char    BcxPtr_Text[cSizeOfDefaultString];
static char    BcxPtr_Buffer[cSizeOfDefaultString];


// *************************************************
//            User Global Initialized Arrays
// *************************************************



// *************************************************
//                 Runtime Functions
// *************************************************

#ifndef BCXTmpStrSize
#define BCXTmpStrSize  2048
#endif
char *BCX_TmpStr (size_t Bites,size_t  iPad,int iAlloc)
{
  static int   StrCnt;
  static char *StrFunc[BCXTmpStrSize];
  StrCnt=(StrCnt + 1) & (BCXTmpStrSize-1);
  if(StrFunc[StrCnt]) {free (StrFunc[StrCnt]); StrFunc[StrCnt] = NULL;}
#if defined BCX_MAX_VAR_SIZE
  if(Bites*sizeof(char)>BCX_MAX_VAR_SIZE)
  {
  printf("Buffer Overflow caught in BCX_TmpStr - requested space of %d EXCEEDS %d\n",(int)(Bites*sizeof(char)),BCX_MAX_VAR_SIZE);
  abort();
  }
#endif
  if(iAlloc) StrFunc[StrCnt]=(char*)calloc(Bites+iPad+1,sizeof(char));
  return StrFunc[StrCnt];
}


char *left (const char *S, int length)
{
  register int tmplen = strlen(S);
  if(length<1) return BCX_TmpStr(1,0,1);
  if(length<tmplen) tmplen=length;
  char *strtmp = BCX_TmpStr(tmplen,1,1);
  return (char*)memcpy(strtmp,S,tmplen);
}


char *mid (const char *S, int start, int length)
{
  char *strtmp;
  register int tmplen = strlen(S);
  if(start>tmplen||start<1) return BCX_TmpStr(1,1,1);
  if (length<0 || length>(tmplen-start)+1)
    length = (tmplen-start)+1;
  strtmp = BCX_TmpStr(length,1,1);
  return (char*)memcpy(strtmp,&S[start-1],length);
}


char *extract (const char *mane, const char *match)
{
  register char *a;
  register char *strtmp = BCX_TmpStr(strlen(mane),1,1);
  if(*match!=0)
    {
      a=_strstr_((char*)mane,(char*)match);
      if(a) return (char*)memcpy(strtmp,mane,a-mane);
    }
  return strcpy(strtmp,mane);
}


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


char *chr (int a)
{
  register char *strtmp = BCX_TmpStr(2,1,1);
  strtmp[0]  = a;
  return strtmp;
}


char *_strstr_(char *String, char *Pattern)
{
  int   mi=-1;
  while(Pattern[++mi])
   {
     if(String[mi]==0) return 0;
     if(String[mi]!=Pattern[mi])
       { String++; mi=-1; }
   }
  return String;
}


int PrinterOpen (char * fontname,int PointSize,int charset)
{
  char zPrinter[cSizeOfDefaultString];
  GetProfileString("WINDOWS","DEVICE","",zPrinter,127);
  strcpy(zPrinter,(char*)extract(zPrinter,","));
  strcpy(BcxPtr_Text,"Printing ...");
  BcxPtr_hDC=CreateDC("",zPrinter,"",0);
  if(!BcxPtr_hDC) return 0;
  BcxPtr_di.cbSize=sizeof(BcxPtr_di);
  BcxPtr_di.lpszDocName=BcxPtr_Text;
  StartDoc(BcxPtr_hDC,&BcxPtr_di);
  StartPage(BcxPtr_hDC);
  SetTextAlign(BcxPtr_hDC,TA_BASELINE | TA_NOUPDATECP | TA_LEFT);
  SetBkMode(BcxPtr_hDC,TRANSPARENT);
  BcxPtr_Lf.lfHeight=PointSize*GetDeviceCaps(BcxPtr_hDC,LOGPIXELSY)/72;
  BcxPtr_Lf.lfWidth=0;
  BcxPtr_Lf.lfEscapement=0;
  BcxPtr_Lf.lfOrientation=0;
  BcxPtr_Lf.lfWeight=FW_NORMAL;
  BcxPtr_Lf.lfItalic=0;
  BcxPtr_Lf.lfUnderline=0;
  BcxPtr_Lf.lfStrikeOut=0;
  BcxPtr_Lf.lfCharSet=charset;
  BcxPtr_Lf.lfOutPrecision=OUT_DEFAULT_PRECIS;
  BcxPtr_Lf.lfClipPrecision=CLIP_DEFAULT_PRECIS;
  BcxPtr_Lf.lfQuality=PROOF_QUALITY;
  BcxPtr_Lf.lfPitchAndFamily=VARIABLE_PITCH | FF_ROMAN;
  strcpy(BcxPtr_Lf.lfFaceName,fontname);
  BcxPtr_hFont=CreateFontIndirect(&BcxPtr_Lf);
  BcxPtr_hFontOld=(HFONT)SelectObject(BcxPtr_hDC,BcxPtr_hFont);
  GetTextMetrics(BcxPtr_hDC,&BcxPtr_tm);
  BcxPtr_FontMetrix=BcxPtr_Lf.lfHeight;
  BcxPtr_PrinterOn=1;
  return   1;
}


void PrinterWrite (char *TextIn, int CPL, int LPP)
{
  char sTemp[cSizeOfDefaultString]={0};
  if(!BcxPtr_PrinterOn)
    {
      MessageBox (GetActiveWindow(),"Problem with Printer","",0);
      return;
    }
  strcpy(sTemp,TextIn);
  for(;;)
    {
      if(strlen(sTemp)>CPL)
        {
          strcpy(BcxPtr_Text,(char*)left(sTemp,CPL));
          strcpy(sTemp,(char*)mid(sTemp,CPL+1,-1));
        }
      else
        {
          strcpy(BcxPtr_Text,sTemp);
          *sTemp=0;
        }
      if(BcxPtr_LineCtr>LPP)
        {
          EndPage(BcxPtr_hDC);
          BcxPtr_LineCtr=0;
          StartPage(BcxPtr_hDC);
        }
      BcxPtr_LineCtr+=1;
      TextOut(BcxPtr_hDC,20,BcxPtr_FontMetrix*BcxPtr_LineCtr,BcxPtr_Text,strlen(BcxPtr_Text));
      if(sTemp[0]==0) break;
    }
}


void PrinterClose (void)
{
  if(!BcxPtr_PrinterOn) return;
  SelectObject(BcxPtr_hDC,BcxPtr_hFontOld);
  DeleteObject(BcxPtr_hFont);
  EndPage(BcxPtr_hDC);
  EndDoc(BcxPtr_hDC);
  DeleteDC(BcxPtr_hDC);
  BcxPtr_LineCtr=0;
  BcxPtr_PrinterOn=0;
}


void EjectPage(void)
{
  EndPage(BcxPtr_hDC);
  BcxPtr_LineCtr=0;
  StartPage(BcxPtr_hDC);
}



// ************************************
//       User Subs and Functions
// ************************************

// *************************************************
//                  Main Program
// *************************************************

int main(int argc, char *argv[])
{
  g_argc = argc;
  g_argv = argv;
PrinterOpen("Courier New",12,DEFAULT_CHARSET);
  {register int i;
for(i=1; i<=50; i+=1)
  {
    sprintf(BcxPtr_Buffer,"%s% d%s","This is line number ",(int)i,".  BCX matures again!");
    PrinterWrite(BcxPtr_Buffer, 80,  60);
  }
  }

sprintf(BcxPtr_Buffer,"%s",chr( 12));
PrinterWrite(BcxPtr_Buffer, 80,  60);
PrinterClose();
  return 0;   /* End of main program */
}