Annotation of mstools/samples/printer/printer.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.