home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
print
/
pmenv
/
pmenv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-03
|
18KB
|
615 lines
/*
* PMEnv
*
* OS/2 Presentation Manager Envelope Printing Program
* Version 1.1
*
* Dave Briccetti & Associates CompuServe: 74475,1072
* P.O. Box 1713
* Lafayette, CA 94549-7013
* USA
*
* Copyright (c) 1990, David C. Briccetti
* All rights reserved.
*
* See the extended help when running the program for more information.
*/
#include <io.h>
#include <malloc.h>
#include <process.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INCL_DEV
#define INCL_DOSPROCESS
#define INCL_GPILCIDS
#define INCL_GPIPRIMITIVES
#define INCL_WINBUTTONS
#define INCL_WINDIALOGS
#define INCL_WINERRORS
#define INCL_WINFRAMEMGR
#define INCL_WINHELP
#define INCL_WINMESSAGEMGR
#define INCL_WINMENUS
#define INCL_WINMLE
#define INCL_WINPOINTERS
#define INCL_WINRECTANGLES
#define INCL_WINSHELLDATA
#define INCL_WINSYS
#define INCL_WINWINDOWMGR
#include <os2.h>
#include "pmenv.h"
#include "help.h"
#include "dlgsup.h"
#include "printsup.h"
typedef struct _PRINTTHREADDATA /* ptdata */
{
HWND hwndDlg;
PBYTE pabBufAddr;
PBYTE pabBufRetAddr;
SHORT PrinterType;
SHORT MarginTop;
SHORT MarginLeft;
}
PRINTTHREADDATA;
typedef PRINTTHREADDATA *PPRINTTHREADDATA;
#define MLE_BUFSIZE 2000
#define WMUSER_PRINTFINISHED WM_USER + 0
#define WMUSER_INITFROMPROFILE WM_USER + 1
#define DEFAULT_PRINTERTYPE 0
#define DEFAULT_MARGINTOP 5
#define DEFAULT_MARGINLEFT 5
static HAB hab;
static HWND hwndHelpInstance;
static MRESULT EXPENTRY
DlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
static VOID EnableMarginControls (HWND hwnd, BOOL fEnable);
static VOID UpdatePrintMsg (HWND hwnd, USHORT cPrintThreadsRunning);
static VOID LaunchPrintThread (HWND hwnd, PBYTE pabBufAddr,
PBYTE pabBufRetAddr, PUSHORT pcPrintThreadsRunning,
SHORT PrinterType, SHORT MarginTop, SHORT MarginLeft);
static VOID PrintEnvelopeThread (PPRINTTHREADDATA pptdata);
/* ----------------------------------------------------------------- */
VOID main (VOID)
{
HMQ hmq;
QMSG qmsg;
HWND hwndDlg;
hab = WinInitialize (0);
hmq = WinCreateMsgQueue (hab, DEFAULT_QUEUE_SIZE);
hwndDlg = WinLoadDlg (HWND_DESKTOP, HWND_DESKTOP,
DlgProc, 0, DID_DLG, 0);
hwndHelpInstance = InitializeHelp (hab, hwndDlg, DID_DLG,
"PMENV.HLP", "Print Envelope Help Window");
while (WinGetMsg (hab, &qmsg, 0, 0, 0))
WinDispatchMsg (hab, &qmsg);
if (hwndHelpInstance)
WinDestroyHelpInstance (hwndHelpInstance);
WinDestroyMsgQueue (hmq);
WinTerminate (hab);
}
/* ----------------------------------------------------------------- */
static MRESULT EXPENTRY
DlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
static PBYTE pabBufAddr; /* Address buffer */
static PBYTE pabBufRetAddr; /* Return address buffer */
ULONG cbData; /* Data length */
static HWND hwndSysMenu; /* Sys menu pull-down handle */
static USHORT cPrintThreadsRunning; /* Number of print threads */
static SHORT PrinterType; /* Printer type */
static SHORT MarginTop; /* Top margin */
static SHORT MarginLeft; /* Left margin */
switch (msg)
{
case WM_INITDLG:
{
HWND hwndStamp; /* Stamp window handle */
RECTL rclStamp; /* Stamp size */
SWP swpEnvelope; /* Envelope position and size */
MENUITEM miTemp; /* Menu item template */
cPrintThreadsRunning = 0;
/* Make cosmetic changes to dialog box */
CenterDlgBox (hwnd);
SetSystemMenu (hwnd);
/* Get system menu pull-down handle */
hwndSysMenu = WinWindowFromID (hwnd, FID_SYSMENU );
WinSendMsg( hwndSysMenu, MM_QUERYITEM,
MPFROM2SHORT( SC_SYSMENU, FALSE ),
MPFROMP( (PSZ)&miTemp ));
hwndSysMenu = miTemp.hwndSubMenu;
/* Place stamp in upper right corner of envelope */
WinQueryWindowRect (hwndStamp = WinWindowFromID
(hwnd, DID_STAMP), &rclStamp);
WinQueryWindowPos (WinWindowFromID
(hwnd, DID_ENVELOPE), &swpEnvelope);
WinSetWindowPos (hwndStamp, 0,
(SHORT) (swpEnvelope.x +
swpEnvelope.cx - (rclStamp.xRight * 11 / 10)),
(SHORT) (swpEnvelope.y +
swpEnvelope.cy - (rclStamp.yTop * 11 / 10)),
0, 0, SWP_MOVE);
/* Allocate MLE buffers */
pabBufAddr = halloc (MLE_BUFSIZE, 1);
pabBufRetAddr = halloc (MLE_BUFSIZE, 1);
WinSendDlgItemMsg (hwnd, DID_ADDR, MLM_SETTEXTLIMIT,
MPFROMLONG ((LONG) MLE_BUFSIZE - 1), 0);
WinSendDlgItemMsg (hwnd, DID_RETURN_ADDR, MLM_SETTEXTLIMIT,
MPFROMLONG ((LONG) MLE_BUFSIZE - 1), 0);
/* Initialize controls from user profile */
WinSendMsg (hwnd, WMUSER_INITFROMPROFILE, 0, 0);
return 0;
}
case WMUSER_INITFROMPROFILE:
/* Retrieve saved data from user profile */
cbData = MLE_BUFSIZE - 2;
pabBufAddr [0] = 0;
pabBufAddr [cbData] = 0;
PrfQueryProfileData (HINI_USERPROFILE,
"PMHPENV", "Address", pabBufAddr, &cbData);
WinSetDlgItemText (hwnd, DID_ADDR, pabBufAddr);
cbData = MLE_BUFSIZE - 2;
pabBufRetAddr [0] = 0;
pabBufRetAddr [cbData] = 0;
PrfQueryProfileData (HINI_USERPROFILE, "PMHPENV",
"ReturnAddress", pabBufRetAddr, &cbData);
WinSetDlgItemText (hwnd,
DID_RETURN_ADDR, pabBufRetAddr);
PrinterType = DEFAULT_PRINTERTYPE;
cbData = sizeof (SHORT);
PrfQueryProfileData (HINI_USERPROFILE,
"PMHPENV", "PrinterType", &PrinterType, &cbData);
WinSendDlgItemMsg (hwnd, PrinterType ?
DID_PRINTER_HP : DID_PRINTER_GENERIC,
BM_SETCHECK, MPFROMSHORT (1), 0);
EnableMarginControls (hwnd, ! PrinterType);
MarginTop = DEFAULT_MARGINTOP;
cbData = sizeof (SHORT);
PrfQueryProfileData (HINI_USERPROFILE,
"PMHPENV", "MarginTop", &MarginTop, &cbData);
WinSetDlgItemShort (hwnd, DID_MARGIN_TOP,
MarginTop, TRUE);
MarginLeft = DEFAULT_MARGINLEFT;
cbData = sizeof (SHORT);
PrfQueryProfileData (HINI_USERPROFILE,
"PMHPENV", "MarginLeft", &MarginLeft, &cbData);
WinSetDlgItemShort (hwnd, DID_MARGIN_LEFT,
MarginLeft, TRUE);
break;
case WM_COMMAND:
switch (SHORT1FROMMP (mp1))
{
case DID_SAVE:
/* Save address in profile */
WinQueryDlgItemText (hwnd, DID_ADDR, MLE_BUFSIZE,
pabBufAddr);
PrfWriteProfileData (HINI_USERPROFILE,
"PMHPENV", "Address", pabBufAddr,
(ULONG) strlen (pabBufAddr));
/* Save return address in profile */
WinQueryDlgItemText (hwnd, DID_RETURN_ADDR,
MLE_BUFSIZE, pabBufRetAddr);
PrfWriteProfileData (HINI_USERPROFILE, "PMHPENV",
"ReturnAddress", pabBufRetAddr,
(ULONG) strlen (pabBufRetAddr));
/* Save printer and margin info in profile */
PrinterType = SHORT1FROMMR (WinSendDlgItemMsg
(hwnd, DID_PRINTER_HP,
BM_QUERYCHECK, 0, 0));
WinQueryDlgItemShort (hwnd, DID_MARGIN_TOP,
&MarginTop, TRUE);
WinQueryDlgItemShort (hwnd, DID_MARGIN_LEFT,
&MarginLeft, TRUE);
cbData = sizeof (SHORT);
PrfWriteProfileData (HINI_USERPROFILE,
"PMHPENV", "PrinterType", &PrinterType, cbData);
PrfWriteProfileData (HINI_USERPROFILE,
"PMHPENV", "MarginTop", &MarginTop, cbData);
PrfWriteProfileData (HINI_USERPROFILE,
"PMHPENV", "MarginLeft", &MarginLeft, cbData);
break;
case DID_DEFAULTS:
PrfWriteProfileData (HINI_USERPROFILE,
"PMHPENV", 0, 0, 0);
WinSendMsg (hwnd, WMUSER_INITFROMPROFILE, 0, 0);
break;
case DID_PRINT:
PrinterType = SHORT1FROMMR (WinSendDlgItemMsg
(hwnd, DID_PRINTER_HP,
BM_QUERYCHECK, 0, 0));
WinQueryDlgItemShort (hwnd, DID_MARGIN_TOP,
&MarginTop, TRUE);
WinQueryDlgItemShort (hwnd, DID_MARGIN_LEFT,
&MarginLeft, TRUE);
LaunchPrintThread (hwnd, pabBufAddr,
pabBufRetAddr, &cPrintThreadsRunning,
PrinterType, MarginTop, MarginLeft);
break;
case DID_CANCEL:
WinPostMsg (hwnd, WM_CLOSE, 0L, 0L);
break;
}
break;
case WM_CONTROL:
switch (SHORT2FROMMP (mp1))
{
case BN_CLICKED:
switch (SHORT1FROMMP (mp1))
{
case DID_PRINTER_HP:
EnableMarginControls (hwnd, FALSE);
break;
case DID_PRINTER_GENERIC:
EnableMarginControls (hwnd, TRUE);
break;
}
break;
}
break;
case WM_CLOSE:
{
BOOL fClose;
if (cPrintThreadsRunning)
fClose = WinMessageBox (HWND_DESKTOP, hwnd,
"Printing is under way. Do you want to "
"exit anyway?", "Printing Under Way", 1,
MB_YESNO | MB_ICONQUESTION | MB_MOVEABLE)
== MBID_YES;
else
fClose = TRUE;
if (fClose)
{
WinPostMsg (0, WM_QUIT, 0L, 0L);
WinDestroyWindow (hwnd);
hfree (pabBufAddr);
hfree (pabBufRetAddr);
}
break;
}
case HM_ERROR:
return ProcessHmMessages (hwndHelpInstance,
msg, mp1, mp2);
case WMUSER_PRINTFINISHED:
UpdatePrintMsg (hwnd, --cPrintThreadsRunning);
break;
default:
return WinDefDlgProc (hwnd, msg, mp1, mp2);
}
return (MRESULT) 0;
}
/* ----------------------------------------------------------------- */
static VOID EnableMarginControls (HWND hwnd, BOOL fEnable)
{
/*
* Enable or disable margin setting controls. They are not
* used when commanding an HP LaserJet.
*/
WinEnableWindow (WinWindowFromID
(hwnd, DID_MARGIN_TOP), fEnable);
WinEnableWindow (WinWindowFromID
(hwnd, DID_MARGIN_LEFT), fEnable);
WinEnableWindow (WinWindowFromID
(hwnd, DID_MARGIN_TOP_LBL), fEnable);
WinEnableWindow (WinWindowFromID
(hwnd, DID_MARGIN_LEFT_LBL), fEnable);
WinEnableWindow (WinWindowFromID
(hwnd, DID_MARGIN_LBL), fEnable);
}
/* ----------------------------------------------------------------- */
static VOID LaunchPrintThread (HWND hwnd, PBYTE pabBufAddr,
PBYTE pabBufRetAddr, PUSHORT pcPrintThreadsRunning,
SHORT PrinterType, SHORT MarginTop, SHORT MarginLeft)
{
/*
* Create a thread to queue an envelope for printing.
*/
PPRINTTHREADDATA pptdata;
WinEnableWindow (WinWindowFromID (hwnd, DID_PRINT), FALSE);
WinSetPointer (HWND_DESKTOP,
WinQuerySysPointer (HWND_DESKTOP,
SPTR_WAIT, 0));
/* Get address data */
WinQueryDlgItemText (hwnd, DID_ADDR,
MLE_BUFSIZE, pabBufAddr);
WinQueryDlgItemText (hwnd, DID_RETURN_ADDR,
MLE_BUFSIZE, pabBufRetAddr);
pptdata = halloc (1L, sizeof *pptdata);
pptdata->hwndDlg = hwnd;
pptdata->pabBufAddr = strdup (pabBufAddr);
pptdata->pabBufRetAddr = strdup (pabBufRetAddr);
pptdata->PrinterType = PrinterType;
pptdata->MarginTop = MarginTop;
pptdata->MarginLeft = MarginLeft;
/* Launch the thread */
if (_beginthread (PrintEnvelopeThread,
0, 8192, pptdata) == -1)
WinMessageBox (HWND_DESKTOP, hwnd,
"Print Envelopes can not create "
"Print Thread", "Print Envelopes Error",
1, MB_MOVEABLE | MB_OK | MB_ICONASTERISK);
else
UpdatePrintMsg (hwnd, ++*pcPrintThreadsRunning);
WinSetPointer (HWND_DESKTOP,
WinQuerySysPointer (HWND_DESKTOP, SPTR_ARROW, 0));
WinEnableWindow (WinWindowFromID (hwnd, DID_PRINT), TRUE);
}
/* ----------------------------------------------------------------- */
static VOID UpdatePrintMsg (HWND hwnd, USHORT cPrintThreadsRunning)
{
/*
* Update the print status message which indicates how many
* print threads are running.
*/
CHAR szMsg [40];
if (cPrintThreadsRunning)
sprintf (szMsg, "Envelopes printing: %u",
cPrintThreadsRunning);
else
*szMsg = 0;
WinSetDlgItemText (hwnd, DID_PRINT_MSG, szMsg);
}
/* ----------------------------------------------------------------- */
static VOID PrintEnvelopeThread (PPRINTTHREADDATA pptdata)
{
/*
* Queue an envelope for printing.
*/
HDC hdcPrint;
USHORT usJobId;
CHAR szPrintTitle [100];
PBYTE pchCR;
HAB habPrint;
HMQ hmqPrint;
SIZEL sizl;
HPS hpsPrint;
POINTL ptl;
LONG cyPage;
LONG cxPage;
FONTMETRICS fm;
habPrint = WinInitialize (0);
hmqPrint = WinCreateMsgQueue (habPrint, DEFAULT_QUEUE_SIZE);
/* Set priority lower than main thread */
DosSetPrty (PRTYS_THREAD, PRTYC_NOCHANGE, -1, 0);
/* Make print spooler document title from envelope address */
if ((pchCR = strchr (pptdata->pabBufAddr, '\r')) != 0)
{
USHORT cbFirstLine;
USHORT cbTitlePart1;
USHORT cbMaxConcat;
memset (szPrintTitle, 0xff, sizeof szPrintTitle);
strcpy (szPrintTitle, "Env. - ");
cbTitlePart1 = strlen (szPrintTitle);
cbFirstLine = pchCR - pptdata->pabBufAddr;
cbMaxConcat = min (cbFirstLine,
sizeof szPrintTitle - cbTitlePart1 - 1);
strncat (szPrintTitle, pptdata->pabBufAddr, cbMaxConcat);
}
else
strcpy (szPrintTitle, "Envelope");
/* Perform document initialization */
OpenDefaultPrinterDC (hab, &hdcPrint,
pptdata->PrinterType ? "PM_Q_RAW" : "PM_Q_STD");
DevQueryCaps (hdcPrint, CAPS_HEIGHT, 1L, &cyPage);
DevQueryCaps (hdcPrint, CAPS_WIDTH, 1L, &cxPage);
DevEscape (hdcPrint, DEVESC_STARTDOC,
(LONG) strlen (szPrintTitle), szPrintTitle, 0L, 0);
if (pptdata->PrinterType) /* HP Printer - dump raw data */
{
/* Print return address */
PrintString( hdcPrint,
"\x01b" "E\x1b&l1O\x1b&l3H\x1b&l15E" );
PrintString( hdcPrint, "\x1b&a1r&a15L" );
PrintString( hdcPrint, pptdata->pabBufRetAddr );
/* Print address */
PrintString( hdcPrint, "\x1b&a11R" ); /* Line position */
PrintString( hdcPrint, "\x1b&a58L" ); /* Column position */
PrintString( hdcPrint, pptdata->pabBufAddr );
PrintString( hdcPrint, "\f\x01b" "E" );
}
else /* Generic Printer - use GPI */
{
sizl.cx = sizl.cy = 0L;
hpsPrint = GpiCreatePS( habPrint, hdcPrint, &sizl,
PU_PELS | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC );
GpiQueryFontMetrics (hpsPrint, sizeof fm, &fm);
ptl.x = pptdata->MarginLeft * fm.lAveCharWidth;
ptl.y = cyPage - pptdata->MarginTop * fm.lMaxBaselineExt;
PrintLinesAt (hpsPrint, ptl,
pptdata->pabBufRetAddr, fm.lMaxBaselineExt);
ptl.x = cxPage / 2;
ptl.y = cyPage - (pptdata->MarginTop + 10)
* fm.lMaxBaselineExt;
PrintLinesAt (hpsPrint, ptl,
pptdata->pabBufAddr, fm.lMaxBaselineExt);
GpiAssociate( hpsPrint, 0 );
GpiDestroyPS( hpsPrint );
}
/* Perform document and thread termination */
DevEscape (hdcPrint, DEVESC_ENDDOC, 0L, 0, 0L,
(PBYTE) &usJobId);
DevCloseDC (hdcPrint);
WinDestroyMsgQueue (hmqPrint);
WinTerminate (habPrint);
/* Notify main thread that this thread is done */
WinPostMsg (pptdata->hwndDlg, WMUSER_PRINTFINISHED, 0, 0);
/* Free per-thread-instance address buffers */
free (pptdata->pabBufAddr);
free (pptdata->pabBufRetAddr);
/* Free other per-thread-instance data */
hfree (pptdata);
}