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