MPPRINT.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:16k
源码类别:

Windows编程

开发平台:

Visual C++

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