[Migrated content. Thread originally posted on 08 February 2011]
In some cases, it might be nice to have a watermark on a report. Something like "Confidential" perhaps?With some help from the Windows API, this can be accomplished. The following example even show you how to print at an angle using COBOL Extend and functions from the Windows API.
Note that this program has been coded for portrait, A4 papersize, printing to default printer.
No compiler switches required, except perhaps -Sp if you do not have the default copybooks in the same directory.
IDENTIFICATION DIVISION.
PROGRAM-ID. PrintWithWatermark.
* Copyright (c) 1996-2010 by Micro Focus. Users of ACUCOBOL-GT
* may freely modify and redistribute this program.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
FILE-CONTROL.
SELECT MatrixReport ASSIGN TO PRINTER "-P SPOOLER"
ORGANIZATION IS LINE SEQUENTIAL.
FILE SECTION.
FD MatrixReport.
01 MatrixRecord PIC X(132).
WORKING-STORAGE SECTION.
COPY "FONTS.DEF".
COPY "WINPRINT.DEF".
*When the runtime start a print job on Windows, it is given a handle to
*the print's Device Context (DC), this handle is provided as an external
*item, in the event the programmer should need it, like in this case.
77 H-ACU-SPOOLER-DC pic 9(9) COMP-5 EXTERNAL.
77 ANGLE PIC X(4) COMP-N.
77 WATERMARK-COLOR PIC X(4) COMP-N.
77 RESTORE-COLOR PIC X(4) COMP-N.
77 WATERMARK-FONT USAGE HANDLE OF FONT.
77 REGULAR-FONT USAGE HANDLE OF FONT.
77 RGB-RED PIC 9(03).
77 RGB-GREEN PIC 9(03).
77 RGB-BLUE PIC 9(03).
77 LinesWritten PIC 9(3).
77 PageCount PIC 9(3).
77 StoreXPos PIC 9(05).
77 StoreYPos PIC 9(05).
01 SYSTEM-INFORMATION.
03 OPERATING-SYSTEM PIC X(10).
88 OS-IS-MSDOS VALUE "MS-DOS".
88 OS-IS-OS2 VALUE "OS/2".
88 OS-IS-VMS VALUES "VMS",
"VAX/VMS".
88 OS-IS-UNIX VALUES "Unix",
"Unix-V", "Unix-4",
"UNOS".
88 OS-IS-AOS VALUE "AOS/VS".
88 OS-IS-WINDOWS VALUE "WINDOWS".
88 OS-IS-WIN-NT VALUE "WIN/NT".
88 OS-IS-WIN-FAMILY VALUES "WINDOWS",
"WIN/NT".
88 OS-IS-AMOS VALUE "AMOS".
88 OS-IS-MPE VALUE "MPE/iX".
88 OS-IS-MPEIX VALUE "MPE/iX".
03 USER-ID PIC X(12).
03 STATION-ID PIC X(12).
03 FILLER PIC X.
88 HAS-INDEXED-READ-PREVIOUS VALUE "Y".
03 FILLER PIC X.
88 HAS-RELATIVE-READ-PREVIOUS VALUE "Y".
03 FILLER PIC X.
88 CAN-TEST-INPUT-STATUS VALUE "Y".
03 FILLER PIC X.
88 IS-MULTI-TASKING VALUE "Y".
03 RUNTIME-VERSION.
88 VERSION-PRIOR-TO-2-2 VALUE SPACES.
05 RUNTIME-MAJOR-VERSION PIC 99.
05 RUNTIME-MINOR-VERSION PIC 99.
05 RUNTIME-RELEASE PIC 99.
03 FILLER PIC X.
88 IS-PLUGIN VALUE "Y".
03 SERIAL-NUMBER PIC X(20).
01 PrintRecord.
03 ItemNo PIC 9(08).
03 FILLER PIC X(01) VALUE SPACE.
03 ItemDesc PIC X(30).
03 FILLER PIC X(01) VALUE SPACE.
03 InOrder PIC 9(08).
03 FILLER PIC X(01) VALUE SPACE.
03 InStock PIC 9(08).
03 FILLER PIC X(01) VALUE SPACE.
03 ItemPrice PIC Z(06),Z(02)9.99.
03 FILLER PIC X(01) VALUE SPACE.
03 LineTotal PIC Z(06),Z(02)9.99-.
03 FILLER PIC X(09) VALUE SPACE.
03 FILLER PIC X(02) VALUE ": ".
03 LineRemarks PIC X(35).
PROCEDURE DIVISION.
MAIN SECTION.
MAIN-001.
OPEN OUTPUT MatrixReport.
PERFORM INIT-STUFF.
PERFORM MATRIX-HEADER.
PERFORM MATRIX-BODY.
CLOSE MatrixReport.
DESTROY WATERMARK-FONT.
DESTROY REGULAR-FONT.
CANCEL "GDI32.DLL".
STOP RUN.
MAIN-900.
MAIN-EXIT.
EXIT.
INIT-STUFF SECTION.
INIT-STUFF-001.
INITIALIZE PageCount.
*Load system information to get station name and user
ACCEPT SYSTEM-INFORMATION FROM SYSTEM-INFO.
*Load the GDI32 dll to be able to call SetBkMode.
*First we have to set proper DLL convention. Windows mode.
CALL "GDI32.DLL@WINAPI".
*Calculate the colormix for the watermark, we choose a ligth gray.
MOVE 200 TO RGB-RED
RGB-GREEN
RGB-BLUE.
COMPUTE WATERMARK-COLOR =
(RGB-RED)
(RGB-GREEN * 256)
(RGB-BLUE * 65536).
*Load the watermark font.
INITIALIZE WFONT-DATA.
SET WFDEVICE-WIN-PRINTER TO TRUE.
SET WFCHARSET-DEFAULT TO TRUE.
SET WFFAMILY-MODERN TO TRUE.
MOVE "Times New Roman" TO WFONT-NAME.
MOVE 72 TO WFONT-SIZE.
MOVE 315 TO WFONT-ANGLE.
INITIALIZE WATERMARK-FONT.
CALL "W$FONT" USING
WFONT-GET-FONT
WATERMARK-FONT
WFONT-DATA.
*Load the standard font.
INITIALIZE WFONT-DATA.
SET WFDEVICE-WIN-PRINTER TO TRUE.
SET WFCHARSET-DEFAULT TO TRUE.
SET WFFAMILY-MODERN TO TRUE.
MOVE "Courier New" TO WFONT-NAME.
MOVE 7.5 TO WFONT-SIZE.
INITIALIZE REGULAR-FONT.
CALL "W$FONT" USING
WFONT-GET-FONT
REGULAR-FONT
WFONT-DATA.
*Prepare the print to use the standard font.
INITIALIZE WPRTDATA-SET-FONT.
MOVE REGULAR-FONT TO WPRTDATA-FONT.
CALL "WIN$PRINTER" USING
WINPRINT-SET-FONT
WINPRINT-DATA.
*We want 60 lines, because that is what the report was med to be.
INITIALIZE WINPRINT-DATA.
MOVE 60 TO WPRTDATA-LINES-PER-PAGE.
CALL "WIN$PRINTER" USING
WINPRINT-SET-LINES-PER-PAGE
WINPRINT-DATA.
INIT-STUFF-900.
INIT-STUFF-EXIT.
EXIT.
WATERMARK SECTION.
WATERMARK-001.
*First, obtain the current position. This is important because
*when we switch fonts and stuff, we loose the original position.
*To continue printing, we want to restore this position at the
*end of this section. We get the current position without
*moving the cursor by initializing WPRTDATA-DRAW and set the
*WPRTDATA-DRAW-SHAPE to 1.
INITIALIZE WPRTDATA-DRAW.
MOVE WPRTUNITS-PIXELS TO WPRTDATA-DRAW-UNITS.
MOVE 1 TO WPRTDATA-DRAW-SHAPE.
CALL "WIN$PRINTER" USING
WINPRINT-SET-CURSOR
WINPRINT-DATA.
MOVE WPRTDATA-DRAW-STOP-X TO StoreXPos.
MOVE WPRTDATA-DRAW-STOP-Y TO StoreYPos.
PERFORM SET-BK-SOLID.
*Set transparent color and retain original color for later restoration
INITIALIZE WPRTDATA-TEXT-COLOR.
MOVE WATERMARK-COLOR TO WPRTDATA-TEXT-COLOR.
CALL "WIN$PRINTER" USING
WINPRINT-SET-TEXT-COLOR
WPRTDATA-TEXT-COLOR
GIVING RESTORE-COLOR.
*Set the transparent font
INITIALIZE WPRTDATA-SET-FONT.
MOVE WATERMARK-FONT TO WPRTDATA-FONT.
CALL "WIN$PRINTER" USING
WINPRINT-SET-FONT
WINPRINT-DATA.
*Move the cursor to where we want to start printing.
*Remember to use device independent measures like inch or
*centimeters.
INITIALIZE WPRTDATA-DRAW.
MOVE 5 TO WPRTDATA-DRAW-START-X
WPRTDATA-DRAW-START-Y.
MOVE WPRTUNITS-CENTIMETERS TO WPRTDATA-DRAW-UNITS.
CALL "WIN$PRINTER" USING
WINPRINT-SET-CURSOR
WINPRINT-DATA.
*Finally, print our watermark.
WRITE MatrixRecord FROM "CONFIDENTIAL"
WITH NO CONTROL.
*Restore color
INITIALIZE WPRTDATA-TEXT-COLOR.
MOVE RESTORE-COLOR TO WPRTDATA-TEXT-COLOR.
CALL "WIN$PRINTER" USING
WINPRINT-SET-TEXT-COLOR
WPRTDATA-TEXT-COLOR.
*Restore font
INITIALIZE WPRTDATA-SET-FONT.
MOVE REGULAR-FONT TO WPRTDATA-FONT.
CALL "WIN$PRINTER" USING
WINPRINT-SET-FONT
WINPRINT-DATA.
PERFORM SET-BK-TRANSPARENT.
*Restore cursor.
INITIALIZE WPRTDATA-DRAW.
MOVE WPRTUNITS-PIXELS TO WPRTDATA-DRAW-UNITS.
MOVE StoreXPos TO WPRTDATA-DRAW-START-X.
MOVE StoreYPos TO WPRTDATA-DRAW-START-Y.
CALL "WIN$PRINTER" USING
WINPRINT-SET-CURSOR
WINPRINT-DATA.
WATERMARK-900.
WATERMARK-EXIT.
EXIT.
MATRIX-HEADER SECTION.
MATRIX-HEADER-001.
ADD 1 TO PageCount.
INITIALIZE MatrixRecord.
STRING "User...: "
USER-ID DELIMITED BY SIZE INTO
MatrixRecord.
MOVE "Matrixreport" TO MatrixRecord(121:12).
IF PageCount = 1
WRITE MatrixRecord AFTER 0 LINES
ELSE
WRITE MatrixRecord AFTER ADVANCING PAGE.
INITIALIZE MatrixRecord.
STRING "Station: "
STATION-ID DELIMITED BY SIZE INTO
MatrixRecord.
MOVE "Page:" TO MatrixRecord(124:5).
MOVE PageCount TO MatrixRecord(130:3).
WRITE MatrixRecord.
INITIALIZE MatrixRecord.
STRING "----------------------------------------"
"----------------------------------------"
"----------------------------------------"
"------------" DELIMITED BY SIZE INTO
MatrixRecord.
WRITE MatrixRecord.
STRING " Item # Article description "
"In order In stock Item price Line "
"total Remarks "
" " DELIMITED BY SIZE INTO
MatrixRecord.
WRITE MatrixRecord.
INITIALIZE MatrixRecord.
STRING "========================================"
"========================================"
"========================================"
"============" DELIMITED BY SIZE INTO
MatrixRecord.
WRITE MatrixRecord.
MOVE 5 TO LinesWritten.
PERFORM WATERMARK.
MATRIX-HEADER-900.
MATRIX-HEADER-EXIT.
EXIT.
MATRIX-BODY SECTION.
MATRIX-BODY-001.
PERFORM UNTIL LinesWritten = 60
Add 1 to LinesWritten
INITIALIZE ItemNo
ItemDesc
InOrder
InStock
ItemPrice
LineTotal
LineRemarks
COMPUTE ItemNo = LinesWritten *
LinesWritten
LinesWritten
MOVE "This is another fine product" TO
ItemDesc
SUBTRACT 60 FROM LinesWritten GIVING InOrder
MOVE LinesWritten TO InStock
ADD 60 TO LinesWritten GIVING ItemPrice
COMPUTE LineTotal = (LinesWritten 60) *
InStock
WRITE MatrixRecord FROM PrintRecord
END-PERFORM.
IF PageCount
PERFORM MATRIX-HEADER
GO TO MATRIX-BODY-001.
MATRIX-BODY-900.
MATRIX-BODY-EXIT.
EXIT.
SET-BK-TRANSPARENT.
*Set background transparent
CALL "SetBkMode" USING
BY VALUE H-ACU-SPOOLER-DC
BY VALUE 1.
EXIT PARAGRAPH.
SET-BK-SOLID.
*Set transparency to "Opaq", e.g. we use the background of our
*our string. Thus, whatever is there presently will be overwritten.
CALL "SetBkMode" USING
BY VALUE H-ACU-SPOOLER-DC
BY VALUE 2.
EXIT PARAGRAPH.
Apologies for not providing the file for download, we're working on it!



