home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winui / mdi / regmpad / mpprint.c < prev    next >
C/C++ Source or Header  |  1993-07-08  |  16KB  |  422 lines

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