|
|
1.1 ! root 1: /******************************************************************************\ ! 2: * ! 3: * PROGRAM: PRINTER.C ! 4: * ! 5: * PURPOSE: This is a sample application demostrating some of the new ! 6: * printing functionality in Windows NT. This app allows the ! 7: * user to select between various GDI graphics primitives, ! 8: * to choose pen & brush colors, styles, and sizes, and to ! 9: * the print these graphics to a printer. Also, the app ! 10: * provides the user the ability to query information (reso- ! 11: * lution, etc.) about the various printers & drivers by ! 12: * making calls to GetDeviceCaps, etc. ! 13: * ! 14: * Functionality for PRINTER is split into six different ! 15: * modules as follows: ! 16: * ! 17: * printer.c - main event loop ! 18: * main window procedure ! 19: * about & abort dialog procedures ! 20: * printing thread ! 21: * ! 22: * paint.c - handles all painting printers & most painting ! 23: * to window ! 24: * ! 25: * enumprt.c - manages the display of information returned ! 26: * from calling EnumPrinters, EnumPrinterDrivers ! 27: * ! 28: * devcapsx.c- manages the display of information returned ! 29: * from calling DeviceCapabilitiesEx ! 30: * ! 31: * getpdriv.c- manages the display of information returned ! 32: * from calling GetPrinterDriver ! 33: * ! 34: * getcaps.c - manages the display of information returned ! 35: * from calling GetDeviceCaps ! 36: * ! 37: * FUNCTIONS: WinMain - initialization, create window, msg loop ! 38: * MainWndProc - processes main window msgs ! 39: * AboutDlgProc - processes About dlg msgs ! 40: * InvalidateClient - invalidates graphics part of client wnd ! 41: * RefreshPrinterCombobox- updates list of printers ! 42: * PrintThread - printing done here ! 43: * AbortProc - msg loop for abort ! 44: * AbortDlgProc - processes abort dialog messages ! 45: * ! 46: * ! 47: * Microsoft Developer Support ! 48: * Copyright (c) 1992 Microsoft Corporation ! 49: * ! 50: \******************************************************************************/ ! 51: ! 52: #include <windows.h> ! 53: #include <stdio.h> ! 54: #include <string.h> ! 55: #include <winspool.h> ! 56: #include <commdlg.h> ! 57: #include "common.h" ! 58: #include "printer.h" ! 59: ! 60: ! 61: ! 62: /******************************************************************************\ ! 63: * ! 64: * FUNCTION: WinMain (standard WinMain INPUTS/RETURNS) ! 65: * ! 66: * COMMENTS: Register & create main window, loop for messages ! 67: * ! 68: \******************************************************************************/ ! 69: ! 70: int WINAPI WinMain (HANDLE ghInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, ! 71: int nCmdShow) ! 72: { ! 73: MSG msg; ! 74: ! 75: ghInst = ghInstance; ! 76: ! 77: if (!hPrevInstance) ! 78: { ! 79: WNDCLASS wc; ! 80: ! 81: wc.style = MAIN_CLASS_STYLE; ! 82: wc.lpfnWndProc = (WNDPROC) MainWndProc; ! 83: wc.cbClsExtra = 0; ! 84: wc.cbWndExtra = 0; ! 85: wc.hInstance = ghInst; ! 86: wc.hIcon = LoadIcon (ghInst, MAKEINTRESOURCE(MAIN_ICON)); ! 87: wc.hCursor = LoadCursor (NULL, IDC_ARROW); ! 88: wc.hbrBackground = NULL; ! 89: wc.lpszMenuName = (LPCSTR) MAIN_MENU_NAME; ! 90: wc.lpszClassName = (LPCSTR) MAIN_CLASS_NAME; ! 91: ! 92: if (!RegisterClass (&wc)) ! 93: { ! 94: MessageBox (NULL, "WinMain(): RegisterClass() failed", ! 95: ERR_MOD_NAME, MB_OK | MB_ICONHAND); ! 96: ! 97: return FALSE; ! 98: } ! 99: } ! 100: ! 101: if (!(ghwndMain = CreateWindow ((LPCSTR) MAIN_CLASS_NAME, ! 102: (LPCSTR) MAIN_WND_TITLE, ! 103: MAIN_WND_STYLE, ! 104: CW_USEDEFAULT, CW_USEDEFAULT, ! 105: CW_USEDEFAULT, CW_USEDEFAULT, ! 106: NULL, NULL, ghInst, NULL))) ! 107: return FALSE; ! 108: ! 109: ShowWindow (ghwndMain, nCmdShow); ! 110: ! 111: while (GetMessage (&msg, NULL, NULL, NULL)) ! 112: { ! 113: TranslateMessage (&msg); ! 114: DispatchMessage (&msg); ! 115: } ! 116: ! 117: return msg.wParam; ! 118: } ! 119: ! 120: ! 121: ! 122: /******************************************************************************\ ! 123: * ! 124: * FUNCTION: MainWndProc (standard window procedure INPUTS/RETURNS) ! 125: * ! 126: * COMMENTS: Handles main app window msg processing ! 127: * ! 128: \******************************************************************************/ ! 129: ! 130: LRESULT CALLBACK MainWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ! 131: { ! 132: static HMENU hMappingModesSubMenu; ! 133: static HMENU hGraphicsSubMenu; ! 134: static HMENU hPenWidthSubMenu; ! 135: static HMENU hPenStyleSubMenu; ! 136: static HMENU hBrushStyleSubMenu; ! 137: static HWND hwndCombobox; ! 138: static int iComboboxWidth; ! 139: static LONG lTextHeight; ! 140: ! 141: int i; ! 142: ! 143: switch (msg) ! 144: { ! 145: case WM_COMMAND: ! 146: ! 147: switch (LOWORD (wParam)) ! 148: { ! 149: case IDM_PRINT: ! 150: case IDM_PRINTDLG: ! 151: { ! 152: DWORD threadId; ! 153: ! 154: if (!CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) PrintThread, ! 155: (LPVOID) wParam, NULL, &threadId)) ! 156: ! 157: MessageBox (hwnd, ! 158: "MainWndProc(): Error creating print thread", ! 159: ERR_MOD_NAME, MB_OK | MB_ICONHAND); ! 160: break; ! 161: } ! 162: ! 163: case IDM_GETDEVICECAPS: ! 164: ! 165: DialogBox (ghInst, (LPCTSTR) "List", hwnd, ! 166: (DLGPROC) GetDeviceCapsDlgProc); ! 167: break; ! 168: ! 169: case IDM_ENUMPRINTERS: ! 170: ! 171: DialogBox (ghInst, (LPCTSTR) "List", hwnd, ! 172: (DLGPROC) EnumPrintersDlgProc); ! 173: break; ! 174: ! 175: case IDM_GETPRINTERDRIVER: ! 176: ! 177: if (strcmp (gszDeviceName, "Display")) ! 178: ! 179: DialogBox (ghInst, (LPCTSTR) "List", hwnd, ! 180: (DLGPROC) GetPrinterDriverDlgProc); ! 181: else ! 182: ! 183: MessageBox (hwnd, (LPCTSTR) "Please select a printer", ! 184: (LPCTSTR) "PRINTER.EXE:", MB_OK); ! 185: ! 186: break; ! 187: ! 188: case IDM_ENUMPRINTERDRIVERS: ! 189: ! 190: DialogBox (ghInst, (LPCTSTR) "List", hwnd, ! 191: (DLGPROC) EnumPrinterDriversDlgProc); ! 192: break; ! 193: ! 194: case IDM_REFRESH: ! 195: ! 196: RefreshPrinterCombobox (hwndCombobox); ! 197: break; ! 198: ! 199: case IDM_ABOUT: ! 200: ! 201: DialogBox (ghInst, (LPCTSTR) "About", hwnd, (DLGPROC) AboutDlgProc); ! 202: break; ! 203: ! 204: case IDM_HIENGLISH: ! 205: case IDM_HIMETRIC: ! 206: case IDM_LOENGLISH: ! 207: case IDM_LOMETRIC: ! 208: case IDM_TWIPS: ! 209: case IDM_ISOTROPIC: ! 210: case IDM_ANISOTROPIC: ! 211: case IDM_TEXT: ! 212: ! 213: // ! 214: // Uncheck the last map mode menuitem, check the new map mode ! 215: // menuitem, set iMappingMode according to menu id, cause a ! 216: // repaint ! 217: // ! 218: ! 219: for (i = 0; i < MAX_MAP_MODES; i++) ! 220: ! 221: if (giMapMode == gaMMLookup[i].iMapMode) ! 222: { ! 223: CheckMenuItem (hMappingModesSubMenu, gaMMLookup[i].wMenuItem, ! 224: MF_UNCHECKED | MF_BYCOMMAND); ! 225: break; ! 226: } ! 227: ! 228: CheckMenuItem (hMappingModesSubMenu, LOWORD (wParam), ! 229: MF_CHECKED | MF_BYCOMMAND); ! 230: ! 231: for (i = 0; i < MAX_MAP_MODES; i++) ! 232: ! 233: if (LOWORD (wParam) == gaMMLookup[i].wMenuItem) ! 234: { ! 235: giMapMode = gaMMLookup[i].iMapMode; ! 236: break; ! 237: } ! 238: ! 239: // ! 240: // invalidate the entire client so toolbar text gets updated ! 241: // ! 242: ! 243: InvalidateRect (hwnd, NULL, TRUE); ! 244: break; ! 245: ! 246: case IDM_ARC: ! 247: case IDM_ELLIPSE: ! 248: case IDM_LINETO: ! 249: case IDM_PIE: ! 250: case IDM_PLGBLT: ! 251: case IDM_POLYBEZIER: ! 252: case IDM_POLYGON: ! 253: case IDM_POLYLINE: ! 254: case IDM_POLYPOLYGON: ! 255: case IDM_RECTANGLE: ! 256: case IDM_ROUNDRECT: ! 257: case IDM_STRETCHBLT: ! 258: { ! 259: // ! 260: // Retrieve the DWORD flag value for the particular menuitem, ! 261: // toggle (un/check) the menuitem, set/clear the flag in ! 262: // gdwGraphicsOptions, cause a repaint ! 263: // ! 264: ! 265: DWORD dwGraphic; ! 266: ! 267: for (i = 0; i < MAX_GRAPHICS; i++) ! 268: ! 269: if (LOWORD (wParam) == gaGraphicLookup[i].wMenuItem) ! 270: { ! 271: dwGraphic = gaGraphicLookup[i].dwGraphic; ! 272: break; ! 273: } ! 274: ! 275: if (GetMenuState (hGraphicsSubMenu, LOWORD(wParam), MF_BYCOMMAND) ! 276: & MF_CHECKED) ! 277: ! 278: { ! 279: gdwGraphicsOptions &= ~dwGraphic; ! 280: CheckMenuItem (hGraphicsSubMenu, LOWORD(wParam), ! 281: MF_UNCHECKED | MF_BYCOMMAND); ! 282: } ! 283: else ! 284: { ! 285: // ! 286: // Clear/uncheck the ENUMFONTS flag/menuitem ! 287: // ! 288: ! 289: gdwGraphicsOptions &= ~ENUMFONTS; ! 290: CheckMenuItem (hGraphicsSubMenu, IDM_ENUMFONTS, ! 291: MF_UNCHECKED | MF_BYCOMMAND); ! 292: ! 293: gdwGraphicsOptions |= dwGraphic; ! 294: CheckMenuItem (hGraphicsSubMenu, LOWORD(wParam), ! 295: MF_CHECKED | MF_BYCOMMAND); ! 296: } ! 297: InvalidateClient (); ! 298: break; ! 299: } ! 300: ! 301: case IDM_ALLGRAPHICS: ! 302: ! 303: // ! 304: // Clear/uncheck the ENUMFONTS flag/menuitem, set/check all ! 305: // other graphics flags/menuitems, cause a repaint ! 306: // ! 307: ! 308: CheckMenuItem (hGraphicsSubMenu, IDM_ENUMFONTS, ! 309: MF_UNCHECKED | MF_BYCOMMAND); ! 310: ! 311: for (i = 0; i < MAX_GRAPHICS; i++) ! 312: ! 313: CheckMenuItem (hGraphicsSubMenu, IDM_ARC + i, ! 314: MF_CHECKED | MF_BYCOMMAND); ! 315: ! 316: gdwGraphicsOptions = ALLGRAPHICS | (gdwGraphicsOptions & DRAWAXIS); ! 317: ! 318: InvalidateClient (); ! 319: break; ! 320: ! 321: case IDM_NOGRAPHICS: ! 322: ! 323: // ! 324: // Clear/uncheck all graphics flags/menuitems, cause a repaint ! 325: // ! 326: ! 327: for (i = 0; i < MAX_GRAPHICS; i++) ! 328: ! 329: CheckMenuItem (hGraphicsSubMenu, IDM_ARC + i, ! 330: MF_UNCHECKED | MF_BYCOMMAND); ! 331: ! 332: gdwGraphicsOptions &= (DRAWAXIS | ENUMFONTS); ! 333: ! 334: InvalidateClient (); ! 335: break; ! 336: ! 337: case IDM_ENUMFONTS: ! 338: ! 339: // ! 340: // Set/clear ENUMFONTS flag, toggle (un/check) menuitem, if ! 341: // checking IDM_ENUMFONTS then uncheck all other items, ! 342: // cause a repaint ! 343: // ! 344: ! 345: if (GetMenuState (hGraphicsSubMenu, IDM_ENUMFONTS, MF_BYCOMMAND) ! 346: & MF_CHECKED) ! 347: { ! 348: gdwGraphicsOptions &= DRAWAXIS; ! 349: ! 350: CheckMenuItem (hGraphicsSubMenu, IDM_ENUMFONTS, ! 351: MF_UNCHECKED | MF_BYCOMMAND); ! 352: } ! 353: ! 354: else ! 355: { ! 356: SendMessage (hwnd, WM_COMMAND, IDM_NOGRAPHICS, 0); ! 357: ! 358: gdwGraphicsOptions = ENUMFONTS | (gdwGraphicsOptions & DRAWAXIS); ! 359: ! 360: CheckMenuItem (hGraphicsSubMenu, IDM_ENUMFONTS, ! 361: MF_CHECKED | MF_BYCOMMAND); ! 362: } ! 363: InvalidateClient (); ! 364: break; ! 365: ! 366: case IDM_DRAWAXIS: ! 367: ! 368: // ! 369: // Set/clear DRAWAXIS flag, toggle (un/check) menuitem, ! 370: // cause a repaint ! 371: // ! 372: ! 373: if (GetMenuState (hGraphicsSubMenu, IDM_DRAWAXIS, MF_BYCOMMAND) ! 374: & MF_CHECKED) ! 375: { ! 376: gdwGraphicsOptions &= ~DRAWAXIS; ! 377: ! 378: CheckMenuItem (hGraphicsSubMenu, IDM_DRAWAXIS, ! 379: MF_UNCHECKED | MF_BYCOMMAND); ! 380: } ! 381: ! 382: else ! 383: { ! 384: gdwGraphicsOptions |= DRAWAXIS; ! 385: ! 386: CheckMenuItem (hGraphicsSubMenu, IDM_DRAWAXIS, ! 387: MF_CHECKED | MF_BYCOMMAND); ! 388: } ! 389: InvalidateClient (); ! 390: break; ! 391: ! 392: case IDM_SETPENCOLOR: ! 393: case IDM_SETBRUSHCOLOR: ! 394: case IDM_TEXTCOLOR: ! 395: { ! 396: CHOOSECOLOR cc; ! 397: ! 398: static DWORD adwCustColors[16]; ! 399: ! 400: memset (&cc, 0, sizeof (CHOOSECOLOR)); ! 401: ! 402: cc.lStructSize = sizeof (CHOOSECOLOR); ! 403: cc.hwndOwner = hwnd; ! 404: cc.Flags = CC_RGBINIT; ! 405: cc.lpCustColors = adwCustColors; ! 406: ! 407: if (LOWORD (wParam) == IDM_SETPENCOLOR) ! 408: ! 409: cc.rgbResult = gdwPenColor; ! 410: ! 411: else if (LOWORD (wParam) == IDM_SETBRUSHCOLOR) ! 412: ! 413: cc.rgbResult = gdwBrushColor; ! 414: ! 415: else ! 416: ! 417: cc.rgbResult = gdwTextColor; ! 418: ! 419: // ! 420: // bring up choose color common dialog ! 421: // ! 422: ! 423: ChooseColor (&cc); ! 424: ! 425: if (LOWORD (wParam) == IDM_SETPENCOLOR) ! 426: ! 427: gdwPenColor = cc.rgbResult; ! 428: ! 429: else if (LOWORD (wParam) == IDM_SETBRUSHCOLOR) ! 430: ! 431: gdwBrushColor = cc.rgbResult; ! 432: ! 433: else ! 434: ! 435: gdwTextColor = cc.rgbResult; ! 436: ! 437: InvalidateClient (); ! 438: break; ! 439: } ! 440: ! 441: case IDM_PENWIDTH_1: ! 442: case IDM_PENWIDTH_2: ! 443: case IDM_PENWIDTH_3: ! 444: case IDM_PENWIDTH_4: ! 445: case IDM_PENWIDTH_5: ! 446: case IDM_PENWIDTH_6: ! 447: case IDM_PENWIDTH_7: ! 448: case IDM_PENWIDTH_8: ! 449: ! 450: // ! 451: // uncheck old pen width menuitem, check new one, cause a repaint ! 452: // ! 453: ! 454: for (i = 0; i < MAX_PENWIDTHS; i++) ! 455: ! 456: if (giPenWidth == gaPenWidths[i].iPenWidth) ! 457: { ! 458: CheckMenuItem (hPenWidthSubMenu, gaPenWidths[i].wMenuItem, ! 459: MF_UNCHECKED | MF_BYCOMMAND); ! 460: break; ! 461: } ! 462: ! 463: for (i = 0; i < MAX_PENWIDTHS; i++) ! 464: ! 465: if (LOWORD(wParam) == gaPenWidths[i].wMenuItem) ! 466: { ! 467: CheckMenuItem (hPenWidthSubMenu, gaPenWidths[i].wMenuItem, ! 468: MF_CHECKED | MF_BYCOMMAND); ! 469: ! 470: giPenWidth = gaPenWidths[i].iPenWidth; ! 471: ! 472: break; ! 473: } ! 474: ! 475: InvalidateClient (); ! 476: break; ! 477: ! 478: case IDM_PENCOLOR_SOLID: ! 479: case IDM_PENCOLOR_DASH: ! 480: case IDM_PENCOLOR_DOT: ! 481: case IDM_PENCOLOR_DASHDOT: ! 482: case IDM_PENCOLOR_DASHDOTDOT: ! 483: case IDM_PENCOLOR_NULL: ! 484: case IDM_PENCOLOR_INSIDEFRAME: ! 485: ! 486: // ! 487: // uncheck old pen style menuitem, check new one, cause a repaint ! 488: // ! 489: ! 490: for (i = 0; i < MAX_PENSTYLES; i++) ! 491: ! 492: if (giPenStyle == gaPenStyles[i].iPenStyle) ! 493: { ! 494: CheckMenuItem (hPenStyleSubMenu, gaPenStyles[i].wMenuItem, ! 495: MF_UNCHECKED | MF_BYCOMMAND); ! 496: break; ! 497: } ! 498: ! 499: for (i = 0; i < MAX_PENSTYLES; i++) ! 500: ! 501: if (LOWORD(wParam) == gaPenStyles[i].wMenuItem) ! 502: { ! 503: CheckMenuItem (hPenStyleSubMenu, gaPenStyles[i].wMenuItem, ! 504: MF_CHECKED | MF_BYCOMMAND); ! 505: ! 506: giPenStyle = gaPenStyles[i].iPenStyle; ! 507: ! 508: break; ! 509: } ! 510: ! 511: InvalidateClient (); ! 512: break; ! 513: ! 514: case IDM_BRUSHSTYLE_SOLID: ! 515: case IDM_BRUSHSTYLE_BDIAGONAL: ! 516: case IDM_BRUSHSTYLE_CROSS: ! 517: case IDM_BRUSHSTYLE_DIAGCROSS: ! 518: case IDM_BRUSHSTYLE_FDIAGONAL: ! 519: case IDM_BRUSHSTYLE_HORIZONTAL: ! 520: case IDM_BRUSHSTYLE_VERTICAL: ! 521: case IDM_BRUSHSTYLE_FDIAGONAL1: ! 522: case IDM_BRUSHSTYLE_BDIAGONAL1: ! 523: case IDM_BRUSHSTYLE_DENSE1: ! 524: case IDM_BRUSHSTYLE_DENSE2: ! 525: case IDM_BRUSHSTYLE_DENSE3: ! 526: case IDM_BRUSHSTYLE_DENSE4: ! 527: case IDM_BRUSHSTYLE_DENSE5: ! 528: case IDM_BRUSHSTYLE_DENSE6: ! 529: case IDM_BRUSHSTYLE_DENSE7: ! 530: case IDM_BRUSHSTYLE_DENSE8: ! 531: case IDM_BRUSHSTYLE_NOSHADE: ! 532: case IDM_BRUSHSTYLE_HALFTONE: ! 533: ! 534: // ! 535: // uncheck old brush style menuitem, check new one, cause a repaint ! 536: // ! 537: ! 538: for (i = 0; i < MAX_BRUSHSTYLES; i++) ! 539: ! 540: if (giBrushStyle == gaBrushStyles[i].iBrushStyle) ! 541: { ! 542: CheckMenuItem (hBrushStyleSubMenu, gaBrushStyles[i].wMenuItem, ! 543: MF_UNCHECKED | MF_BYCOMMAND); ! 544: break; ! 545: } ! 546: ! 547: for (i = 0; i < MAX_BRUSHSTYLES; i++) ! 548: ! 549: if (LOWORD(wParam) == gaBrushStyles[i].wMenuItem) ! 550: { ! 551: CheckMenuItem (hBrushStyleSubMenu, gaBrushStyles[i].wMenuItem, ! 552: MF_CHECKED | MF_BYCOMMAND); ! 553: ! 554: giBrushStyle = gaBrushStyles[i].iBrushStyle; ! 555: ! 556: break; ! 557: } ! 558: ! 559: InvalidateClient (); ! 560: break; ! 561: ! 562: case ID_COMBOBOX: ! 563: ! 564: switch (HIWORD(wParam)) ! 565: { ! 566: case CBN_SELCHANGE: ! 567: { ! 568: DWORD dwIndex; ! 569: char buf[BUFSIZE]; ! 570: ! 571: // ! 572: // User clicked on one of the items in the toolbar combobox; ! 573: // figure out which item, then parse the text apart and ! 574: // copy it to the gszDriverName, gszDeviceName, and gszPort ! 575: // variables. ! 576: // ! 577: ! 578: dwIndex = (DWORD) SendMessage ((HWND) lParam, ! 579: CB_GETCURSEL, 0, 0); ! 580: SendMessage ((HWND) lParam, CB_GETLBTEXT, dwIndex, ! 581: (LONG) buf); ! 582: ! 583: if (!strcmp (buf, "Display")) ! 584: { ! 585: strcpy (gszDeviceName, "Display"); ! 586: ! 587: gszPort[0] = ! 588: gszDriverName[0] = '\0'; ! 589: } ! 590: else ! 591: { int j = 0; ! 592: ! 593: i = -1; ! 594: ! 595: while (buf[++i] != ';') gszDeviceName[i] = buf[i]; ! 596: gszDeviceName[i] = '\0'; ! 597: while (buf[++i] != ';') gszPort[j++] = buf[i]; ! 598: gszPort[j] = '\0'; ! 599: j = 0; ! 600: while (buf[++i] != '\0') gszDriverName[j++] = buf[i]; ! 601: gszDriverName[j] = '\0'; ! 602: } ! 603: break; ! 604: } ! 605: } ! 606: break; ! 607: } ! 608: break; ! 609: ! 610: case WM_PAINT: ! 611: { ! 612: PAINTSTRUCT ps; ! 613: RECT rect; ! 614: HRGN hrgn; ! 615: HPEN hpen, hpenSave; ! 616: HBRUSH hbr; ! 617: char buf[BUFSIZE]; ! 618: POINT p; ! 619: ! 620: BeginPaint (hwnd, &ps); ! 621: ! 622: // ! 623: // paint 3d toolbar background & client size text ! 624: // ! 625: ! 626: GetClientRect (hwnd, &rect); ! 627: rect.bottom = 2*glcyMenu; ! 628: FillRect (ps.hdc, &rect, GetStockObject (LTGRAY_BRUSH)); ! 629: SelectObject (ps.hdc, GetStockObject (WHITE_PEN)); ! 630: MoveToEx (ps.hdc, 0, 2*glcyMenu - 2, NULL); ! 631: LineTo (ps.hdc, 0, 0); ! 632: LineTo (ps.hdc, (int) rect.right, 0); ! 633: hpen = CreatePen (PS_SOLID, 1, 0x808080); ! 634: hpenSave = SelectObject (ps.hdc, hpen); ! 635: MoveToEx (ps.hdc, 0, (int) 2*glcyMenu-1, NULL); ! 636: LineTo (ps.hdc, (int) rect.right - 1, (int) 2*glcyMenu-1); ! 637: LineTo (ps.hdc, (int) rect.right - 1, 1); ! 638: SelectObject (ps.hdc, hpenSave); ! 639: DeleteObject (hpen); ! 640: ! 641: GetClientRect (hwnd, &rect); ! 642: ! 643: // ! 644: // positioning of the string based upon x,y,cx,cy of combobox ! 645: // ! 646: ! 647: SetBkMode (ps.hdc, TRANSPARENT); ! 648: ! 649: p.x = rect.right; ! 650: p.y = (rect.bottom - 2*glcyMenu < 0 ? 0 : rect.bottom - 2*glcyMenu); ! 651: SetMapMode (ps.hdc, giMapMode); ! 652: DPtoLP (ps.hdc, &p, 1); ! 653: ! 654: if (giMapMode != MM_TEXT && giMapMode != MM_ANISOTROPIC) ! 655: ! 656: // ! 657: // p.y will come out negative because we started with origin in ! 658: // upper left corner ! 659: // ! 660: ! 661: p.y = -p.y; ! 662: ! 663: SetMapMode (ps.hdc, MM_TEXT); ! 664: sprintf (buf, "cxClient = %ld (%ld)", rect.right, p.x); ! 665: TextOut (ps.hdc, iComboboxWidth + (int) 3*glcyMenu/2, (int) glcyMenu/8, ! 666: buf, strlen (buf)); ! 667: sprintf (buf, "cyClient = %ld (%ld)", ! 668: rect.bottom - 2*glcyMenu < 0 ? 0 : rect.bottom - 2*glcyMenu, ! 669: p.y); ! 670: TextOut (ps.hdc, iComboboxWidth + (int) 3*glcyMenu/2, ! 671: (int) (glcyMenu/8 + lTextHeight), ! 672: buf, strlen (buf)); ! 673: ! 674: // ! 675: // paint graphics background white ! 676: // ! 677: ! 678: rect.top += 2*glcyMenu; ! 679: FillRect (ps.hdc, &rect, GetStockObject (WHITE_BRUSH)); ! 680: ! 681: ! 682: if (rect.bottom <= 4*glcyMenu) ! 683: ! 684: // ! 685: // we don't want to overpaint the toolbar, so just skip Paint() call ! 686: // ! 687: ! 688: goto done_painting; ! 689: ! 690: // ! 691: // set up a clip region so we don't draw all over our toolbar ! 692: // ! 693: ! 694: GetClientRect (hwnd, &rect); ! 695: rect.top += 2*glcyMenu; ! 696: hrgn = CreateRectRgnIndirect (&rect); ! 697: SelectClipRgn (ps.hdc, hrgn); ! 698: DeleteObject (hrgn); ! 699: ! 700: // ! 701: // set up view port, pens/brushes, & map mode, then paint ! 702: // ! 703: ! 704: rect.top -= 2*glcyMenu; ! 705: ! 706: if (giMapMode == MM_TEXT || giMapMode == MM_ANISOTROPIC) ! 707: ! 708: SetViewportOrgEx (ps.hdc, glcyMenu, 3*glcyMenu, NULL); ! 709: ! 710: else ! 711: ! 712: SetViewportOrgEx (ps.hdc, glcyMenu, rect.bottom - glcyMenu, NULL); ! 713: ! 714: rect.bottom -= 4*glcyMenu; ! 715: rect.right -= 2*glcyMenu; ! 716: ! 717: hpen = CreatePen (giPenStyle, giPenWidth, gdwPenColor); ! 718: SelectObject (ps.hdc, hpen); ! 719: hbr = CreateHatchBrush (giBrushStyle, gdwBrushColor); ! 720: SelectObject (ps.hdc, hbr); ! 721: ! 722: SetTextColor (ps.hdc, gdwTextColor); ! 723: ! 724: SetMapMode (ps.hdc, giMapMode); ! 725: Paint (ps.hdc, &rect); ! 726: ! 727: DeleteObject (hpen); ! 728: DeleteObject (hbr); ! 729: ! 730: done_painting: ! 731: ! 732: EndPaint (hwnd, &ps); ! 733: break; ! 734: } ! 735: ! 736: case WM_CREATE: ! 737: { ! 738: HDC hdc; ! 739: TEXTMETRIC tm; ! 740: SIZE size; ! 741: HMENU hmenu, hPenSubMenu, hBrushSubMenu; ! 742: ! 743: // ! 744: // initialize the globals ! 745: // ! 746: ! 747: glcyMenu = (LONG) GetSystemMetrics (SM_CYMENU); ! 748: ! 749: hmenu = GetMenu (hwnd); ! 750: hMappingModesSubMenu = GetSubMenu (hmenu, 1); ! 751: hGraphicsSubMenu = GetSubMenu (hmenu, 2); ! 752: hPenSubMenu = GetSubMenu (hmenu, 3); ! 753: hPenWidthSubMenu = GetSubMenu (hPenSubMenu, 1); ! 754: hPenStyleSubMenu = GetSubMenu (hPenSubMenu, 2); ! 755: hBrushSubMenu = GetSubMenu (hmenu, 4); ! 756: hBrushStyleSubMenu = GetSubMenu (hBrushSubMenu, 1); ! 757: ! 758: GetTextMetrics ((hdc = GetDC (hwnd)), &tm); ! 759: lTextHeight = tm.tmHeight; ! 760: ! 761: // ! 762: // create combobox to display current printers in. the width ! 763: // is caluculated by getting the text extent of a typical ! 764: // entry in the listbox. ! 765: // ! 766: ! 767: ! 768: #define ASTRING "long printer name;long port name;long driver name" ! 769: ! 770: GetTextExtentPoint (hdc, ASTRING, sizeof (ASTRING), &size); ! 771: ! 772: iComboboxWidth = (int) size.cx; ! 773: ! 774: ReleaseDC (hwnd, hdc); ! 775: ! 776: hwndCombobox = CreateWindow ((LPCSTR) "COMBOBOX", (LPCSTR) "", ! 777: WS_CHILD | WS_VISIBLE | CBS_DROPDOWN, ! 778: (int) glcyMenu/2, ! 779: (int) glcyMenu/2 - 2, // - 2 = fudge factor ! 780: iComboboxWidth, ! 781: (int) 6*glcyMenu, ! 782: hwnd, NULL, ghInst, NULL); ! 783: ! 784: SetWindowLong (hwndCombobox, GWL_ID, ID_COMBOBOX); ! 785: ! 786: PostMessage (hwnd, WM_COMMAND, ! 787: (WPARAM) MAKELONG (IDM_REFRESH, 0), ! 788: (LPARAM) 0); ! 789: PostMessage (hwnd, WM_COMMAND, ! 790: (WPARAM) MAKELONG (IDM_POLYPOLYGON, 0), ! 791: (LPARAM) 0); ! 792: break; ! 793: } ! 794: ! 795: case WM_DESTROY: ! 796: ! 797: PostQuitMessage (NULL); ! 798: break; ! 799: ! 800: default: ! 801: ! 802: return (DefWindowProc (hwnd, msg, wParam, lParam)); ! 803: } ! 804: return 0; ! 805: } ! 806: ! 807: ! 808: ! 809: /******************************************************************************\ ! 810: * ! 811: * FUNCTION: AboutDlgProc (standard dialog procedure INPUTS/RETURNS) ! 812: * ! 813: * COMMENTS: Handles "About" dialog messages ! 814: * ! 815: \******************************************************************************/ ! 816: ! 817: LRESULT CALLBACK AboutDlgProc (HWND hwnd, UINT msg, WPARAM wParam, ! 818: LPARAM lParam) ! 819: { ! 820: switch (msg) ! 821: { ! 822: case WM_INITDIALOG: ! 823: ! 824: return TRUE; ! 825: ! 826: case WM_COMMAND: ! 827: ! 828: switch (LOWORD (wParam)) ! 829: { ! 830: case IDOK: ! 831: ! 832: EndDialog (hwnd, TRUE); ! 833: ! 834: return 1; ! 835: } ! 836: break; ! 837: } ! 838: return 0; ! 839: } ! 840: ! 841: ! 842: ! 843: /******************************************************************************\ ! 844: * ! 845: * FUNCTION: InvalidateClient ! 846: * ! 847: * COMMENTS: Eliminates the flashing of the toolbar when we redraw ! 848: * ! 849: \******************************************************************************/ ! 850: ! 851: void InvalidateClient () ! 852: { ! 853: RECT rect; ! 854: ! 855: GetClientRect (ghwndMain, &rect); ! 856: ! 857: rect.top += 2*glcyMenu; ! 858: ! 859: InvalidateRect (ghwndMain, &rect, TRUE); ! 860: } ! 861: ! 862: ! 863: ! 864: /******************************************************************************\ ! 865: * ! 866: * FUNCTION: RefreshPrinterCombobox ! 867: * ! 868: * INPUTS: hwndCombobox- handle of the toolbar combobox ! 869: * ! 870: * COMMENTS: The idea here is to enumerate all printers & list them in ! 871: * then combobox in the form: "DEVICE_NAME;PORT;DRIVER_NAME". ! 872: * Then later, when a user selects one of these, we just ! 873: * query out the string & parse it apart, sticking the ! 874: * appropriate parts into the DriverName, DeviceName, and ! 875: * Port variables. ! 876: * ! 877: * Also, the "Display" option is added to the combobox so ! 878: * that user can get DevCaps info about it. ! 879: * ! 880: \******************************************************************************/ ! 881: ! 882: void RefreshPrinterCombobox (HWND hwndCombobox) ! 883: { ! 884: DWORD dwFlags = PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL; ! 885: LPPRINTER_INFO_2 pPrinters; ! 886: DWORD cbPrinters; ! 887: DWORD cReturned, i; ! 888: char buf[256]; ! 889: ! 890: SendMessage (hwndCombobox, CB_RESETCONTENT, 0, 0); ! 891: ! 892: // ! 893: // add the "Display" option to the combobox ! 894: // ! 895: ! 896: strcpy (buf, "Display"); ! 897: SendMessage (hwndCombobox, CB_INSERTSTRING, (UINT)-1, (LONG) buf); ! 898: ! 899: // ! 900: // get byte count needed for buffer, alloc buffer, the enum the printers ! 901: // ! 902: ! 903: EnumPrinters (dwFlags, NULL, 2, NULL, 0, &cbPrinters, ! 904: &cReturned); ! 905: ! 906: if (!(pPrinters = (LPPRINTER_INFO_2) LocalAlloc (LPTR, cbPrinters + 4))) ! 907: { ! 908: MessageBox (ghwndMain, (LPCTSTR) "LocalAlloc failed", ! 909: (LPCTSTR) ERR_MOD_NAME, MB_OK | MB_ICONEXCLAMATION); ! 910: goto done_refreshing; ! 911: } ! 912: ! 913: ! 914: if (!EnumPrinters (dwFlags, NULL, 2, (LPBYTE) pPrinters, ! 915: cbPrinters, &cbPrinters, &cReturned)) ! 916: { ! 917: MessageBox (ghwndMain, (LPCTSTR) "EnumPrinters failed", ! 918: (LPCTSTR) ERR_MOD_NAME, MB_OK | MB_ICONEXCLAMATION); ! 919: goto done_refreshing; ! 920: } ! 921: ! 922: if (cReturned > 0) ! 923: ! 924: for (i = 0; i < cReturned; i++) ! 925: { ! 926: // ! 927: // for each printer in the PRINTER_INFO_2 array: build a string that ! 928: // looks like "DEVICE_NAME;PORT;DRIVER_NAME" ! 929: // ! 930: ! 931: strcpy (buf, (pPrinters + i)->pPrinterName); ! 932: strcat (buf, ";"); ! 933: strcat (buf, (pPrinters + i)->pPortName); ! 934: strcat (buf, ";"); ! 935: strcat (buf, (pPrinters + i)->pDriverName); ! 936: ! 937: SendMessage (hwndCombobox, CB_INSERTSTRING, (UINT)-1, (LONG) buf); ! 938: } ! 939: ! 940: else ! 941: ! 942: MessageBox (ghwndMain, "No printers listed", "PRINTER.EXE", MB_OK); ! 943: ! 944: done_refreshing: ! 945: ! 946: SendMessage (hwndCombobox, CB_SELECTSTRING, (UINT) -1, (LONG) buf); ! 947: ! 948: PostMessage (ghwndMain, WM_COMMAND, ! 949: (WPARAM) MAKELONG (ID_COMBOBOX, CBN_SELCHANGE), ! 950: (LPARAM) hwndCombobox); ! 951: ! 952: LocalFree (LocalHandle (pPrinters)); ! 953: } ! 954: ! 955: ! 956: ! 957: /******************************************************************************\ ! 958: * ! 959: * FUNCTION: PrintThread ! 960: * ! 961: * INPUTS: wParam - wParam of a WM_COMMAND message containing menuitem id ! 962: * ! 963: * COMMENTS: This is the code for the print thread created when the user ! 964: * selects the "Print" or "PrintDlg" menuitems. A thread is used ! 965: * here more demostration purposes only, since we really don't ! 966: * have any background processing to do. A real app would want ! 967: * to have alot more error checking here (e.g. check return of ! 968: * StartDoc, StartPage...). ! 969: * ! 970: \******************************************************************************/ ! 971: ! 972: void PrintThread (LPVOID wParam) ! 973: { ! 974: DOCINFO di; ! 975: RECT rect; ! 976: HPEN hpen; ! 977: HBRUSH hbr; ! 978: ! 979: switch (LOWORD((WPARAM) wParam)) ! 980: { ! 981: case IDM_PRINT: ! 982: { ! 983: if (!strcmp (gszDeviceName, "Display")) ! 984: { ! 985: MessageBox (ghwndMain, "Please select a printer", ! 986: "PRINTER.EXE:", MB_OK); ! 987: return; ! 988: } ! 989: else if (!(ghdc = CreateDC (gszDriverName, gszDeviceName, gszPort, NULL))) ! 990: { ! 991: MessageBox (ghwndMain, "PrintThread(): CreateDC() failed", ! 992: ERR_MOD_NAME, MB_OK); ! 993: return; ! 994: } ! 995: break; ! 996: } ! 997: ! 998: case IDM_PRINTDLG: ! 999: { ! 1000: PRINTDLG pd; ! 1001: ! 1002: // ! 1003: // Initialize a PRINTDLG struct and call PrintDlg to allow user to ! 1004: // specify various printing options... ! 1005: // ! 1006: ! 1007: memset (&pd, 0, sizeof(PRINTDLG)); ! 1008: ! 1009: pd.lStructSize = sizeof(PRINTDLG); ! 1010: pd.hwndOwner = ghwndMain; ! 1011: pd.Flags = PD_RETURNDC; ! 1012: pd.hInstance = NULL; ! 1013: ! 1014: PrintDlg(&pd); ! 1015: ghdc = pd.hDC; ! 1016: ! 1017: if (pd.hDevMode) ! 1018: ! 1019: GlobalFree (pd.hDevMode); ! 1020: ! 1021: if (pd.hDevNames) ! 1022: ! 1023: GlobalFree (pd.hDevNames); ! 1024: ! 1025: if (!ghdc) ! 1026: { ! 1027: MessageBox (ghwndMain, "PrintDlg (PD_RETURNDC) failed", ! 1028: ERR_MOD_NAME, MB_OK); ! 1029: return; ! 1030: } ! 1031: } ! 1032: } ! 1033: ! 1034: // ! 1035: // put up Abort & install the abort procedure ! 1036: // ! 1037: ! 1038: gbAbort = FALSE; ! 1039: ghwndAbort = CreateDialog (ghInst, (LPCTSTR) "Abort", ghwndMain, ! 1040: (DLGPROC) AbortDlgProc); ! 1041: EnableWindow (ghwndMain, FALSE); ! 1042: SetAbortProc (ghdc, AbortProc); ! 1043: ! 1044: // ! 1045: // create & select pen/brush ! 1046: // ! 1047: ! 1048: hpen = CreatePen (giPenStyle, giPenWidth, gdwPenColor); ! 1049: SelectObject (ghdc, hpen); ! 1050: hbr = CreateHatchBrush (giBrushStyle, gdwBrushColor); ! 1051: SelectObject (ghdc, hbr); ! 1052: ! 1053: SetTextColor (ghdc, gdwTextColor); ! 1054: ! 1055: SetMapMode (ghdc, giMapMode); ! 1056: rect.top = ! 1057: rect.left = 0; ! 1058: rect.right = GetDeviceCaps (ghdc, HORZRES); ! 1059: rect.bottom = GetDeviceCaps (ghdc, VERTRES); ! 1060: di.cbSize = sizeof(DOCINFO); ! 1061: di.lpszDocName = "print test"; ! 1062: di.lpszOutput = NULL; ! 1063: ! 1064: StartDoc (ghdc, &di); ! 1065: StartPage (ghdc); ! 1066: ! 1067: if (gdwGraphicsOptions) ! 1068: ! 1069: Paint (ghdc, &rect); ! 1070: ! 1071: else ! 1072: ! 1073: TextOut (ghdc, 5, 5, (LPCTSTR) "A blank page!", sizeof("A blank page!")); ! 1074: ! 1075: EndPage (ghdc); ! 1076: EndDoc (ghdc); ! 1077: DeleteDC (ghdc); ! 1078: ! 1079: if (!gbAbort) ! 1080: { ! 1081: EnableWindow (ghwndMain, TRUE); ! 1082: DestroyWindow (ghwndAbort); ! 1083: } ! 1084: } ! 1085: ! 1086: ! 1087: ! 1088: /******************************************************************************\ ! 1089: * ! 1090: * FUNCTION: AbortProc ! 1091: * ! 1092: * COMMENTS: Standard printing abort proc ! 1093: * ! 1094: \******************************************************************************/ ! 1095: ! 1096: BOOL CALLBACK AbortProc (HDC hdc, int error) ! 1097: { ! 1098: MSG msg; ! 1099: ! 1100: while (!gbAbort && PeekMessage (&msg, NULL, NULL, NULL, PM_REMOVE)) ! 1101: ! 1102: if (!ghwndAbort || !IsDialogMessage (ghwndAbort, &msg)) ! 1103: { ! 1104: TranslateMessage (&msg); ! 1105: DispatchMessage (&msg); ! 1106: } ! 1107: ! 1108: return !gbAbort; ! 1109: } ! 1110: ! 1111: ! 1112: ! 1113: /******************************************************************************\ ! 1114: * ! 1115: * FUNCTION: AbortDlgProc (standard dialog procedure INPUTS/RETURNS) ! 1116: * ! 1117: * COMMENTS: Handles "Abort" dialog messages ! 1118: * ! 1119: \******************************************************************************/ ! 1120: ! 1121: LRESULT CALLBACK AbortDlgProc (HWND hwnd, UINT msg, WPARAM wParam, ! 1122: LPARAM lParam) ! 1123: { ! 1124: switch (msg) ! 1125: { ! 1126: case WM_INITDIALOG: ! 1127: ! 1128: ghwndAbort = hwnd; ! 1129: EnableMenuItem (GetSystemMenu (hwnd, FALSE), SC_CLOSE, MF_GRAYED); ! 1130: break; ! 1131: ! 1132: case WM_COMMAND: ! 1133: ! 1134: switch (LOWORD (wParam)) ! 1135: { ! 1136: case DID_CANCEL: ! 1137: ! 1138: gbAbort = TRUE; ! 1139: AbortDoc (ghdc); ! 1140: EnableWindow (ghwndMain, TRUE); ! 1141: DestroyWindow (hwnd); ! 1142: return TRUE; ! 1143: } ! 1144: break; ! 1145: } ! 1146: return 0; ! 1147: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.