|
|
1.1 ! root 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: * ExtDeviceModeEx(). * ! 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 ExtDeviceModeEx() 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, NULL, NULL, 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, (WNDPROC)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 + 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 = 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 ExtDeviceModeEx(). 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 ExtDeviceModeEx() 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.