home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / PENPAD / PPPRINT.C_ / PPPRINT.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  13.7 KB  |  411 lines

  1. /***************************************************************************
  2.  *                                     *
  3.  *  MODULE  : PpPrint()                        *
  4.  *                                     *
  5.  *  PURPOSE : Printing code for penpad.                *
  6.  *                                     *
  7.  *  FUNCTIONS   : GetPrinterDC ()      -  Creates a printer DC for the *
  8.  *                        default device.          *
  9.  *                                     *
  10.  *        AbortProc ()         -  Export proc. for GDI to check*
  11.  *                        print abort.         *
  12.  *                                     *
  13.  *        PrintDlgProc ()      -  Dialog function for the print*
  14.  *                        cancel dialog.           *
  15.  *                                     *
  16.  *        PrintFile ()         -  Prints the contents of the   *
  17.  *                        edit control.        *
  18.  *                                     *
  19.  *        GetInitializationData () -  Gets DC initialisation data  *
  20.  *                        from a DC supporting     *
  21.  *                        ExtDeviceMode().         *
  22.  *                                     *
  23.  ***************************************************************************/
  24. #include "penpad.h"
  25.  
  26. BOOL fAbort;        /* TRUE if the user has aborted the print job    */
  27. HWND hwndPDlg;      /* Handle to the cancel print dialog         */
  28. char szDevice[160]; /* Contains the device, the driver, and the port */
  29. PSTR szDriver;      /* Pointer to the driver name            */
  30. PSTR szPort;        /* Port, ie, LPT1                */
  31. PSTR szTitle;       /* Global pointer to job title           */
  32. int iPrinter = 0;   /* level of available printer support.       */
  33.             /* 0 - no printer available          */
  34.             /* 1 - printer available             */
  35.             /* 2 - driver supports 3.0 device initialization */
  36. HANDLE hInitData=NULL;  /* handle to initialization data         */
  37.  
  38. char szExtDeviceMode[] = "EXTDEVICEMODE";
  39.  
  40. int FAR PASCAL __export AbortProc (HDC,WORD);         /* Prototype  */ 
  41.  
  42. /****************************************************************************
  43.  *                                      *
  44.  *  FUNCTION   : GetPrinterDC ()                        *
  45.  *                                      *
  46.  *  PURPOSE    : Creates a printer display context for the default device.  *
  47.  *       As a side effect, it sets the szDevice and szPort variables*
  48.  *       It also sets iPrinter to the supported level of printing.  *
  49.  *                                      *
  50.  *  RETURNS    : HDC   - A handle to printer DC.                *
  51.  *                                      *
  52.  ****************************************************************************/
  53. HDC FAR PASCAL GetPrinterDC(void)
  54. {
  55.     HDC      hdc;
  56.     LPSTR    lpdevmode = NULL;
  57.  
  58.     iPrinter = 0;
  59.  
  60.     /* Get the printer information from win.ini into a buffer and
  61.      * null terminate it.
  62.      */
  63.     GetProfileString ( "windows", "device", "" ,szDevice, sizeof(szDevice));
  64.     for (szDriver = szDevice; *szDriver && *szDriver != ','; szDriver++)
  65.     ;
  66.     if (*szDriver)
  67.     *szDriver++ = 0;
  68.  
  69.     /* From the current position in the buffer, null teminate the
  70.      * list of ports
  71.      */
  72.     for (szPort = szDriver; *szPort && *szPort != ','; szPort++)
  73.     ;
  74.     if (*szPort)
  75.     *szPort++ = 0;
  76.  
  77.     /* if the device, driver and port buffers all contain meaningful data,
  78.      * proceed.
  79.      */
  80.     if (!*szDevice || !*szDriver || !*szPort){
  81.     *szDevice = 0;
  82.     return NULL;
  83.     }
  84.  
  85.     /* Create the printer display context */
  86.     if (hInitData){
  87.     /* Get a pointer to the initialization data */
  88.     lpdevmode = (LPSTR) LocalLock (hInitData);
  89.  
  90.     if (lstrcmp (szDevice, lpdevmode)){
  91.         /* User has changed the device... cancel this setup, as it is
  92.          * invalid (although if we worked harder we could retain some
  93.          * of it).
  94.          */
  95.         lpdevmode = NULL;
  96.         LocalUnlock (hInitData);
  97.         LocalFree (hInitData);
  98.         hInitData = NULL;
  99.     }
  100.     }
  101.     hdc = CreateDC (szDriver, szDevice, szPort, lpdevmode);
  102.  
  103.     /* Unlock initialization data */
  104.     if (hInitData)
  105.     LocalUnlock (hInitData);
  106.  
  107.     if (!hdc)
  108.     return NULL;
  109.  
  110.  
  111.     iPrinter = 1;
  112.  
  113.     /* Find out if ExtDeviceMode() is supported and set flag appropriately */
  114.     if (GetProcAddress (GetModuleHandle (szDriver), szExtDeviceMode))
  115.     iPrinter = 2;
  116.  
  117.     return hdc;
  118.  
  119. }
  120.  
  121. /****************************************************************************
  122.  *                                      *
  123.  *  FUNCTION   : AbortProc()                            *
  124.  *                                      *
  125.  *  PURPOSE    : To be called by GDI print code to check for user abort.    *
  126.  *                                      *
  127.  ****************************************************************************/
  128. int FAR PASCAL __export AbortProc ( hdc, reserved )
  129. HDC hdc;
  130. WORD reserved;
  131. {
  132.     MSG msg;
  133.  
  134.      hdc;                   /* Needed to prevent compiler warning message */
  135.      reserved;          /* Needed to prevent compiler warning message */
  136.  
  137.     /* Allow other apps to run, or get abort messages */
  138.     while (!fAbort && PeekMessage (&msg, NULL, NULL, NULL, TRUE))
  139.     if (!hwndPDlg || !IsDialogMessage (hwndPDlg, &msg)){
  140.         TranslateMessage (&msg);
  141.         DispatchMessage  (&msg);
  142.     }
  143.     return !fAbort;
  144. }
  145.  
  146. /****************************************************************************
  147.  *                                      *
  148.  *  FUNCTION   : PrintDlgProc ()                        *
  149.  *                                      *
  150.  *  PURPOSE    : Dialog function for the print cancel dialog box.       *
  151.  *                                      *
  152.  *  RETURNS    : TRUE  - OK to abort/ not OK to abort               *
  153.  *       FALSE - otherwise.                     *
  154.  *                                      *
  155.  ****************************************************************************/
  156. BOOL FAR PASCAL __export PrintDlgProc(HWND hwnd, WORD msg, WORD wParam, LONG lParam)
  157. {
  158.      wParam;                    /* Needed to prevent compiler warning message */
  159.      lParam;                    /* Needed to prevent compiler warning message */
  160.  
  161.     switch (msg){
  162.     case WM_INITDIALOG:
  163.         /* Set up information in dialog box */
  164.         SetDlgItemText (hwnd, IDD_PRINTDEVICE, (LPSTR)szDevice);
  165.         SetDlgItemText (hwnd, IDD_PRINTPORT, (LPSTR)szPort);
  166.         SetDlgItemText (hwnd, IDD_PRINTTITLE, (LPSTR)szTitle);
  167.         break;
  168.  
  169.     case WM_COMMAND:
  170.         /* abort printing if the only button gets hit */
  171.         fAbort = TRUE;
  172.         break;
  173.  
  174.     default:
  175.         return FALSE;
  176.     }
  177.     return TRUE;
  178. }
  179.  
  180. /****************************************************************************
  181.  *                                      *
  182.  *  FUNCTION   : PrintFile ()                           *
  183.  *                                      *
  184.  *  PURPOSE    : Prints the contents of the edit control.           *
  185.  *                                      *
  186.  ****************************************************************************/
  187.  
  188. VOID FAR PASCAL PrintFile(HWND hwnd)
  189. {
  190.     HDC     hdc;
  191.     int     yExtPage;
  192.     char    sz[32];
  193.     WORD    cch;
  194.     WORD    ich;
  195.     PSTR    pch;
  196.     WORD    iLine;
  197.     WORD    nLinesEc;
  198.     HANDLE  hT;
  199.     FARPROC lpfnAbort;
  200.     FARPROC lpfnPDlg;
  201.     HWND    hwndPDlg;
  202.     WORD    dy;
  203.     int     yExtSoFar;
  204.     WORD    fError = TRUE;
  205.     HWND    hwndEdit;
  206.  
  207.     hwndEdit = (HWND)GetWindowWord(hwnd,GWW_HWNDEDIT);
  208.  
  209.     /* Create the job title by loading the title string from STRINGTABLE */
  210.     cch = LoadString (hInst, IDS_PRINTJOB, sz, sizeof(sz));
  211.     szTitle = sz + cch;
  212.     cch += GetWindowText (hwnd, sz + cch, 32 - cch);
  213.     sz[31] = 0;
  214.  
  215.     /* Make instances of the Abort proc. and the Print dialog function */
  216.     lpfnAbort = MakeProcInstance (AbortProc, hInst);
  217.     if (!lpfnAbort)
  218.     goto getout;
  219.     lpfnPDlg = MakeProcInstance (PrintDlgProc, hInst);
  220.     if (!lpfnPDlg)
  221.     goto getout4;
  222.  
  223.     /* Initialize the printer */
  224.     hdc = GetPrinterDC();
  225.     if (!hdc)
  226.     goto getout5;
  227.  
  228.     /* Disable the main application window and create the Cancel dialog */
  229.     EnableWindow (hwndFrame, FALSE);
  230.     hwndPDlg = CreateDialog (hInst, IDD_PRINT, hwnd, lpfnPDlg);
  231.     if (!hwndPDlg)
  232.     goto getout3;
  233.     ShowWindow (hwndPDlg, SW_SHOW);
  234.     UpdateWindow (hwndPDlg);
  235.  
  236.     /* Allow the app. to inform GDI of the escape function to call */
  237.     if (Escape (hdc, SETABORTPROC, 0, (LPSTR)lpfnAbort, NULL) < 0)
  238.     goto getout1;
  239.  
  240.     /* Initialize the document */
  241.     if (Escape (hdc, STARTDOC, cch, (LPSTR)sz, NULL) < 0)
  242.     goto getout1;
  243.  
  244.     /* Get the height of one line and the height of a page */
  245.     dy = HIWORD (GetTextExtent (hdc, "CC", 2));
  246.     yExtPage = GetDeviceCaps (hdc, VERTRES);
  247.  
  248.     /* Get the lines in document and and a handle to the text buffer */
  249.     iLine     = 0;
  250.     yExtSoFar = 0;
  251.     nLinesEc  = (WORD)SendMessage (hwndEdit, EM_GETLINECOUNT, 0, 0L);
  252.     hT        = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
  253.  
  254.     /* While more lines print out the text */
  255.     while (iLine < nLinesEc){
  256.     if (yExtSoFar + (int)dy > yExtPage){
  257.         /* Reached the end of a page. Tell the device driver to eject a
  258.          * page
  259.          */
  260.         if (Escape (hdc, NEWFRAME, 0, NULL, NULL) < 0 || fAbort)
  261.         goto getout2;
  262.         yExtSoFar = 0;
  263.     }
  264.  
  265.     /* Get the length and position of the line in the buffer
  266.      * and lock from that offset into the buffer */
  267.     ich = (WORD)SendMessage (hwndEdit, EM_LINEINDEX, iLine, 0L);
  268.     cch = (WORD)SendMessage (hwndEdit, EM_LINELENGTH, ich, 0L);
  269.     pch = LocalLock(hT) + ich;
  270.  
  271.     /* Print the line and unlock the text handle */
  272.     TextOut (hdc, 0, yExtSoFar, (LPSTR)pch, cch);
  273.     LocalUnlock (hT);
  274.  
  275.     /* Test and see if the Abort flag has been set. If yes, exit. */
  276.     if (fAbort)
  277.         goto getout2;
  278.  
  279.     /* Move down the page */
  280.     yExtSoFar += dy;
  281.     iLine++;
  282.     }
  283.  
  284.     /* Eject the last page. */
  285.     if (Escape (hdc, NEWFRAME, 0, NULL, NULL) < 0)
  286.     goto getout2;
  287.  
  288.     /* Complete the document. */
  289.     if (Escape (hdc, ENDDOC, 0, NULL, NULL) < 0){
  290. getout2:
  291.     /* Ran into a problem before NEWFRAME? Abort the document */
  292.     Escape( hdc, ABORTDOC, 0, NULL, NULL);
  293.     }
  294.     else
  295.     fError=FALSE;
  296.  
  297. getout3:
  298.     /* Close the cancel dialog and re-enable main app. window */
  299.     EnableWindow (hwndFrame, TRUE);
  300.     DestroyWindow (hwndPDlg);
  301.  
  302. getout1:
  303.     DeleteDC(hdc);
  304.  
  305. getout5:
  306.     /* Get rid of dialog procedure instances */
  307.     FreeProcInstance (lpfnPDlg);
  308.  
  309. getout4:
  310.     FreeProcInstance (lpfnAbort);
  311.  
  312. getout:
  313.  
  314.     /* Error? make sure the user knows... */
  315.     if (fError)
  316.     PPError (hwnd, MB_OK | MB_ICONEXCLAMATION, IDS_PRINTERROR, (LPSTR)szTitle);
  317.  
  318.     return;
  319. }
  320.  
  321. /****************************************************************************
  322.  *                                      *
  323.  *  FUNCTION   : GetInitializationData()                    *
  324.  *                                      *
  325.  *  PURPOSE    : Gets DC initialization data from a printer driver      *
  326.  *       supporting ExtDeviceMode(). Called in response to the      *
  327.  *       File/Printer setup menu selection.             *
  328.  *                                      *
  329.  *       This function allows the user to change the printer        *
  330.  *       settings FOR PENPAD ONLY.  This allows Penpad to print *
  331.  *       in a variety of settings without messing up any other      *
  332.  *       applications. In a more sophisticated application, this    *
  333.  *       setup could even be saved on a document-by-document basis. *
  334.  *                                      *
  335.  ****************************************************************************/
  336. BOOL FAR PASCAL GetInitializationData( hwnd )
  337. HWND hwnd ;
  338. {
  339.     LPSTR     lpOld;
  340.     LPSTR     lpNew;
  341.     int (FAR PASCAL *lpfn)(HWND, HANDLE, LPDEVMODE, LPSTR, LPSTR, LPDEVMODE, LPSTR, WORD);
  342.     HANDLE    hT,hDrv;
  343.     char      sz[32];
  344.     WORD      cb;
  345.     int       flag;
  346.  
  347.     /* Pop up dialog for user and retain data in app buffer */
  348.     flag = DM_PROMPT | DM_COPY;
  349.  
  350.     /* Load the device driver and find the ExtDeviceMode() function */
  351.     wsprintf (sz, "%s.drv", (LPSTR)szDriver);
  352.     if ((hDrv = LoadLibrary (sz)) < 32)
  353.     return FALSE;
  354.     if (!((FARPROC)lpfn = GetProcAddress (hDrv, szExtDeviceMode)))
  355.     return FALSE;
  356.  
  357.     if (hInitData){
  358.     /* We have some old data... we want to modify the previously specified
  359.      * setup rather than starting with the default setup.
  360.      */
  361.     lpOld = (LPSTR)LocalLock(hInitData);
  362.     flag |= DM_MODIFY;
  363.     }
  364.     else
  365.     lpOld = NULL;
  366.  
  367.     /* Get the number of bytes needed for the init data */
  368.     cb = (*lpfn) (hwnd,
  369.           hDrv,
  370.           NULL,
  371.           (LPSTR)szDevice,
  372.           (LPSTR)szPort,
  373.           (LPDEVMODE)NULL,
  374.           (LPSTR)NULL,
  375.           0);
  376.  
  377.     /* Grab some memory for the new data and lock it. */
  378.     hT    = LocalAlloc (LHND,cb);
  379.     lpNew = (LPSTR)LocalLock (hT);
  380.  
  381.     /* Post the device mode dialog. 0 flag iff user hits OK button */
  382.     if ((*lpfn) (hwnd,
  383.          hDrv,
  384.          (LPDEVMODE)lpNew,
  385.          (LPSTR)szDevice,
  386.          (LPSTR)szPort,
  387.          (LPDEVMODE)lpOld,
  388.          (LPSTR)NULL,
  389.          flag)==IDOK)
  390.     flag = 0;
  391.  
  392.     /* Unlock the input structures */
  393.     LocalUnlock (hT);
  394.     if (hInitData)
  395.     LocalUnlock (hInitData);
  396.  
  397.     /* If the user hit OK and everything worked, free the original init.
  398.      * data and retain the new one.  Otherwise, toss the new buffer.
  399.      */
  400.     if (flag)
  401.     LocalFree (hT);
  402.     else{
  403.     if (hInitData)
  404.         LocalFree (hInitData);
  405.     hInitData = hT;
  406.     }
  407.  
  408.     FreeLibrary(hDrv);
  409.     return (!flag);
  410. }
  411.