home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / printq14.zip / PRINTQ.DOC
Text File  |  1994-04-25  |  39KB  |  849 lines

  1. PrintQ - Print Library for OS/2 Presentation Manager Programs
  2. (C) Peter Wansch, 1994
  3. Version 1.31
  4.  
  5. Contents
  6. ========
  7.  
  8. 1. Introduction .............................................................. 1
  9. 1.1 What's new? .............................................................. 2
  10. 2. Requirements .............................................................. 2
  11. 3. Components of the Print Subsystem ......................................... 2
  12. 4. Functions ................................................................. 3
  13. 5. Compiling, installing and using the library .............................. 11
  14. 6. Multithreading considerations ............................................ 11
  15. 7. e-mail ................................................................... 12
  16.  
  17.  
  18. 1. Introduction
  19. ===============
  20.  
  21. The operating system OS/2 Version 2 and its graphical program environment 
  22. Presentation Manager provide outstanding functionality and consistency both 
  23. for the program developer and the user. The programming interface of the 
  24. print subsystem combined with the powerful functions of the Graphic 
  25. Programming Interface (GPI) enable the programmer to create device-independent 
  26. printed output. 
  27.  
  28. However most books about Presentation Manager programming (even those known 
  29. for their in-depth coverage of PM-Programming like "Programming the OS/2 
  30. Presentation Manager" by Charles Petzold) lack a chapter on printing. A 
  31. possible reason for that could be the fact that programming printing does not 
  32. only require some knowledge about the corresponding functions but also a 
  33. detailed understanding of the print subsystem itself. 
  34.  
  35. Hence it can be difficult for inexperienced programmers to tackle printing. 
  36. On the one hand the programming references and books lack comprehensible 
  37. examples and the sample print program from the Developers Toolkit is too 
  38. complex to use it as a template.
  39.  
  40. The dynamic link library PrintQ completely hides the print subsystem from the 
  41. programmer and provides 13 extremely easy to use functions and 4 data
  42. structures to create printed output from your Presentation Manager 
  43. applications. Hence PrintQ substantially reduces the complexity of a 
  44. Presentation Manager application and the time to implement printing because 
  45. the programmer needs no knowledge about the print subsystem. 
  46.  
  47. I hope this document together with the sample application Hello queue/2 that
  48. uses the PrintQ library provides sufficient and comprehensible documentation 
  49. for programmers. This document is a brief summary of a document about the 
  50. print subsystem and the PrintQ library which I wrote in German. I suggest that 
  51. you read this document first (you don't actually have to read chapter 3) and 
  52. have a look at the sample programs after that.
  53.  
  54. The code for the PrintQ library as well as the PRINTQ.DLL and PRINTQ.LIB files
  55. can be found in the \PRINTQ directory. The code and the file hello.exe for the
  56. sample program Hello queue/2 can be found in the \HELLOQ1, \HELLOQ2 , \HELLOQ3,
  57. \HELLOQMT and \HELLOQO directories. The sample programs are almost identical but 
  58. Hello queue/2 1.0 uses a cached-micro presentation space for drawing (obtained 
  59. withWinBeginPaint) and obtains a handle to the printer presentation space with 
  60. the function SpoolBeginSpool whereas Hello queue/2 1.1 uses a normal presentation 
  61. space both for drawing and printing. Hello queue/2 1.2 shows how printing from 
  62. a secondary thread is accomplished and Hello queue/2 1.3 shows how to save 
  63. printer settings
  64.  
  65.                                       -1-  
  66. 1.1 What's new?
  67. ===============
  68.  
  69. When you started a program using the PrintQ library 1.0 or 1.1, all settings
  70. of the printer queues were reset to their default values. Now you can save the
  71. printer settings and restore them when you call SpoolInitialize. This enables
  72. you to save the printer settings with documents or just to save the printer
  73. settings in an initialization file, so that they do not have to be changed
  74. each time you load the program. Hello queue/2 1.3 in the \HELLOQ3 directory
  75. shows how to do that and how to use the printer font dialog.
  76.  
  77. It is now safe to call PrintQ functions from separate threads in a process 
  78. since they are serialized in the PrintQ library. The sample program Hello 
  79. queue/2 1.2 in the directory \HELLOQMT shows how to implement a secondary 
  80. print thread.
  81.  
  82. More sophisticated Presentation Manager applications don't use a cached micro 
  83. or a micro presentation space that is obtained with the WinBeginPaint function 
  84. call because of its limited functionality. These programs use normal 
  85. presentation spaces that are created for a display window in response to the 
  86. WM_CREATE message of your main application window (using GpiCreatePS), 
  87. associated with the display device (the handle to that device is obtained with 
  88. the WinOpenWindowDC function) and kept until termination. 
  89. These presentation spaces also have to be destroyed using GpiDestroy. Unlike 
  90. cached-micro and micro presentation spaces, normal presentation spaces can be 
  91. disassociated from the screen device and associated with a printer device 
  92. which makes sense since all the settings are retained. 
  93.  
  94. PrintQ now supports this type of applications as well and the sample program 
  95. Hello queue/2 1.1 demonstrates the use of PrintQ functions in such a program. You just 
  96. specifiy the handle of your normal presentation space as a parameter in 
  97. SpoolBeginSpool or SpoolBeginInfo and PrintQ automatically makes all the 
  98. associations and disassociations for you. This new feature makes PrintQ usable 
  99. for a broader range of applications while retaining its ease of use. Hello queue/2 1.0
  100. also demonstrate how you can print bitmaps.
  101.  
  102.  
  103. 2. Requirements
  104. ===============
  105.  
  106. I assume that you have basic experience programming Presentation Manager
  107. applications in C and that you know how to paint in an applications client 
  108. window which comprises a certain knowledge about presentation space and device 
  109. contexts. To compile the source code for the dynamic link library and the sample 
  110. programs you need the IBM C Set/2 for OS/2 2.0 Version 1.0 and the Developer's 
  111. Toolkit for OS/2 2.0 (or higher versions) or any other C compiler for 
  112. OS/2 2.x.
  113.  
  114.  
  115. 3. Components of the Print Subsystem
  116. ====================================
  117.  
  118. The following chapter provides background information about the print 
  119. subsystem which is not necessarily required to understand the PrintQ library.
  120.  
  121. The print subsystem comprises the following components:
  122.  
  123.   * the spooler
  124.   * the user interface of the print subsystem
  125.   * the queue driver (queue processor)
  126.   * the printer driver
  127.  
  128.  
  129.                                       -2-
  130. The Spooler is a background process that controls the print subsystem. It
  131. manages print jobs that are submitted by applications in the system. 
  132. Applications do not directly print to a physical printer (device) but to a 
  133. queue. The main purpose of the Spooler is to read print jobs from a queue, 
  134. sort them according to their priority and send them to the corresponding 
  135. physical device i. e. the printer. A spooler can manage more than one queue 
  136. at once. Per default each printer has its own queue. However other 
  137. configurations e.g. for printer sharing where two or more queues are connected 
  138.  
  139. to a single device or printer pooling where two or more printer devices are 
  140. connected to a single queue are also possible. Each queue can be configured 
  141. individually. A print job in a queue is actually a meta file which is a 
  142. sequence of GPI function calls. 
  143.  
  144. The user interface of the print subsystem is realised by means of printer
  145. objects on the Workplace Shell desktop. These device objects do not represent
  146. the physical printer devices but queues. Such a queue is connected to a 
  147. logical device that contains the specification of the corresponding physical 
  148. device. The specification comprises the printer driver and the port to which 
  149. the physical device is attached. The settings for the printer objects on the 
  150. desktop are stored in the system initialisation file OS2SYS.INI.
  151.  
  152. The queue driver (sometimes referred to as queue processor) retrieves the 
  153. print jobs from the queue and sends the corresponding meta files to the 
  154. printer driver.
  155.  
  156. The printer driver provides a dialog window that allows the user to view and
  157. change the configuration of the physical device (e. g. which forms are 
  158. available and which font cards are installed) and a dialog window that enables 
  159. the user to configure an individual print job (e. g. set the default font or 
  160. form). This configuration data is also referred to as Job properties. Hence a 
  161. print job consists of a meta file and Job properties which are its default 
  162. print settings. The printer driver also translates the device independent GPI 
  163. function calls in the meta file of a print job into a printer specific command 
  164. language like PCL, PPDS or Postscript. After the translation the printer 
  165. driver directly sends the data to the printer via the file system and the 
  166. corresponding port. 
  167.  
  168.  
  169. 4. Functions
  170. ============
  171.  
  172. The functions that are provided by PrintQ are displayed in the following 
  173. table.
  174.  
  175.                             {SpoolInitialize
  176.                                     |
  177.                                     |
  178.       {SpoolBeginSetup       {SpoolBeginInfo         {SpoolBeginSpool         
  179.               |                                              |
  180.               |                                              |
  181.   SpoolSetDef, SpoolJobProp                    SpoolNewFrame, GPI functions
  182.               |                                              |
  183.               |                                              |
  184.         SpoolEndSetup}        SpoolEndInfo}   SpoolAbortSpool, SpoolEndSpool}
  185.                                     |
  186.                                     |
  187.                               SpoolTerminate}
  188.  
  189. Some functions (SpoolInitialize and SpoolTerminate, SpoolBeginSetup and 
  190. SpoolEndSetup, SpoolBeginInfo and SpoolEndInfo, SpoolBeginSpool and 
  191. SpoolEndSpool) form logical brackets.
  192.  
  193. The use of these functions is shown in the sample programs.
  194.                                       -3-
  195. This dependence also imposes a sequence on the correct use of the library 
  196. functions. For instance SpoolAbortSpool and SpoolNewFrame can only be used 
  197. after a SpoolBeginSpool call. You should be familiar with these logical 
  198. brackets since they are used in Presentation Manager programs all the time 
  199. (e. g. WinInitialize and WinTerminate or WinBeginPaint and WinEndPaint). 
  200. In the following the use of these functions will be described.
  201.  
  202.  
  203. BOOL SpoolInitialize(HAB hab, PDRIVDATA pDriverData, PBOOL pfIni)
  204.  
  205.   Before you can use any function or data structure provided by the library 
  206.   you have to initialise the library for use by your program. The first
  207.   parameter is the anchor block-handle of your application that you obtain by 
  208.   a WinInitialize function call which is normally the first statement in a 
  209.   Presentation Manager application. Hence it is advisable to call 
  210.   SpoolInitialize immediately after WinInitialize. If you have saved the driver
  211.   data you can pass a pointer to a DRIVDATA structure in the second parameter or
  212.   you can pass NULL. In the third parameter you pass a pointer to a flag. If
  213.   the flag is true, SpoolInitialize tries to set the default printer and its
  214.   settings according to the data passed in the second parameter. If that is
  215.   not possible (for instance if a different version of the corresponding printer
  216.   driver has been installed) the flag to which pfIni points will be set to FALSE
  217.   after the call. See Hello queue/2 1.3 in the \HELLOQ3 directory for an
  218.   example, where the driver data is stored in the user ini profile.
  219.  
  220.   All Library functions  return a value of type BOOL which indicates whether
  221.   or not the function was  successful (TRUE success, FALSE error occurred). 
  222.   If you for instance call  any other library function before initialising 
  223.   the library, this function  will return FALSE. You should always check the 
  224.   return values of the PrintQ functions. In the sample programs the return 
  225.   value is only checked for the SpoolInitialize function to improve the 
  226.   clarity of the sample program.
  227.  
  228. BOOL SpoolTerminate(void)
  229.  
  230.   This function terminates the use of the PrintQ library and releases of 
  231.   resources associated with the application. It forms a logical bracket with 
  232.   the SpoolInitialize function like the WinInitialize and WinTerminate 
  233.   functions. Hence it is advisable that this function is the last but one 
  234.   function in your program with WinTerminate being the last function. 
  235.  
  236.   The File menu of a Presentation Manager application normally contains a 
  237.   Printer setup item. When you choose this command a dialog window is 
  238.   displayed that consists of a list box and several push buttons. The list box 
  239.   displays the printers that are available in the system. The default printer 
  240.   (which can be set in the context menu of any printer object with the command 
  241.   "Set default") is selected. Now you can select a different printer or change 
  242.   the job properties for a printer. The job properties are the settings that 
  243.   are specific for the print job in your application. In your application you 
  244.   have to create a dialog box template for the printer setup dialog and write 
  245.   the dialog procedure. Your dialog box should consist of a list box, an OK 
  246.   button a Cancel button and a Job properties button. If you provide on-line 
  247.   help you should also include a Help button. In response to the WM_INITDLG 
  248.   messages which is sent to your dialog procedure before the dialog window is 
  249.   displayed, you have to call the following function.
  250.  
  251. BOOL SpoolBeginSetup(HWND hwnd)
  252.  
  253.   where hwnd is the handle to the printer list box. You can obtain a handle to
  254.   the list box using the WinWindowFromId function. When the user chooses the 
  255.   Job properties button you receive a corresponding WM_COMMAND message and you 
  256.   call the following function. If hwnd is NULLHANDLE, Printq assumes that you
  257.   don't want to display a list box. If you call SpoolJobProp the Jop properties
  258.   dialog window of the currently selected printer is displayed.
  259.  
  260.                                       -4-
  261. BOOL SpoolJobProp(void)
  262.  
  263.   This function displays the Job properties dialog window for the currently 
  264.   selected printer. When the user presses the OK button in the Printer setup
  265.   dialog window the default printer settings for your application has to be 
  266.   updated using the following function.
  267.  
  268. BOOL SpoolSetDef(void)
  269.  
  270.   sets the hilited printer in the List box your default printer. The data 
  271.   structures that information on the device and form capabilities are updated.
  272.  
  273. BOOL SpoolEndSetup(void) 
  274.  
  275.   forms a logical bracket with the SpoolBeginSetup function. It is advisable to
  276.   call the function after the WindDlgBox function call which displays the 
  277.   Printer setup dialog. 
  278.  
  279.  
  280.   If you want to obtain a presentation space to the printer currently selected 
  281.   in your application just to retrieve information (e. g. about font metrics), 
  282.   you use the following function.
  283.  
  284. BOOL SpoolBeginInfo(PHPS phpsPrinterInfo, BOOL fAssocPS)
  285.  
  286.   The parameter phpsPrinterInfo is a pointer to a HPS variable which is assigned
  287.   the presentation parameter of the currently selected printer if fAssocPS is 
  288.   FALSE. If fAssocPS is TRUE this function expects a pointer to the handle of 
  289.   a normal presentation space which it will associate with the printer device 
  290.   context. This returned presentation space is an information presentation 
  291.   space which is used to query information about a device associated with it. 
  292.   Directing GPI functions to this yields no printed output.
  293.  
  294. BOOL SpoolEndInfo(void)
  295.  
  296.   forms a logical bracket with the SpoolBeginInfo function. This function is 
  297.   especially important if you use a normal presentation space in your program 
  298.   since it re-associates the presentation space with the display device 
  299.   context.
  300.  
  301.   A print job is normally started in response to the user choosing the Print 
  302.   command from the File menu i. e. in response to the corresponding WM_COMMAND
  303.   message. To start a print job you call the following function.
  304.  
  305. BOOL SpoolBeginSpool(PSZ pszComment, PSZ pszDocName, PSZ pszQueueProcParams, 
  306.                      ULONG ulOptions, PHPS phpsPrinter, BOOL fAssocPS)
  307.  
  308.   The first parameter pszComment is a zero-terminated comment string 
  309.   describing the print job. This string is displayed in the settings of a 
  310.   print job on the Submission data page and has no further relevance. The 
  311.   second parameter pszDocName is a null-terminated string that is the name 
  312.   (title) of the print job. This string is the document name of the print job. 
  313.   The third parameter pszQueueProcParms is a zero-terminated string that may 
  314.   contain commands for the queue processor separated by one or more blanks. 
  315.   The available commands are:
  316.  
  317.   COP=n          
  318.  
  319.   The COP parameter specifies the number of copies that you want printed. The 
  320.   value of n must be an integer in the range of 1 through 999. The default 
  321.   value of n is 1.
  322.  
  323.  
  324.  
  325.                                       -5-
  326.   COL=M|C  
  327.  
  328.   The COL parameter enables you to specify color output if you have a color
  329.   printer. A value of COL=M creates monochrome output. A value of COL=C creates
  330.   color output. The default value of COL is M for a monochrome printer and C 
  331.   for a color printer.
  332.  
  333.   MAP=N|A        
  334.  
  335.   The MAP parameter specifies how neutral colors (colors which were not 
  336.   defined e. g. the background color) are printed. The default value N yields 
  337.   a white background and a black foreground while a value of MAP=A provides 
  338.   the reverse of the normal representation. 
  339.  
  340.   ARE=C|w,h,l,t  
  341.  
  342.   This parameter determines the size and position of the output area on the 
  343.   physical printer page. The default value of ARE=C means that the output area
  344.   is the whole page. To size and position the output area at a specific point 
  345.   
  346.   
  347.   on the page use ARE=w,h,l,t where w and h are the width and height of the 
  348.   desired output area and l and t are the offsets of the upper-left corner of 
  349.   the output area from the left and from the top of the maximum output area. 
  350.   These four values must be gives as percentages of the maximum output 
  351.   dimensions.
  352.  
  353.   FIT=S|l,t      
  354.  
  355.   This parameter determines which part of a picture is to be printed. The 
  356.   default value of FIT=S causes the output to be scaled until the larger of 
  357.   the height or width just fits within the defined output area. The aspect 
  358.   ratio of the picture is maintained. To print the picture in actual size use 
  359.   FIT=l,t where l and t are the coordinates of the point in the picture that 
  360.   you want positioned at the center of the output area. l is measured from the 
  361.   left edge of the picture and it is measured from the top edge. The 
  362.   coordinates must be gives as percentages of the actual dimensions of the 
  363.   picture.
  364.  
  365.   XFM=0|1        
  366.  
  367.   The default value of XFM=1 allows the appearance of the output to be 
  368.   determined by the ARE and FIT parameters. A value of XFM=0 yields output as 
  369.   specified in the picture file.
  370.  
  371.   For instance the string "COP=2 MAP=A" would result in two inverse copies.
  372.  
  373.   Default values are used for parameters that are omitted or used incorrectly.
  374.   Bitmaps or image data is not affected by the ARE and FIT parameters.
  375.  
  376.   The fourth parameter ulOptions determines the scale units for the printer 
  377.   presentation space. If you use 0UL, pixels are used. Other options are 
  378.   PU_LOMTRIC (0.1 mm), PU_HIMETRIC (0.01 mm), PU_LOENGLISH (0.01 inch), 
  379.   PU_HIENGLISH (0.001 inch) or PU_TWIPS (1/1440 inch). If fAssocPS is TRUE, 
  380.   the parameter phpsPrinter is a pointer to a HPS variable which is assigned 
  381.   the presentation space of the currently selected printer. If fAssocPS is 
  382.   TRUE this function expects a pointer to the handle of a normal presentation 
  383.   space which it will associate with the printer device context. 
  384.   Now you can use this presentation space handle as the first parameter for 
  385.   GPI functions like GpiLine. The coordinates are interpreted with respect to 
  386.   the ulOptions parameter.
  387.  
  388.   Use the following function to start a new page and to eject the old page.
  389.  
  390.                                       -6-
  391. BOOL SpoolNewFrame(void)
  392.  
  393.   To end the print job use the following function.
  394.  
  395. BOOL SpoolEndSpool(PUSHORT pusJobId)
  396.  
  397.   The parameter pusJobId is a pointer to an USHORT variable which is assigned 
  398.   the id of the submitted print job. This variable can be used to inform the 
  399.   user of the id of the print job if desired. 
  400.  
  401.   If you decide to abort the print job without actually printing after calling 
  402.   the SpoolBeginSpool function (e. g. in response to a user request) you use 
  403.   the following function.
  404.  
  405. SpoolAbortSpool(void)
  406.  
  407.   Please note that it is not neccessary to call SpoolEndSpool after 
  408.   SpoolAbortSpool since you either call SpoolAbortSpool or SpoolEndSpool to 
  409.   close the logical bracket with the SpoolBeginSpool function.
  410.  
  411.   
  412.   The library also provides 4 variables. These variables are only valid after
  413.   initialising the Library using the SpoolInitialize function and before de-
  414.   registering from the library using the SpoolTerminate function. Their use is 
  415.   illustrated in the sample program Hello queue/2. The variable hcInfoDef is
  416.   a structure of type HCINFO and it contains information about the currently 
  417.   selected form of the currently selected printer. It is also described in the 
  418.   PM Reference as follows:
  419.  
  420.   typedef struct _HCINFO {
  421.     CHAR    szFormname[32];  /* Form name */
  422.     LONG    cx;              /* Width (left-to-right) in millimeters  */
  423.     LONG    cy;              /* Height (top-to-bottom) in millimeters  */
  424.     LONG    xLeftClip;       /* Left clip limit in millimeters  */
  425.     LONG    yBottomClip;     /* Bottom clip limit in millimeters  */
  426.     LONG    xRightClip;      /* Right clip limit in millimeters  */
  427.     LONG    yTopClip;        /* Top clip limit in millimeters  */
  428.     LONG    xPels;           /* Pels between left and right clip limits  */
  429.     LONG    yPels;           /* Pels between bottom and top clip limits  */
  430.     LONG    flAttributes;    /* Attributes of the form identifier  */
  431.   } HCINFO;
  432.  
  433.   The variable prqInfoDef is a structure of type PRQINFO3 and is described in
  434.   the PM Reference as follows. It provides information about the currently 
  435.   selected printer queue.
  436.  
  437.   typedef struct _PRQINFO3 {
  438.     PSZ          pszName;        /* Queue name  */
  439.     USHORT       uPriority;      /* Queue priority  */
  440.     USHORT       uStartTime;     /* Time when queue becomes active  */
  441.     USHORT       uUntilTime;     /* Time when queue ceases to be active  */
  442.     USHORT       fsType;         /* Queue type  */
  443.     PSZ          pszSepFile;     /* SeParator-page file  */
  444.     PSZ          pszPrProc;      /* Default queue-processor  */
  445.     PSZ          pszParms;       /* Queue Parameters  */
  446.     PSZ          pszComment;     /* Queue description  */
  447.     USHORT       fsStatus;       /* Queue status  */
  448.     USHORT       cJobs;          /* Number of jobs in queue  */
  449.     PSZ          pszPrinters;    /* Print devices connected to queue  */
  450.     PSZ          pszDriverName;  /* Default device driver  */
  451.     PDRIVDATA    pDriverData;    /* Default queue job properties  */
  452.   } PRQINFO3;
  453.  
  454.  
  455.                                       -7-
  456.   The third variable alCaps is an array of LONG values. You access the array 
  457.   elements using the following symbolic names. For instance the number of 
  458.   available physical colors on the currently selected printer (which will be 2 
  459.   for non-color printers) is alCaps[CAPS_PHYS_COLORS]. The following description 
  460.   is copied from the PM Reference.
  461.  
  462.   CAPS_FAMILY 
  463.     Device type (values as for lType in DevOpenDC). 
  464.   CAPS_IO_CAPS 
  465.     Device input/output capability: 
  466.     CAPS_IO_DUMMY 
  467.       Dummy device 
  468.     CAPS_SUPPORTS_OP 
  469.       Device supports output 
  470.     CAPS_SUPPORTS_IP 
  471.        Device supports input 
  472.     CAPS_SUPPORTS_IO 
  473.        Device supports output and input. 
  474.   
  475.   CAPS_TECHNOLOGY 
  476.       Technology: 
  477.     CAPS_TECH_UNKNOWN 
  478.       Unknown 
  479.     CAPS_TECH_VECTOR_PLOTTER 
  480.       Vector plotter 
  481.     CAPS_TECH_RASTER_DISPLAY 
  482.       Raster display 
  483.     CAPS_TECH_RASTER_PRINTER 
  484.       Raster printer 
  485.      CAPS_TECH_RASTER_CAMERA 
  486.       Raster camera 
  487.     CAPS_TECH_POSTSCRIPT 
  488.       PostScript device. 
  489.   CAPS_DRIVER_VERSION 
  490.     Version identifier of the Presentation driver. The high order word of the 
  491.     version identifier is 0. The low order word identifies the release, for 
  492.     example x0120 is release 1.2. 
  493.   CAPS_WIDTH 
  494.     Media width (for a full screen, maximized window for displays) in pels. 
  495.   CAPS_HEIGHT 
  496.     Media depth (for a full screen, maximized window for displays) in pels. 
  497.     (For a plotter, a pel is defined as the smallest possible displacement of 
  498.     the pen and can be smaller than a pen width.) 
  499.   CAPS_WIDTH_IN_CHARS 
  500.     Media width (for a full screen, maximized window for displays) in default 
  501.     character columns. 
  502.   CAPS_HEIGHT_IN_CHARS 
  503.     Media depth (for a full screen, maximized window for displays) in default 
  504.     character rows. 
  505.   CAPS_HORIZONTAL_RESOLUTION 
  506.     Horizontal resolution of device in pels per meter. 
  507.   CAPS_VERTICAL_RESOLUTION 
  508.     Vertical resolution of device in pels per meter. 
  509.   CAPS_CHAR_WIDTH 
  510.     Default character-box width in pels for VIO. 
  511.   CAPS_CHAR_HEIGHT 
  512.     Default character-box height in pels for VIO. 
  513.   CAPS_SMALL_CHAR_WIDTH 
  514.     Default small-character box width in pels for VIO. This is 0 if there is 
  515.     only one character-box size. 
  516.   CAPS_SMALL_CHAR_HEIGHT 
  517.     Default small-character box height in pels for VIO. This is 0 if there is 
  518.     only one character-box size. 
  519.  
  520.                                       -8-
  521.   CAPS_COLORS 
  522.     Number of distinct colors supported at the same time, including reset 
  523.     (gray scales count as distinct colors). If loadable color tables are 
  524.     supported, this is the number of entries in the device color table.  For 
  525.     plotters, the value returned is the number of pens plus one (for the 
  526.     background). 
  527.   CAPS_COLOR_PLANES 
  528.     Number of color planes. 
  529.   CAPS_COLOR_BITCOUNT 
  530.     Number of adjacent color bits for each pel (within one plane). 
  531.   CAPS_COLOR_TABLE_SUPPORT 
  532.     Loadable color table support: 
  533.     CAPS_COLTABL_RGB_8 
  534.       1 if RGB color table can be loaded, with a minimum support of 8 bits 
  535.       each for red, green, and blue. 
  536.     CAPS_COLTABL_RGB_8_PLUS 
  537.       1 if color table with other than 8 bits for each primary color can be 
  538.       loaded. 
  539.     
  540.     CAPS_COLTABL_TRUE_MIX 
  541.       1 if true mixing occurs when the logical color table has been realized, 
  542.       providing that the size of the logical color table is not greater than 
  543.       the number of distinct colors supported (see element CAPS_COLORS). 
  544.     CAPS_COLTABL_REALIZE 
  545.       1 if a loaded color table can be realized. 
  546.   CAPS_MOUSE_BUTTONS 
  547.     The number of pointing device buttons that are available. A returned value 
  548.     of 0 indicates that there are no pointing device buttons available. 
  549.   CAPS_FOREGROUND_MIX_SUPPORT 
  550.     Foreground mix support: 
  551.     CAPS_FM_OR 
  552.       Logical OR. 
  553.     CAPS_FM_OVERPAINT 
  554.       Overpaint. 
  555.     CAPS_FM_XOR 
  556.       Logical XOR. 
  557.     CAPS_FM_LEAVEALONE 
  558.       Leave alone. 
  559.     CAPS_FM_AND 
  560.       Logical AND. 
  561.     CAPS_FM_GENERAL_BOOLEAN 
  562.       All other mix modes; see GpiSetMix. The value returned is the sum of the 
  563.       values appropriate to the mixes supported. A device capable of 
  564.       supporting OR must, as a minimum, return CAPS_FM_OR + CAPS_FM_OVERPAINT + 
  565.       PS_FM_LEAVEALONE, signifying support for the mandatory mixes OR, 
  566.       overpaint, and leave-alone. Note that these numbers correspond to the 
  567.       decimal representation of a bit string that is six bits long, with each 
  568.       bit set to 1 if the appropriate mode is supported. Those mixes returned 
  569.       as supported are guaranteed for all primitive types.
  570.   CAPS_BACKGROUND_MIX_SUPPORT 
  571.     Background mix support: 
  572.     CAPS_BM_OR 
  573.       Logical OR. 
  574.     CAPS_BM_OVERPAINT 
  575.       Overpaint. 
  576.     CAPS_BM_XOR 
  577.       Logical XOR. 
  578.     CAPS_BM_LEAVEALONE 
  579.       Leave alone. 
  580.     CAPS_BM_AND 
  581.       Logical AND. 
  582.  
  583.  
  584.  
  585.                                       -9-
  586.     CAPS_BM_GENERAL_BOOLEAN 
  587.       All other mix modes; see GpiSetBackMix. The value returned is the sum of 
  588.       the values appropriate to the mixes supported. A device must, as a 
  589.       minimum, return CAPS_BM_OVERPAINT + CAPS_BM_LEAVEALONE, signifying 
  590.       support for the mandatory background mixes overpaint, and leave-alone. 
  591.       Note that these numbers correspond to the decimal rePresentation of a bit 
  592.       string that is four bits long, with each bit set to 1 if the appropriate 
  593.       mode is supported. Those mixes returned as supported are guaranteed for 
  594.       all primitive types.  
  595.   CAPS_VIO_LOADABLE_FONTS 
  596.     Number of fonts that can be loaded for VIO. 
  597.   CAPS_WINDOW_BYTE_ALIGNMENT 
  598.     Whether or not the client area of VIO windows should be byte-aligned: 
  599.     CAPS_BYTE_ALIGN_REQUIRED 
  600.       Must be byte-aligned. 
  601.     CAPS_BYTE_ALIGN_RECOMMENDED 
  602.       More efficient if byte-aligned, but not required. 
  603.     CAPS_BYTE_ALIGN_NOT_REQUIRED 
  604.       Does not matter whether byte-aligned. 
  605.   
  606.   CAPS_BITMAP_FORMATS 
  607.     Number of bit-map formats supported by device. 
  608.   CAPS_RASTER_CAPS 
  609.     Capability for device raster operations: 
  610.     CAPS_RASTER_BITBLT 
  611.       1 if GpiBitBlt and GpiWCBitBlt supported 
  612.     CAPS_RASTER_BANDING 
  613.       1 if banding is supported 
  614.     CAPS_RASTER_BITBLT_SCALING 
  615.       1 if GpiBitBlt and GpiWCBitBlt with scaling supported. 
  616.     CAPS_RASTER_SET_PEL 
  617.       1 if GpiSetPel supported. 
  618.     CAPS_RASTER_FONTS 
  619.       1 if this device can draw raster fonts. 
  620.     CAPS_RASTER_FLOOD_FILL 
  621.       1 if GpiFloodFill is supported. 
  622.   CAPS_MARKER_HEIGHT 
  623.     Default marker-box height in pels. 
  624.  
  625.   CAPS_MARKER_WIDTH 
  626.     Default marker-box width in pels. 
  627.   CAPS_DEVICE_FONTS 
  628.     Number of device-specific fonts. 
  629.   CAPS_GRAPHICS_SUBSET 
  630.     Graphics drawing subset supported. (3 indicates GOCA DR/3) 
  631.   CAPS_GRAPHICS_VERSION 
  632.     Graphics architecture version number supported. (1 indicates Version 1) 
  633.   CAPS_GRAPHICS_VECTOR_SUBSET 
  634.     Graphics vector drawing subset supported. (2 indicates GOCA VS/2) 
  635.   CAPS_DEVICE_WINDOWING 
  636.     Device windowing support: 
  637.     CAPS_DEV_WINDOWING_SUPPORT 
  638.       1 if device supports windowing. Other bits are reserved 0. 
  639.   CAPS_ADDITIONAL_GRAPHICS 
  640.     Additional graphics support: 
  641.     CAPS_GRAPHICS_KERNING_SUPPORT 
  642.       1 if device supports kerning. 
  643.     CAPS_FONT_OUTLINE_DEFAULT 
  644.       1 if device has a default outline font. 
  645.     CAPS_FONT_IMAGE_DEFAULT 
  646.       1 if device has a default image font. 
  647.     CAPS_SCALED_DEFAULT_MARKERS 
  648.       1 if default markers are to be scaled by the marker-box attribute. 
  649.  
  650.                                       -10-
  651.     CAPS_COLOR_CURSOR_SUPPORT 
  652.       1 if device supports colored cursors. 
  653.     CAPS_PALETTE_MANAGER 
  654.       1 if device supports palette functions. 
  655.     CAPS_COSMETIC_WIDELINE_SUPPORT 
  656.       1 if device supports cosmetic thick lines  
  657.     CAPS_ENHANCED_TEXT 
  658.       1 if device supports full font file description and text alignment. 
  659.       Other bits are reserved 0. 
  660.   CAPS_PHYS_COLORS 
  661.     Maximum number of distinct colors available on the device. 
  662.   CAPS_COLOR_INDEX 
  663.     Maximum logical color-table index supported for this device. For the EGA 
  664.     and VGA drivers, the value is 63. 
  665.   CAPS_GRAPHICS_CHAR_WIDTH 
  666.     Default graphics character-box width, in pels. 
  667.   CAPS_GRAPHICS_CHAR_HEIGHT 
  668.     Default graphics character-box height, in pels. 
  669.   
  670.   CAPS_HORIZONTAL_FONT_RES 
  671.     Effective horizontal device resolution in pels per inch, for the purpose 
  672.     of selecting fonts. For printers, this is the actual device resolution, 
  673.     but for displays it may differ from the actual resolution for reasons of 
  674.     legibility. 
  675.   CAPS_VERTICAL_FONT_RES 
  676.     Effective vertical device resolution in pels per inch, for the purpose of 
  677.     selecting fonts. 
  678.   CAPS_DEVICE_FONT_SIM 
  679.     Identifies which simulations are valid on device fonts. Valid flags are: 
  680.     CAPS_DEVICE_FONT_SIM_BOLD 
  681.     CAPS_DEVICE_FONT_SIM_ITALIC 
  682.     CAPS_DEVICE_FONT_SIM_UNDERSCORE 
  683.     CAPS_DEVICE_FONT_SIM_STRIKEOUT 
  684.   CAPS_LINEWIDTH_THICK 
  685.     Cosmetic thickness of lines and arcs on this device, when fxLineWidth is   
  686.     LINEWIDTH_THICK. The units are pels.  A value of 0 is interpreted as 2 
  687.     pels.  
  688.  
  689.   If you select another printer or change the Job properties of the currently 
  690.   selected printer these variables are updated. You use these variables to 
  691.   position graphics on a page (e. g. to determine the boundaries of a page).
  692.  
  693. The fourth variable hcPrn is a handle to the printer device context. You need
  694. this handle when you want to print bitmaps.
  695.  
  696.  
  697. 5. Compiling, installing and using the library
  698. ==============================================
  699.  
  700. The source code of the library and the sample programs Hello queue/2 include
  701. makefiles. The makefiles require the include file ibmc.inc which must be 
  702. copied to an include path. (e. g. \IBMC\INCLUDE for the IBM C Set/2 1.0 
  703. compiler). To create the DLL and the import library type NMAKE at the command 
  704. prompt. Then you have to copy the file PRINTQ.DLL to a path that is included in 
  705. the LIBPATH statement of your CONFIG.SYS file (e. g. \OS2\DLL). To use the 
  706. library in an application you have to copy the created import library PRINTQ.LIB 
  707. to a directory where your C compiler searches for libraries (e. g. \IBMC\LIB). 
  708. You also have to copy the file PrintQ.h to a path where your C compiler searches 
  709. for include files (e. g. \IBMC\INCLUDE). In every C source code file that uses 
  710. PrintQ library functions you have to insert the following line
  711.  
  712. #include <printq.h>
  713.  
  714. The file PRINTQ.H contains function prototypes and the definition of the 3 
  715. variables. Makes sure that you add the name of the import library file 
  716. PRINTQ.LIB when linking the .obj files. You have to use the system linkage
  717. convention (IBM C Set/2 1.0 compiler option /Ms) instead of optlink.
  718.                                       -11-
  719. 6. Multithreading considerations
  720. ================================
  721.  
  722. If spooling a print job in your application takes considerably longer than a 
  723. few seconds you might want to use a secondary thread to print from your 
  724. application so that the system queue is not blocked while you are printing. 
  725. Please note that if you use a normal presentation space and you have started a 
  726. print job the presentation space is not associated with your screen until you 
  727. call either SpoolAbortSpool or SpoolEndSpool so you must think of a way to 
  728. synchronize painting and printing. You could for instance obtain a cached 
  729. micro-presentation space when printing and just paint the window with 
  730. SYSCLR_WINDOW in the meantime. 
  731.  
  732. The first two samples do not print in secondary threads so if you plan to do so 
  733. in your application, have a look at Hello queue/2 1.2 in \HELLOQMT. 
  734.  
  735. Here is a short description of the program:
  736.  
  737. In your primary thread a flag fPrintThreadStarted indicates if there is a 
  738. secondary print thread. This variable is initialised as FALSE. In response to 
  739. a Print-WM_COMMAND message you set this variable TRUE. Then you create a 
  740. thread for the printing function Print(). While the printing flag is set you 
  741. must not allow your primary thread to modify the data that is being printed in 
  742. any way. It's a good idea to gray the menu items that change the data and the 
  743. Print menu item. In our sample application only the Printer setup choice can 
  744. change the data so it is grayed. The Print item has to be grayed because we 
  745. only allow one secondary thread at a time which is not a limitation. It is a 
  746. good idea to include an Abort print job choice in your File menu. This choice 
  747. is enabled when a print job has been started. You can determine whether or 
  748. not a job has been started using the SpoolIsJobStarted() function. We use this 
  749. function when processing the WM_INITMENU function. In response to the Abort 
  750. print job WM_COMMAND message we use the SpoolAbortSpool function to abort the 
  751. printing process. You can also use the SpoolIsJobStarted function in your 
  752. printing function to determine - while calling GpiFunctions - if the job has 
  753. been aborted. If SpoolIsJobStarted returns FALSE then you post a "Job done" 
  754. message to your application window. I think this is quite an elegant 
  755. alternative to the modal dialog box in Windoze. In the secondary thread after 
  756. everything is printed and before it terminates you should as mentioned before 
  757. post a message to your main window procedure to report that the job has been 
  758. done. In response to that you set the printing flag fPrintThreadStarted to 
  759. FALSE. This is a very simple communication pattern that works fine for 
  760. communication with secondary threads. You just have to check the return code of 
  761. WinPostMsg because in the (unlikely) event that your message queue is full your 
  762. printing flag is never reset because you lost the message posted by the printing 
  763. function. Hence I suggest something like this when using WinPostMsg to ensure 
  764. that a message is posted sucessfully:
  765.  
  766.   while (!WinPostMsg(hwndMain, WMP_PRINT_JOB_DONE, NULL, NULL))
  767.     DosSleep(BACKOFF_TIME);
  768.  
  769. When your primary window is destroyed (i.e. in the course of processing the 
  770. WM_DESTROY message) you have to wait for the print thread to terminate. 
  771.  
  772. If you have to use _beginthread to start your printing thread you must use the 
  773. _Optlink keyword to specifiy the oplink linkage convention otherwise the 
  774. compile will report an error if you use the /Ms option for system linkage. 
  775. You must not use the optlink convention for your entire program just for your 
  776. Print thread if started with _beginthread otherwise parameter passing to 
  777. PrintQ functions does not work. You specifiy optlink for a print function 
  778. called Print as follows:
  779. void _Optlink Print(void *arg);
  780.  
  781.  
  782.  
  783.                                       -12-
  784. 7. e-mail
  785. =========
  786.  
  787. Your e-mail is appreciated if you have any comments, suggestions or questions.
  788.  
  789. Peter Wansch
  790. Vienna, Austria
  791. e-mail p.wansch@ieee.org
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.  
  801.  
  802.  
  803.  
  804.  
  805.  
  806.  
  807.  
  808.  
  809.  
  810.  
  811.  
  812.  
  813.  
  814.  
  815.  
  816.  
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.  
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846.  
  847.  
  848.                                       -12-
  849.