388 lines
9.6 KiB
C
388 lines
9.6 KiB
C
|
#define INCLUDE_DRIVINIT_H
|
||
|
#include <windows.h>
|
||
|
#include <string.h>
|
||
|
#include <stdio.h>
|
||
|
#include "edit.h"
|
||
|
#include "win1632.h"
|
||
|
|
||
|
#define PSTR_LEN 256
|
||
|
static char ProfileString[PSTR_LEN];
|
||
|
static char _FAR *Title;
|
||
|
static char *Rest;
|
||
|
static char *DeviceName;
|
||
|
static char *DriverName;
|
||
|
static char *PortName;
|
||
|
static char _FAR *PrinterData;
|
||
|
static char DriverFormat[] = "%s.DRV";
|
||
|
|
||
|
/*
|
||
|
* PrinterDC - obtains a DC to the current printer
|
||
|
*/
|
||
|
HDC PrinterDC( void )
|
||
|
{
|
||
|
char *tmp;
|
||
|
HDC hdc;
|
||
|
char str[128];
|
||
|
HINSTANCE hlib;
|
||
|
FARPROC fp;
|
||
|
|
||
|
/*
|
||
|
* get printer device type
|
||
|
*/
|
||
|
PrinterSupport = PSUPP_NONE;
|
||
|
GetProfileString( "WiNdOwS", "dEvIcE", "", ProfileString, PSTR_LEN );
|
||
|
|
||
|
/*
|
||
|
* find first ',' and insert a 0; this is the device name
|
||
|
*/
|
||
|
DeviceName = ProfileString;
|
||
|
tmp = ProfileString;
|
||
|
while( 1 ) {
|
||
|
if( *tmp == ',' ) {
|
||
|
*tmp = 0;
|
||
|
tmp++;
|
||
|
break;
|
||
|
}
|
||
|
if( !(*tmp) ) {
|
||
|
DeviceName[0] = 0;
|
||
|
return( NULL );
|
||
|
}
|
||
|
tmp++;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* find next ',' and insert a 0; this terminates the driver name
|
||
|
*/
|
||
|
DriverName = tmp;
|
||
|
while( 1 ) {
|
||
|
if( *tmp == ',' ) {
|
||
|
*tmp = 0;
|
||
|
tmp++;
|
||
|
break;
|
||
|
}
|
||
|
if( !(*tmp) ) {
|
||
|
DeviceName[0] = 0;
|
||
|
return( NULL );
|
||
|
}
|
||
|
tmp++;
|
||
|
}
|
||
|
if( !(*tmp) ) {
|
||
|
DeviceName[0] = 0;
|
||
|
return( NULL );
|
||
|
}
|
||
|
PortName = tmp;
|
||
|
|
||
|
/*
|
||
|
* check if printer has changed, if so, toss the data
|
||
|
*/
|
||
|
if( PrinterData != NULL && _strcmp( PrinterData, DeviceName ) ) {
|
||
|
MemFree( PrinterData );
|
||
|
PrinterData = NULL;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* get the printer dc
|
||
|
*/
|
||
|
hdc = CreateDC( DriverName, DeviceName, PortName, NULL );
|
||
|
if( hdc == NULL ) return( NULL );
|
||
|
PrinterSupport = PSUPP_CANPRINT;
|
||
|
|
||
|
/*
|
||
|
* look for ExtDeviceMode
|
||
|
*/
|
||
|
sprintf( str, DriverFormat, DriverName );
|
||
|
hlib = LoadLibrary( str );
|
||
|
if( (UINT)hlib >= 32 ) {
|
||
|
fp = GetProcAddress( hlib, "EXTDEVICEMODE" );
|
||
|
if( fp != NULL ) PrinterSupport = PSUPP_CANPRINTANDSET;
|
||
|
FreeLibrary( hlib );
|
||
|
}
|
||
|
return( hdc );
|
||
|
|
||
|
} /* PrinterDC */
|
||
|
|
||
|
#ifndef __WINDOWS_386__
|
||
|
typedef int (CALLBACK* EDMPROC)(HWND, HANDLE, LPDEVMODE, LPSTR, LPSTR, LPDEVMODE, LPSTR, WORD);
|
||
|
#endif
|
||
|
/*
|
||
|
* GetPrinterSetup - get data about this printer
|
||
|
*/
|
||
|
void GetPrinterSetup( HWND hwnd )
|
||
|
{
|
||
|
char str[128];
|
||
|
HINSTANCE hlib;
|
||
|
int edm_flag;
|
||
|
char _FAR *newdata;
|
||
|
char _FAR *olddata;
|
||
|
WORD bytes;
|
||
|
WORD rc;
|
||
|
#ifdef __WINDOWS_386__
|
||
|
HINDIR hindir;
|
||
|
#endif
|
||
|
FARPROC fp;
|
||
|
|
||
|
/*
|
||
|
* get ExtDeviceMode address
|
||
|
*/
|
||
|
sprintf( str, DriverFormat, DriverName );
|
||
|
hlib = LoadLibrary( str );
|
||
|
if( (UINT)hlib < 32 ) return;
|
||
|
fp = GetProcAddress( hlib, "EXTDEVICEMODE" );
|
||
|
if( fp == NULL ) {
|
||
|
FreeLibrary( hlib );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* get number of bytes
|
||
|
*/
|
||
|
#ifdef __WINDOWS_386__
|
||
|
hindir = GetIndirectFunctionHandle( fp,
|
||
|
INDIR_WORD, INDIR_WORD, INDIR_DWORD,
|
||
|
INDIR_PTR, INDIR_PTR, INDIR_DWORD,
|
||
|
INDIR_DWORD, INDIR_WORD, INDIR_ENDLIST );
|
||
|
bytes = (WORD) InvokeIndirectFunction( hindir, hwnd, hlib, NULL,
|
||
|
DeviceName, PortName, NULL, NULL, 0 );
|
||
|
MemFree( (void *) hindir );
|
||
|
#else
|
||
|
bytes = ((EDMPROC)fp)( hwnd, hlib, (LPDEVMODE) NULL, (LPSTR) DeviceName,
|
||
|
(LPSTR) PortName, (LPDEVMODE) NULL, (LPSTR) NULL, 0);
|
||
|
#endif
|
||
|
/*
|
||
|
* if we already have data, use that in the dialog
|
||
|
*/
|
||
|
newdata = MemAlloc( bytes );
|
||
|
edm_flag = DM_PROMPT | DM_COPY;
|
||
|
if( PrinterData != NULL ) edm_flag |= DM_MODIFY;
|
||
|
olddata = PrinterData;
|
||
|
|
||
|
/*
|
||
|
* now, get the new data from the dialog
|
||
|
*/
|
||
|
#ifdef __WINDOWS_386__
|
||
|
hindir = GetIndirectFunctionHandle( fp,
|
||
|
INDIR_WORD, INDIR_WORD, INDIR_PTR,
|
||
|
INDIR_PTR, INDIR_PTR, INDIR_PTR,
|
||
|
INDIR_DWORD, INDIR_WORD, INDIR_ENDLIST );
|
||
|
rc = InvokeIndirectFunction(
|
||
|
hindir,
|
||
|
hwnd,
|
||
|
hlib,
|
||
|
(LPDEVMODE) newdata,
|
||
|
(LPSTR) DeviceName,
|
||
|
(LPSTR) PortName,
|
||
|
(LPDEVMODE) olddata,
|
||
|
0L,
|
||
|
edm_flag );
|
||
|
MemFree( (void *) hindir );
|
||
|
#else
|
||
|
rc = ((EDMPROC)fp)( hwnd, hlib, (LPDEVMODE) newdata, (LPSTR) DeviceName,
|
||
|
(LPSTR) PortName, (LPDEVMODE) olddata,
|
||
|
(LPSTR) NULL, edm_flag );
|
||
|
#endif
|
||
|
|
||
|
FreeLibrary( hlib );
|
||
|
if( rc != IDOK ) {
|
||
|
MemFree( newdata );
|
||
|
} else {
|
||
|
MemFree( olddata );
|
||
|
PrinterData = newdata;
|
||
|
}
|
||
|
|
||
|
} /* GetPrinterSetup */
|
||
|
|
||
|
static volatile BOOL WasAborted;
|
||
|
static HWND DlgWnd;
|
||
|
|
||
|
/*
|
||
|
* Abort - procedure to abort a print job
|
||
|
*/
|
||
|
int _EXPORT FAR PASCAL Abort( HDC hdc, WORD w )
|
||
|
{
|
||
|
MSG msg;
|
||
|
|
||
|
w = w; /* shut up warning */
|
||
|
hdc = hdc;
|
||
|
|
||
|
while( !WasAborted && PeekMessage( &msg, 0, 0, 0, TRUE )) {
|
||
|
if( !IsDialogMessage( DlgWnd, &msg ) ) {
|
||
|
TranslateMessage( &msg );
|
||
|
DispatchMessage ( &msg );
|
||
|
}
|
||
|
}
|
||
|
return( !WasAborted );
|
||
|
|
||
|
} /* Abort */
|
||
|
|
||
|
/*
|
||
|
* AbortDialog - wait for the person to press cancel
|
||
|
*/
|
||
|
int _EXPORT FAR PASCAL AbortDialog( HWND hwnd, unsigned msg, UINT wparam,
|
||
|
LONG lparam )
|
||
|
{
|
||
|
lparam = lparam;
|
||
|
wparam = wparam;
|
||
|
|
||
|
switch(msg) {
|
||
|
case WM_COMMAND:
|
||
|
WasAborted = TRUE;
|
||
|
return( TRUE );
|
||
|
|
||
|
case WM_INITDIALOG:
|
||
|
SetDlgItemText( hwnd, PRINT_TITLE, (LPSTR) Title );
|
||
|
SetDlgItemText( hwnd, PRINT_REST, (LPSTR) Rest );
|
||
|
return( TRUE );
|
||
|
}
|
||
|
return( FALSE );
|
||
|
|
||
|
} /* AbortDialog */
|
||
|
|
||
|
|
||
|
/*
|
||
|
* CleanUp - clean up after print
|
||
|
*/
|
||
|
static BOOL CleanUp( HDC hdc, FARPROC abort, FARPROC abortdlg, BOOL err )
|
||
|
{
|
||
|
|
||
|
if( err ) Escape( hdc, ABORTDOC, 0, NULL, NULL );
|
||
|
if( DlgWnd != NULL ) DestroyWindow( DlgWnd );
|
||
|
DlgWnd = NULL;
|
||
|
if( hdc != NULL ) DeleteDC( hdc );
|
||
|
#ifndef __NT__
|
||
|
if( abortdlg != NULL ) FreeProcInstance( abortdlg );
|
||
|
if( abort != NULL ) FreeProcInstance( abort );
|
||
|
#else
|
||
|
abortdlg = abortdlg;
|
||
|
abort = abort;
|
||
|
#endif
|
||
|
/* Error? make sure the user knows... */
|
||
|
if( WasAborted ) {
|
||
|
MessageBox( NULL, Title, "Error printing file", MB_OK );
|
||
|
}
|
||
|
return( 0 );
|
||
|
|
||
|
} /* CleanUp */
|
||
|
|
||
|
/*
|
||
|
* Print - print current file
|
||
|
*/
|
||
|
BOOL Print( LPEDATA ed )
|
||
|
{
|
||
|
FARPROC abort;
|
||
|
FARPROC abortdlg;
|
||
|
HDC hdc;
|
||
|
WORD pageheight;
|
||
|
WORD lineheight;
|
||
|
WORD height;
|
||
|
LRESULT linecnt;
|
||
|
WORD currline;
|
||
|
UINT offset;
|
||
|
WORD len;
|
||
|
LOCALHANDLE hdata;
|
||
|
BOOL error;
|
||
|
char FAR *buff;
|
||
|
char _FAR *tmpbuff;
|
||
|
char rest[256];
|
||
|
SIZE sz;
|
||
|
|
||
|
/*
|
||
|
* init. misc.
|
||
|
*/
|
||
|
Title = ed->filename;
|
||
|
if( Title == NULL ) Title = (LPSTR) "untitled";
|
||
|
WasAborted = FALSE;
|
||
|
error = FALSE;
|
||
|
Rest = rest;
|
||
|
sprintf( Rest,"%s %s", PortName, DeviceName );
|
||
|
|
||
|
/*
|
||
|
* create procs
|
||
|
*/
|
||
|
abort = MakeProcInstance( (FARPROC)Abort, ed->inst );
|
||
|
if( abort == NULL ) return( 0 );
|
||
|
abortdlg = MakeProcInstance( (FARPROC)AbortDialog, ed->inst );
|
||
|
if( abortdlg == NULL ) return( CleanUp( NULL, abort, NULL, FALSE ) );
|
||
|
|
||
|
/*
|
||
|
* init. printer
|
||
|
*/
|
||
|
hdc = PrinterDC();
|
||
|
if( !hdc ) return( CleanUp( NULL, abort, abortdlg, FALSE ) );
|
||
|
|
||
|
/*
|
||
|
* Create abort dialog
|
||
|
*/
|
||
|
DlgWnd = CreateDialog( ed->inst, "AbortDialog", ed->hwnd, (DLGPROC)abortdlg );
|
||
|
if( DlgWnd == NULL ) return( CleanUp( hdc, abort, abortdlg, 0 ) );
|
||
|
ShowWindow( DlgWnd, SW_SHOW );
|
||
|
UpdateWindow( DlgWnd );
|
||
|
|
||
|
/*
|
||
|
* set up escape function
|
||
|
*/
|
||
|
if( Escape( hdc, SETABORTPROC, 0, (LPSTR) abort, NULL ) < 0 ) {
|
||
|
return( CleanUp( hdc, abort, abortdlg, FALSE ) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* start document
|
||
|
*/
|
||
|
if( Escape( hdc, STARTDOC, _strlen( Title ), (LPSTR) Title, NULL ) < 0 ) {
|
||
|
return( CleanUp( hdc, abort, abortdlg, FALSE ) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* get info
|
||
|
*/
|
||
|
pageheight = GetDeviceCaps( hdc, VERTRES );
|
||
|
GetTextExtentPoint( hdc, "CC", 2, &sz );
|
||
|
lineheight = sz.cy;
|
||
|
height = 0;
|
||
|
linecnt = SendMessage( ed->editwnd, EM_GETLINECOUNT, 0, 0L );
|
||
|
currline = 0;
|
||
|
hdata = (HANDLE)SendMessage( ed->editwnd, EM_GETHANDLE, 0, 0L );
|
||
|
|
||
|
/*
|
||
|
* print all lines
|
||
|
*/
|
||
|
while( currline < linecnt ) {
|
||
|
|
||
|
if( height + lineheight > pageheight ) {
|
||
|
height = 0;
|
||
|
if( Escape( hdc, NEWFRAME, 0, NULL, NULL ) < 0 ) error = TRUE;
|
||
|
}
|
||
|
if( WasAborted || error ) return( CleanUp( hdc, abort, abortdlg, TRUE ) );
|
||
|
|
||
|
/*
|
||
|
* get the data and print it
|
||
|
*/
|
||
|
offset = SendMessage( ed->editwnd, EM_LINEINDEX, currline, 0L );
|
||
|
len = SendMessage( ed->editwnd, EM_LINELENGTH, offset, 0L );
|
||
|
buff = MK_LOCAL32( LocalLock( hdata ) ) ;
|
||
|
tmpbuff = MemAlloc( len );
|
||
|
#ifndef __NT__
|
||
|
_fmemcpy( tmpbuff, buff + offset, len );
|
||
|
#else
|
||
|
memcpy( tmpbuff, buff + offset, len );
|
||
|
#endif
|
||
|
LocalUnlock( hdata );
|
||
|
|
||
|
TextOut( hdc, 0, height, (LPSTR)tmpbuff, len );
|
||
|
MemFree( tmpbuff );
|
||
|
|
||
|
currline++;
|
||
|
height += lineheight;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* eject final page, and tidy up
|
||
|
*/
|
||
|
if( Escape( hdc, NEWFRAME, 0, NULL, NULL) >= 0 ) {
|
||
|
if( Escape( hdc, ENDDOC, 0, NULL, NULL ) < 0 ) error = TRUE;
|
||
|
} else {
|
||
|
error = TRUE;
|
||
|
}
|
||
|
return( CleanUp( hdc, abort, abortdlg, error ) );
|
||
|
|
||
|
} /* Print */
|