Category : Files from Magazines
Archive   : VOL9N08.ZIP
Filename : PRINTCAL.C

 
Output of file : PRINTCAL.C contained in archive : VOL9N08.ZIP
/*---------------------------------------------------------------------
PRINTCAL.C -- OS/2 Presentation Manager program to print a calendar
(c) 1990, Ziff Communications Co.
PC Magazine * Charles Petzold, 10/89
---------------------------------------------------------------------*/

#define INCL_WIN
#define INCL_GPI
#define INCL_DEV
#define INCL_DOSPROCESS
#include
#include
#include
#include
#include
#include "printcal.h"

#define LCID_CALFONT 1L
#define STACKSIZE (4096 * sizeof (int))
#define WM_USER_PRINT_OK (WM_USER + 0)
#define WM_USER_PRINT_ERROR (WM_USER + 1)

typedef struct
{
SHORT sYear, sMonthBeg, sMonthEnd ;
}
CALPARAMS ;

typedef struct
{
int aiThreadStack[STACKSIZE / sizeof (int)] ;
CALPARAMS cp ;
HWND hwndNotify ;
}
THREADPARAMS ;

MPARAM EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
MPARAM EXPENTRY AboutDlgProc (HWND, USHORT, MPARAM, MPARAM) ;
MPARAM EXPENTRY PrintDlgProc (HWND, USHORT, MPARAM, MPARAM) ;
VOID DisplayPage (HPS, SIZEL *, SHORT, SHORT) ;
VOID Message (HWND, SHORT, CHAR *) ;
VOID FAR PrintThread (THREADPARAMS *) ;
HDC OpenDefaultPrinterDC (HAB) ; // in PRINTDC.C

HAB hab ;
USHORT usActiveThreads = 0 ;

int main (void)
{
static CHAR szClientClass[] = "PrintCal" ;
static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
FCF_SIZEBORDER | FCF_MINMAX |
FCF_MENU |
FCF_SHELLPOSITION | FCF_TASKLIST ;
HMQ hmq ;
HWND hwndFrame, hwndClient ;
QMSG qmsg ;

hab = WinInitialize (0) ;
hmq = WinCreateMsgQueue (hab, 0) ;
WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;

hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
&flFrameFlags, szClientClass, NULL,
0L, NULL, ID_RESOURCE, &hwndClient) ;
while (TRUE)
{
while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
WinDispatchMsg (hab, &qmsg) ;

if (usActiveThreads == 0)
break ;

Message (hwndClient, MB_ICONEXCLAMATION,
"Printing thread still active.\n"
"Program cannot be closed now.") ;

WinCancelShutdown (hmq, FALSE) ;
}

WinDestroyWindow (hwndFrame) ;
WinDestroyMsgQueue (hmq) ;
WinTerminate (hab) ;
return 0 ;
}

MPARAM EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
static CALPARAMS cp ;
static HPS hps ;
static SIZEL sizlClient ;
DATETIME dt ;
HDC hdc ;
SHORT sResult ;

SIZEL sizlPage ;
THREADPARAMS *ptp ;

switch (msg)
{
case WM_CREATE:
hdc = WinOpenWindowDC (hwnd) ;
sizlPage.cx = 0 ;
sizlPage.cy = 0 ;
hps = GpiCreatePS (hab, hdc, &sizlPage,
PU_ARBITRARY | GPIF_DEFAULT |
GPIT_MICRO | GPIA_ASSOC) ;

DosGetDateTime (&dt) ;
cp.sYear = dt.year ;
cp.sMonthBeg = dt.month - 1 ;
cp.sMonthEnd = dt.month - 1 ;
return 0 ;

case WM_SIZE:
sizlClient.cx = SHORT1FROMMP (mp2) ;
sizlClient.cy = SHORT2FROMMP (mp2) ;

GpiConvert (hps, CVTC_DEVICE, CVTC_PAGE, 1L,
(PPOINTL) &sizlClient) ;
return 0 ;

case WM_PAINT:
WinBeginPaint (hwnd, hps, NULL) ;

GpiErase (hps) ;
DisplayPage (hps, &sizlClient, cp.sYear, cp.sMonthBeg) ;

WinEndPaint (hps) ;
return 0 ;

case WM_COMMAND:
switch (COMMANDMSG(&msg)->cmd)
{
case IDM_ABOUT:
WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc,
NULL, IDD_ABOUT, NULL) ;
return 0 ;

case IDM_PRINT:
sResult = WinDlgBox (HWND_DESKTOP, hwnd, PrintDlgProc,
NULL, IDD_PRINT, &cp) ;

if (sResult == DID_CANCEL)
return 0 ;

WinInvalidateRect (hwnd, NULL, FALSE) ;

if (sResult == IDD_PREVIEW)
return 0 ;

if ((ptp = malloc (sizeof (THREADPARAMS))) == NULL)
{
Message (hwnd, MB_ICONEXCLAMATION,
"Cannot allocate memory for print thread!") ;
return 0 ;
}

ptp->cp = cp ;
ptp->hwndNotify = hwnd ;

if (_beginthread (PrintThread, ptp->aiThreadStack,
STACKSIZE, ptp) == -1)
{
free (ptp) ;
Message (hwnd, MB_ICONEXCLAMATION,
"Cannot create print thread!") ;
return 0 ;
}

usActiveThreads++ ;
Message (hwnd, MB_ICONASTERISK,
"Print job successfully started.") ;
return 0 ;
}
break ;

case WM_USER_PRINT_OK:
ptp = PVOIDFROMMP (mp1) ;
free (ptp) ;
usActiveThreads-- ;
Message (hwnd, MB_ICONASTERISK,
"Print job sent to spooler.") ;
return 0 ;

case WM_USER_PRINT_ERROR:
ptp = PVOIDFROMMP (mp1) ;
free (ptp) ;
usActiveThreads-- ;
Message (hwnd, MB_ICONEXCLAMATION,
"Error encountered during printing.") ;
return 0 ;

case WM_DESTROY:
GpiDestroyPS (hps) ;
return 0 ;
}
return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
}

MRESULT EXPENTRY AboutDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
switch (msg)
{
case WM_COMMAND:
switch (COMMANDMSG(&msg)->cmd)
{
case DID_OK:
case DID_CANCEL:
WinDismissDlg (hwnd, TRUE) ;
return 0 ;
}
break ;
}
return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
}

MRESULT EXPENTRY PrintDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
static CALPARAMS cpLocal, *pcpCurrent ;

switch (msg)
{
case WM_INITDLG:
pcpCurrent = PVOIDFROMMP (mp2) ;
cpLocal = *pcpCurrent ;

WinSendDlgItemMsg (hwnd, IDD_MONTHBEG + cpLocal.sMonthBeg,
BM_SETCHECK, MPFROM2SHORT (TRUE, 0), NULL) ;

WinSendDlgItemMsg (hwnd, IDD_MONTHEND + cpLocal.sMonthEnd,
BM_SETCHECK, MPFROM2SHORT (TRUE, 0), NULL) ;

WinSendDlgItemMsg (hwnd, IDD_YEAR, EM_SETTEXTLIMIT,
MPFROM2SHORT (4, 0), NULL) ;

WinSetDlgItemShort (hwnd, IDD_YEAR, cpLocal.sYear, FALSE) ;
return 0 ;

case WM_CONTROL:
if (SHORT1FROMMP (mp1) >= IDD_MONTHBEG &&
SHORT1FROMMP (mp1) < IDD_MONTHBEG + 12)

cpLocal.sMonthBeg = SHORT1FROMMP (mp1) - IDD_MONTHBEG ;

else if (SHORT1FROMMP (mp1) >= IDD_MONTHEND &&
SHORT1FROMMP (mp1) < IDD_MONTHEND + 12)

cpLocal.sMonthEnd = SHORT1FROMMP (mp1) - IDD_MONTHEND ;

return 0 ;

case WM_COMMAND:
switch (COMMANDMSG(&msg)->cmd)
{
case DID_OK:
case IDD_PREVIEW:
WinQueryDlgItemShort (hwnd, IDD_YEAR,
&cpLocal.sYear, FALSE) ;

if (cpLocal.sYear < 1900 || cpLocal.sYear > 2099)
{
Message (hwnd, MB_ICONEXCLAMATION,
"Year must be between 1900 and 2099!") ;
WinSetFocus (HWND_DESKTOP,
WinWindowFromID (hwnd, IDD_YEAR)) ;
return 0 ;
}

if (cpLocal.sMonthBeg > cpLocal.sMonthEnd)
{
Message (hwnd, MB_ICONEXCLAMATION,
"Begin month cannot be later "
"than end month!") ;
WinSetFocus (HWND_DESKTOP,
WinWindowFromID (hwnd,
IDD_MONTHBEG + cpLocal.sMonthBeg)) ;
return 0 ;
}

*pcpCurrent = cpLocal ;
// fall through
case DID_CANCEL:
WinDismissDlg (hwnd, COMMANDMSG(&msg)->cmd) ;
return 0 ;
}
break ;
}
return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
}

VOID DisplayPage (HPS hps, SIZEL *psizlPage, SHORT sYear, SHORT sMonth)
{
static CHAR *apszMonths[] = { "January", "February", "March",
"April", "May", "June",
"July", "August", "September",
"October", "November", "December" } ;
static SHORT asMonthLen[] = { 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 } ;
static SHORT asMonthStart[] = { 0, 3, 3, 6, 1, 4,
6, 2, 5, 0, 3, 5 } ;
CHAR szBuffer[16] ;
BOOL fLeap ;
FATTRS fat ;
LONG lLength ;
POINTL ptl, aptlTextBox[TXTBOX_COUNT] ;
SHORT sDayStart, sDay, sExtraDay ;
SIZEF sizfx ;
SIZEL sizlCell ;

GpiSavePS (hps) ;

// Determine size of day cell

sizlCell.cx = (psizlPage->cx - 1) / 7 ;
sizlCell.cy = (psizlPage->cy - 1) / 7 ;

// Create the vector font and use it in the PS

fat.usRecordLength = sizeof fat ;
fat.fsSelection = 0 ;
fat.lMatch = 0 ;
fat.idRegistry = 0 ;
fat.usCodePage = GpiQueryCp (hps) ;
fat.lMaxBaselineExt = 0 ;
fat.lAveCharWidth = 0 ;
fat.fsType = 0 ;
fat.fsFontUse = FATTR_FONTUSE_OUTLINE |
FATTR_FONTUSE_TRANSFORMABLE ;

strcpy (fat.szFacename, "Helv") ;

GpiCreateLogFont (hps, NULL, LCID_CALFONT, &fat) ;
GpiSetCharSet (hps, LCID_CALFONT) ;

// Scale the font for the month and year name

lLength = sprintf (szBuffer, " %s %d ", apszMonths[sMonth], sYear) ;
GpiQueryTextBox (hps, lLength, szBuffer, TXTBOX_COUNT, aptlTextBox) ;
GpiQueryCharBox (hps, &sizfx) ;

sizfx.cx = sizlCell.cx * sizfx.cx / aptlTextBox[TXTBOX_CONCAT].x * 7 ;
sizfx.cy = sizlCell.cy * sizfx.cy / (aptlTextBox[TXTBOX_TOPLEFT].y -
aptlTextBox[TXTBOX_BOTTOMLEFT].y) ;

sizfx.cx = sizfx.cy = min (sizfx.cx, sizfx.cy) ;
GpiSetCharBox (hps, &sizfx) ;
GpiQueryTextBox (hps, lLength, szBuffer, TXTBOX_COUNT, aptlTextBox) ;

// Display month and year at top of page

ptl.x = (psizlPage->cx - aptlTextBox[TXTBOX_CONCAT].x) / 2 ;
ptl.y = 6 * sizlCell.cy - aptlTextBox[TXTBOX_BOTTOMLEFT].y ;
GpiCharStringAt (hps, &ptl, lLength, szBuffer) ;

// Set font size for day numbers

sizfx.cx = sizfx.cy = MAKEFIXED (min (sizlCell.cx, sizlCell.cy) / 4, 0) ;
GpiSetCharBox (hps, &sizfx) ;

// Calculate some variables for showing days in month

fLeap = (sYear % 4 == 0) && ((sYear % 100 != 0) || (sYear % 400 == 0)) ;
sExtraDay = fLeap && sMonth == 1 ? 1 : 0 ;

sDayStart = 1 + sYear - 1900 + (sYear - 1901) / 4 ;
sDayStart += asMonthStart[sMonth] + (fLeap && sMonth > 1 ? 1 : 0) ;
sDayStart %= 7 ;

// Loop through days

for (sDay = 0 ; sDay < asMonthLen[sMonth] + sExtraDay ; sDay++)
{
ptl.x = (sDayStart + sDay) % 7 * sizlCell.cx ;
ptl.y = (5 - (sDayStart + sDay) / 7) * sizlCell.cy ;
GpiMove (hps, &ptl) ;

ptl.x += sizlCell.cx ;
ptl.y += sizlCell.cy ;
GpiBox (hps, DRO_OUTLINE, &ptl, 0L, 0L) ;

lLength = sprintf (szBuffer, " %d", sDay + 1) ;
GpiQueryTextBox (hps, lLength, szBuffer, TXTBOX_COUNT, aptlTextBox) ;

GpiQueryCurrentPosition (hps, &ptl) ;
ptl.y += sizlCell.cy - aptlTextBox[TXTBOX_TOPLEFT].y ;
GpiCharStringAt (hps, &ptl, lLength, szBuffer) ;
}
// Clean up

GpiSetCharSet (hps, LCID_DEFAULT) ;
GpiDeleteSetId (hps, LCID_CALFONT) ;
GpiRestorePS (hps, -1L) ;
}

VOID Message (HWND hwnd, SHORT sIcon, CHAR *pszMessage)
{
WinMessageBox (HWND_DESKTOP, hwnd, pszMessage, "PrintCal",
0, sIcon | MB_OK | MB_MOVEABLE) ;
}

VOID FAR PrintThread (THREADPARAMS *ptp)
{
HAB hab ;
HDC hdcPrinter ;
HPS hpsPrinter ;
SHORT msgReturn ;
SHORT sMonth ;
SIZEL sizlPage ;

hab = WinInitialize (0) ;

if ((hdcPrinter = OpenDefaultPrinterDC (hab)) != DEV_ERROR)
{
// Create the presentation space for the printer

sizlPage.cx = 0 ;
sizlPage.cy = 0 ;
hpsPrinter = GpiCreatePS (hab, hdcPrinter, &sizlPage,
PU_ARBITRARY | GPIF_DEFAULT |
GPIT_MICRO | GPIA_ASSOC) ;

GpiQueryPS (hpsPrinter, &sizlPage) ;

// Start the document

if (DevEscape (hdcPrinter, DEVESC_STARTDOC,
8L, "Calendar", NULL, NULL) != DEVESC_ERROR)
{
// Loop through months

for (sMonth = ptp->cp.sMonthBeg ;
sMonth <= ptp->cp.sMonthEnd ; sMonth++)
{
DisplayPage (hpsPrinter, &sizlPage, ptp->cp.sYear, sMonth);

DevEscape (hdcPrinter, DEVESC_NEWFRAME,
0L, NULL, NULL, NULL) ;
}
// End the document

DevEscape (hdcPrinter, DEVESC_ENDDOC, 0L, NULL, NULL, NULL) ;
msgReturn = WM_USER_PRINT_OK ;
}
else
msgReturn = WM_USER_PRINT_ERROR ;

// Clean up

GpiDestroyPS (hpsPrinter) ;
DevCloseDC (hdcPrinter) ;
}
else
msgReturn = WM_USER_PRINT_ERROR ;

// Post message to client window and end thread

DosEnterCritSec () ;
WinPostMsg (ptp->hwndNotify, msgReturn, MPFROMP (ptp), NULL) ;
WinTerminate (hab) ;
_endthread () ;
}


  3 Responses to “Category : Files from Magazines
Archive   : VOL9N08.ZIP
Filename : PRINTCAL.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/