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