home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_17 / Printer / Printer.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-24  |  19.2 KB  |  761 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : printer.cpp                                                         //
  10. //  Description: Printer demo program, Chapter 17                                    //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define _WIN32_WINNT 0x0500
  16. #define NOCRYPT
  17.  
  18. #pragma pack(push, 4)
  19. #include <windows.h>
  20. #pragma pack(pop)
  21.  
  22. #include <assert.h>
  23. #include <tchar.h>
  24. #include <math.h>
  25. #include <stdio.h>
  26.  
  27. #include "..\..\include\win.h"
  28. #include "..\..\include\dialog.h"
  29. #include "..\..\include\Toolbar.h"
  30. #include "..\..\include\Status.h"
  31. #include "..\..\include\FrameWnd.h"
  32. #include "..\..\include\GDIObject.h"
  33. #include "..\..\include\pen.h"
  34. #include "..\..\include\filedialog.h"
  35. #include "..\..\include\outputsetup.h"
  36. #include "..\..\include\fonttext.h"
  37. #include "..\..\include\pagecanvas.h"
  38. #include "..\..\include\areafill.h"
  39.  
  40. #include "resource.h"
  41.  
  42. //////////////////////////////////////////////////////////////
  43.  
  44. int nCall_AbortProc;
  45.  
  46. BOOL CALLBACK SimpleAbortProc(HDC hDC, int iError)
  47. {
  48.     nCall_AbortProc ++;
  49.  
  50.     return TRUE;
  51. }
  52.  
  53. void SimplePrint(int nPages)
  54. {
  55.     TCHAR temp[MAX_PATH];
  56.  
  57.     DWORD size = MAX_PATH;
  58.     GetDefaultPrinter(temp, & size); // default printer name
  59.  
  60.     HDC hDC = CreateDC(NULL, temp, NULL, NULL); // DC with default setting
  61.     
  62.     if ( hDC )
  63.     {
  64.         nCall_AbortProc = 0;
  65.         SetAbortProc(hDC, SimpleAbortProc);
  66.  
  67.         DOCINFO docinfo;
  68.         docinfo.cbSize       = sizeof(docinfo);
  69.         docinfo.lpszDocName  = _T("SimplePrint");
  70.         docinfo.lpszOutput   = NULL; 
  71.         docinfo.lpszDatatype = _T("EMF");
  72.         docinfo.fwType         = 0; 
  73.  
  74.         if ( StartDoc(hDC, & docinfo) > 0 )
  75.         {
  76.             for (int p=0; p<nPages; p++) // one page at a time
  77.                 if ( StartPage(hDC) <= 0 )
  78.                     break;
  79.                 else
  80.                 {
  81.                     int width  = GetDeviceCaps(hDC, HORZRES);
  82.                     int height = GetDeviceCaps(hDC, VERTRES);
  83.                     int dpix   = GetDeviceCaps(hDC, LOGPIXELSX);
  84.                     int dpiy   = GetDeviceCaps(hDC, LOGPIXELSY);
  85.             
  86.                     wsprintf(temp, _T("Page %d of %d"), p+1, nPages);
  87.                     SetTextAlign(hDC, TA_TOP | TA_RIGHT );
  88.                     TextOut(hDC, width, 0, temp, _tcslen(temp));
  89.  
  90.                     Rectangle(hDC, 0, 0, dpix, dpiy);
  91.                     Rectangle(hDC, width, height, width-dpix, height-dpiy);
  92.                 
  93.                     if ( EndPage(hDC)<0 )
  94.                         break;
  95.                 }
  96.             
  97.             EndDoc(hDC);
  98.         }
  99.  
  100.         DeleteDC(hDC);
  101.     }
  102.  
  103.     wsprintf(temp, "AbortProc called %d times", nCall_AbortProc);
  104.     MessageBox(NULL, temp, "SimlePrint", MB_OK);    
  105. }
  106.  
  107. const TCHAR * R2_Names[] = 
  108. {
  109.     "R2_BLACK",
  110.     "R2_NOTMERGEPEN",
  111.     "R2_MASKNOTPEN",
  112.     "R2_NOTCOPYPEN",
  113.     "R2_MASKPENNOT",
  114.     "R2_NOT",
  115.     "R2_XORPEN",
  116.     "R2_NOTMASKPEN",
  117.     "R2_MASKPEN",
  118.     "R2_NOTXORPEN",
  119.     "R2_NOP",
  120.     "R2_MERGENOTPEN",
  121.     "R2_COPYPEN",
  122.     "R2_MERGEPENNOT",
  123.     "R2_MERGEPEN",
  124.     "R2_WHITE"
  125. };
  126.  
  127. void Demo_LineCurve(HDC hDC, const RECT * rcPaint, int width, int height)
  128. {
  129.     // ROP2
  130.     KLogFont logfont(- 10 * ONEINCH / 72, "Tahoma");
  131.     KGDIObject font(hDC, logfont.CreateFont());
  132.  
  133.     for (int c=0; c<20; c++)
  134.     {
  135.         RECT rect = { c*200+400, 300, c*200+580, 4000 };
  136.  
  137.         HBRUSH hBrush = CreateSolidBrush(PALETTEINDEX(c));
  138.  
  139.         FillRect(hDC, & rect, hBrush);
  140.  
  141.         DeleteObject(hBrush);
  142.     }
  143.     
  144.     {
  145.         KGDIObject redbrush(hDC, CreateSolidBrush(RGB(0xFF, 0, 0)));
  146.         SelectObject(hDC, GetStockObject(NULL_PEN));
  147.  
  148.         SetTextAlign(hDC, TA_TOP | TA_LEFT);
  149.  
  150.         for (int r=R2_BLACK; r<=R2_WHITE; r++)
  151.         {
  152.             SetROP2(hDC, r);
  153.             TextOut(hDC, 4400, r*220+200, R2_Names[r-R2_BLACK], _tcslen(R2_Names[r-R2_BLACK]));
  154.  
  155.             Rectangle(hDC, 300, r*220+200, 4300, r*220+400);
  156.         }
  157.     
  158.         SetROP2(hDC, R2_COPYPEN);
  159.     }
  160.  
  161.     {
  162.         KPen Red (PS_DOT,            0, RGB(0xFF, 0, 0));
  163.         KPen Blue(PS_SOLID, ONEINCH/36, RGB(0, 0, 0xFF));
  164.  
  165.         for (int z=0; z<=2000; z+=400)
  166.         {
  167.             int x = 400, y = 6400;
  168.  
  169.             POINT p[4] = { x, y, x+ 400, y-z, x+800, y-z, x+1200, y }; x+= 1300;
  170.             POINT q[4] = { x, y, x+ 400, y-z, x+800, y+z, x+1200, y }; x+= 1400;
  171.         
  172.             POINT r[4] = { x, y, x+1500, y-z, x- 200, y-z, x+1300, y }; x+= 1800;
  173.             POINT s[4] = { x, y, x+1500, y-z, x- 200, y+z, x+1300, y }; x+= 1600;
  174.         
  175.             POINT t[4] = { x+600, y, x,  y-z, x+1300, y-z, x+600, y }; 
  176.  
  177.             Red.Select(hDC);
  178.             Polyline(hDC, p, 4);
  179.             Polyline(hDC, q, 4);
  180.             Polyline(hDC, r, 4);
  181.             Polyline(hDC, s, 4);
  182.             Polyline(hDC, t, 4);
  183.             Red.UnSelect();
  184.  
  185.             Blue.Select(hDC);
  186.             PolyBezier(hDC, p, 4);
  187.             PolyBezier(hDC, q, 4);
  188.             PolyBezier(hDC, r, 4);
  189.             PolyBezier(hDC, s, 4);
  190.             PolyBezier(hDC, t, 4);
  191.             Blue.UnSelect();
  192.         }
  193.     }
  194.  
  195. }
  196.  
  197. TCHAR * HS_Names [] = 
  198. {    _T("HS_HORIZONTAL"),
  199.     _T("HS_VERTICAL"),
  200.     _T("HS_FDIAGONAL"),
  201.     _T("HS_BDIAGONAL"),
  202.     _T("HS_CROSS"),
  203.     _T("HS_DIAGCROSS")
  204. };
  205.  
  206. void Demo_AreaFill(HDC hDC, const RECT * rcPaint, int width, int height)
  207. {
  208.     const COLORREF c0 = RGB(0x20, 0x20, 0x20);
  209.     const COLORREF c1 = RGB(0xF0, 0xF0, 0x20);
  210.  
  211.     for (int i=0; i<4; i++)
  212.         GradientRectangle(hDC, 1000+1100*i, 500, 2000+1100*i, 1500, c0, c1, i*450);
  213.  
  214.     for (i=0; i<4; i++)
  215.         SymGradientRectangle(hDC, 1000+1100*i, 1600, 2000+1100*i, 2600, c0, c1, i*450);
  216.  
  217.     for (i=0; i<4; i++)
  218.         CornerGradientRectangle(hDC, 1000+1100*i, 2700, 2000+1100*i, 3700, c0, c1, i);
  219.  
  220.     CenterGradientRectangle(hDC, 5600, 1500, 6600, 2500, c0, c1);
  221.     CenterGradientRectangle(hDC, 5600, 2600, 6600, 3600, c1, c0);
  222.  
  223.     //  Buttons
  224.     RoundRectButton(hDC, 0,    4000,  800, 4800,   0, 100, RGB(0x20, 0x20, 0x20), RGB(0xF0, 0xF0, 0x20));
  225.     RoundRectButton(hDC, 1000, 4000, 1800, 4800, 400, 100, RGB(0xF0, 0x20, 0x20), RGB(0x20, 0xF0, 0x20));
  226.     RoundRectButton(hDC, 2000, 4000, 2800, 4800, 800, 100, RGB(0xFF, 0xFF, 0x20), RGB(0x20, 0x20, 0xF0));
  227.     
  228.        GradientRectangle(hDC, 0, 5000, 2000, 6000, RGB(0xFF, 0x0, 0), RGB(0, 0, 0xFF), 0);
  229.     HLSGradientRectangle(hDC, 0, 6200, 2000, 7200, RGB(0xFF, 0x0, 0), RGB(0, 0, 0xFF), 200);
  230.  
  231.     RadialGradientFill(hDC, 3200, 6300, 3200    , 6300   ,  1000, RGB(0xFF, 0xFF, 0xFF), RGB(0, 0, 0xFF), 8);
  232.     RadialGradientFill(hDC, 5300, 6300, 5300-300, 6300-600, 1000, RGB(0xFF, 0xFF, 0xFF), RGB(0, 0, 0xFF), 16);
  233.     RadialGradientFill(hDC, 7400, 6300, 7400-300, 6300+300, 1000, RGB(0xFF, 0xFF, 0xFF), RGB(0, 0, 0xFF), 256);
  234.  
  235.     {
  236.         RECT r = { 7000, 500, 8500, 500+1500 };
  237.  
  238.         KGDIObject blue(hDC, CreatePen(PS_SOLID, 1 * ONEINCH/72, RGB(0, 0, 0xFF)));
  239.         KGDIObject yellow(hDC, CreateSolidBrush(RGB(0xFF, 0xFF, 0)));
  240.     
  241.         Rectangle(hDC, 7000, 500, 8500, 500+1500);
  242.         
  243.         BrickPatternFill(hDC, 7000,  500, 8500,     500+1500, 150, 150);
  244.         BrickPatternFill(hDC, 7000, 2100, 8500, 2100+1500, 100, 100);
  245.     }
  246.  
  247.     KLogFont logfont(- 8 * ONEINCH / 72, "Tahoma");
  248.     KGDIObject font(hDC, logfont.CreateFont());
  249.  
  250.     {
  251.         SelectObject(hDC, GetStockObject(NULL_PEN));
  252.     
  253.         typedef enum { GAP = 1200 };
  254.  
  255.         for (int hs= HS_HORIZONTAL; hs<=HS_DIAGCROSS; hs++)
  256.         {
  257.             HBRUSH hBrush = CreateHatchBrush(hs, RGB(0, 0, 0xFF));
  258.             HGDIOBJ hOld  = SelectObject(hDC, hBrush);
  259.  
  260.             SetBkColor(hDC, RGB(0xFF, 0xFF, 0));
  261.             Rectangle(hDC, hs*GAP, 8000, hs*GAP+890, 8890);
  262.  
  263.             SetBkColor(hDC, RGB(0xFF, 0xFF, 0xFF));
  264.         
  265.             SetTextAlign(hDC, TA_CENTER);
  266.             TextOut(hDC, hs*GAP+880/2, 8980, HS_Names[hs-HS_HORIZONTAL], _tcslen(HS_Names[hs-HS_HORIZONTAL]));
  267.  
  268.             SelectObject(hDC, hOld);
  269.             DeleteObject(hBrush);
  270.         }
  271.     }
  272.  
  273.     {
  274.         HINSTANCE hCards = LoadLibrary("cards.dll");
  275.  
  276.         for (int i=0; i<3; i++)
  277.     {
  278.         HBRUSH hBrush;
  279.         int    width, height;
  280.  
  281.         switch ( i )
  282.         {
  283.             case 0:
  284.                 {
  285.                     HBITMAP hBitmap = LoadBitmap(hCards, MAKEINTRESOURCE(52));
  286.                     BITMAP  bmp;
  287.  
  288.                     GetObject(hBitmap, sizeof(bmp), & bmp);
  289.                     width = bmp.bmWidth; height = bmp.bmHeight;
  290.  
  291.                     hBrush = CreatePatternBrush(hBitmap);
  292.                     DeleteObject(hBitmap);
  293.                 }
  294.                 break;
  295.  
  296.             case 1:
  297.                 {
  298.                     HRSRC hResource = FindResource(hCards, MAKEINTRESOURCE(52-14), RT_BITMAP);
  299.                     HGLOBAL hGlobal = LoadResource(hCards, hResource);
  300.     
  301.                     hBrush  = CreateDIBPatternBrushPt(LockResource(hGlobal), DIB_RGB_COLORS);
  302.                     width   = ((BITMAPCOREHEADER *) hGlobal)->bcWidth; // old DIB format
  303.                     height  = ((BITMAPCOREHEADER *) hGlobal)->bcHeight;// old DIB format
  304.                 }
  305.                 break;
  306.  
  307.             case 2:
  308.                 {
  309.                     HRSRC hResource = FindResource(hCards, MAKEINTRESOURCE(52-28), RT_BITMAP);
  310.                     HGLOBAL hGlobal = LoadResource(hCards, hResource);
  311.  
  312.                     hBrush  = CreateDIBPatternBrush(hGlobal, DIB_RGB_COLORS);
  313.                     width   = ((BITMAPCOREHEADER *) hGlobal)->bcWidth;  // old DIB format
  314.                     height  = ((BITMAPCOREHEADER *) hGlobal)->bcHeight; // old DIB format
  315.                 }
  316.         }
  317.         
  318.         HGDIOBJ hOld  = SelectObject(hDC, hBrush);
  319.  
  320.         POINT P = { i*1400+200 + width*10*i/4, 10000 + height*10*i/4 };
  321.         LPtoDP(hDC, &P, 1);
  322.         SetBrushOrgEx(hDC, P.x, P.y, NULL); // make sure cards aligned with rectangle
  323.     
  324.         Rectangle(hDC, i*1400+200, 10000, i*1400+200+width*30/2+1, 10000+height*30/2+1);
  325.     
  326.         SelectObject(hDC, hOld);
  327.         DeleteObject(hBrush);
  328.  
  329.     }
  330.     }
  331.  
  332. }
  333.  
  334.  
  335. void Demo_Bitmap(HDC hDC, const RECT * rcPaint, int width, int height, HINSTANCE hInst)
  336. {
  337.     HDC hMemDC = CreateCompatibleDC(NULL);
  338.  
  339.     // load difference BITMAP as resource
  340.     HPALETTE hPal = CreateHalftonePalette(hDC);
  341.     HPALETTE hOld = SelectPalette(hDC, hPal, FALSE);
  342.     RealizePalette(hDC);
  343.  
  344.     SetStretchBltMode(hDC, STRETCH_DELETESCANS);
  345.  
  346.     for (int i=0; i<6; i++)
  347.     {
  348.         int x = 100 + (i%3) * 3200;
  349.         int y = 100 + (i/3) * 3200;
  350.  
  351.         HBITMAP hBmp = LoadBitmap(hInst, MAKEINTRESOURCE(i+IDB_BITMAP1));
  352.  
  353.         KGDIObject bmp(hMemDC, hBmp);
  354.  
  355.         if ( hBmp==NULL ) break;
  356.  
  357.         BITMAP info;
  358.         GetObject(hBmp, sizeof(BITMAP), & info);
  359.  
  360.         StretchBlt(hDC, x, y, 
  361.             info.bmWidth * ONEINCH / 120, info.bmHeight * ONEINCH / 120, 
  362.             hMemDC, 0, 0, info.bmWidth, info.bmHeight, SRCCOPY);
  363.     }
  364.  
  365.     SelectPalette(hDC, hOld, FALSE);
  366.     RealizePalette(hDC);
  367.     DeleteObject(hPal);
  368.  
  369.     DeleteObject(hMemDC);
  370. }
  371.  
  372.  
  373. void Demo_Text(HDC hDC, const RECT * rcPaint, int width, int height)
  374. {
  375.     KLogFont logfont(- 10 * ONEINCH / 72, "Times New Roman");
  376.     KGDIObject font(hDC, logfont.CreateFont());
  377.  
  378.     const TCHAR * mess = "A quick brown fox jumps over a lazy dog. "
  379.                          "A quick brown fox jumps over a lazy dog. "
  380.                          "A quick brown fox jumps over a lazy dog. ";
  381.  
  382.     SetBkMode(hDC, TRANSPARENT);
  383.     SetTextAlign(hDC, TA_LEFT | TA_BASELINE);
  384.     int y = ONEINCH/2;
  385.     
  386.     // use normal GDI TextOut
  387.     SIZE size;
  388.     GetTextExtentPoint32(hDC, mess, _tcslen(mess), & size);
  389.     MoveToEx(hDC, 0, y, NULL); LineTo(hDC, size.cx, y);
  390.  
  391.     TextOut(hDC, 0, y, mess, _tcslen(mess));
  392.  
  393.     TCHAR temp[64];
  394.     wsprintf(temp, "size = { %d, %d }", size.cx, size.cy);
  395.     TextOut(hDC, 0, y + size.cy, temp, _tcslen(temp));
  396.  
  397.     y += size.cy * 3;
  398.  
  399.     KTextFormator format;
  400.  
  401.     format.SetupPixel(hDC, (HFONT) font.m_hObj, (float)(10.0 * ONEINCH/72));
  402.  
  403.     float wid, hei;
  404.     format.GetTextExtent(hDC, mess, _tcslen(mess), wid, hei);
  405.     
  406.     MoveToEx(hDC, 0, y, NULL);
  407.     LineTo(hDC, (int) wid, y);
  408.     format.TextOut(hDC, 0, y, mess, _tcslen(mess));
  409.     
  410.     sprintf(temp, "size = { %5.3f, %5.3f }", wid, hei);
  411.     TextOut(hDC, 0, y + size.cy, temp, _tcslen(temp));
  412. }
  413.  
  414.  
  415. class KTestPageCanvas : public KPageCanvas
  416. {
  417.     int m_demo;
  418.  
  419.     void GetWndClassEx(WNDCLASSEX & wc)
  420.     {
  421.         KPageCanvas::GetWndClassEx(wc);
  422.  
  423.         wc.hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_PRINT));
  424.     }
  425.  
  426. public:
  427.     virtual void UponDrawPage(HDC hDC, const RECT * rcPaint, int width, int height, int pageno)
  428.     {
  429.         switch ( m_demo )
  430.         {
  431.             case 0:
  432.                 KSurface::UponDrawPage(hDC, rcPaint, width, height, pageno);
  433.                 break;
  434.  
  435.             case IDM_VIEW_LINECURVE:
  436.                 Demo_LineCurve(hDC, rcPaint, width, height);
  437.                 break;
  438.  
  439.             case IDM_VIEW_AREAFILL:
  440.                 Demo_AreaFill(hDC, rcPaint, width, height);
  441.                 break;
  442.  
  443.             case IDM_VIEW_BITMAP:
  444.                 Demo_Bitmap(hDC, rcPaint, width, height, m_hInst);
  445.                 break;
  446.  
  447.             case IDM_VIEW_TEXT:
  448.                 Demo_Text(hDC, rcPaint, width, height);
  449.                 break;
  450.         }
  451.     }
  452.  
  453.     virtual int OnCommand(int cmd, HWND hWnd)
  454.     {
  455.         switch ( cmd )
  456.         {
  457.             case IDM_VIEW_LINECURVE:
  458.             case IDM_VIEW_AREAFILL:
  459.             case IDM_VIEW_BITMAP:
  460.             case IDM_VIEW_TEXT:
  461.                 if ( cmd==m_demo )
  462.                     return View_NoChange;
  463.                 else
  464.                 {
  465.                     m_demo = cmd;
  466.                     return View_Redraw;
  467.                 }
  468.                 break;
  469.  
  470.             case IDM_VIEW_ZOOM500  : return SetZoom(500);
  471.             case IDM_VIEW_ZOOM400  : return SetZoom(400);
  472.             case IDM_VIEW_ZOOM200  : return SetZoom(200); 
  473.             case IDM_VIEW_ZOOM150  : return SetZoom(150); 
  474.             case IDM_VIEW_ZOOM100  : return SetZoom(100);
  475.             case IDM_VIEW_ZOOM75   : return SetZoom( 75);
  476.             case IDM_VIEW_ZOOM50   : return SetZoom( 50);
  477.             case IDM_VIEW_ZOOM25   : return SetZoom( 25);
  478.             case IDM_VIEW_ZOOM10   : return SetZoom( 10);
  479.  
  480.             case IDM_FILE_PRINT    : UponFilePrint();      GetDimension(); return View_Resize;
  481.             case IDM_FILE_PAGESETUP: UponFilePageSetup(); GetDimension(); return View_Resize;
  482.  
  483.             case IDM_FILE_PROPERTY:  
  484.             {
  485.                 int nControlID[] = { IDC_LIST, IDC_DEFAULT, IDC_PRINTERS, 
  486.                     IDC_PRINTERPROPERTIES, IDC_ADVANCEDDOCUMENTPROPERTIES, IDC_DOCUMENTPROPERTIES };
  487.             
  488.                 ShowProperty(m_OutputSetup, m_hInst, nControlID, IDD_PROPERTY);
  489.             }
  490.         }
  491.  
  492.         return View_NoChange;
  493.     }
  494.     
  495.     KTestPageCanvas(HBRUSH hBackground) : KPageCanvas(hBackground)
  496.     {
  497.         m_demo = 0;
  498.     }
  499. };
  500.  
  501.  
  502. ////////////////////////// MDI Frame Window
  503.  
  504. const int Translate[] =
  505. {
  506.     IDM_FILE_CLOSE,
  507.     IDM_FILE_EXIT,
  508.     IDM_WINDOW_TILE,
  509.     IDM_WINDOW_CASCADE,
  510.     IDM_WINDOW_ARRANGE,
  511.     IDM_WINDOW_CLOSEALL
  512. };
  513.  
  514.  
  515. BOOL SendFile(HANDLE hOutput, const TCHAR * filename, bool bPrinter)
  516. {
  517.     HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 
  518.                         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  519.  
  520.     if ( hFile==INVALID_HANDLE_VALUE )
  521.         return FALSE;
  522.  
  523.     char buffer[1024];
  524.  
  525.     for (int size = GetFileSize(hFile, NULL); size; )
  526.     {
  527.         DWORD dwRead = 0, dwWritten = 0;
  528.  
  529.         if ( ! ReadFile(hFile, buffer, min(size, sizeof(buffer)), & dwRead, NULL) )
  530.             break;
  531.  
  532.         if ( bPrinter )
  533.             WritePrinter(hOutput, buffer, dwRead, & dwWritten);
  534.         else
  535.             WriteFile(hOutput, buffer, dwRead, & dwWritten, NULL);
  536.         
  537.         size -= dwRead;
  538.     }
  539.  
  540.     return TRUE;
  541. }
  542.  
  543. void Demo_WritePort(void)
  544. {
  545.     KFileDialog fd;
  546.  
  547.     if ( fd.GetOpenFileName(NULL, "prn", "Raw printer data") )
  548.     {
  549.         HANDLE hPort = CreateFile("lpt1:", GENERIC_WRITE, FILE_SHARE_READ,
  550.                            NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  551.  
  552.         if ( hPort!=INVALID_HANDLE_VALUE )
  553.         {
  554.             SendFile(hPort, fd.m_TitleName, false);
  555.             CloseHandle(hPort);
  556.         }
  557.     }
  558. }
  559.  
  560. void Demo_WritePrinter(void)
  561. {
  562.     PRINTDLG  pd;
  563.  
  564.     memset(&pd, 0, sizeof(PRINTDLG));
  565.     pd.lStructSize = sizeof(PRINTDLG);
  566.  
  567.     if ( PrintDlg(&pd)==IDOK )
  568.     {
  569.         HANDLE hPrinter;
  570.  
  571.         DEVMODE * pDevMode = (DEVMODE *) GlobalLock(pd.hDevMode);
  572.  
  573.         PRINTER_DEFAULTS prn;
  574.         prn.pDatatype     = "NT EMF 1.008";
  575.         prn.pDevMode      = pDevMode;
  576.         prn.DesiredAccess = PRINTER_ACCESS_USE;
  577.  
  578.         if ( OpenPrinter((char *) pDevMode->dmDeviceName, & hPrinter, & prn) )
  579.         {
  580.             KFileDialog fd;
  581.  
  582.             if ( fd.GetOpenFileName(NULL, "spl", "Windows 2000 EMF Spool file") )
  583.             {
  584.                 DOC_INFO_1 docinfo;
  585.  
  586.                 docinfo.pDocName    = "Testing WritePrinter";
  587.                 docinfo.pOutputFile = NULL;
  588.                 docinfo.pDatatype   = "NT EMF 1.008";
  589.  
  590.                 StartDocPrinter(hPrinter, 1, (BYTE *) & docinfo);
  591.                 StartPagePrinter(hPrinter);
  592.                 
  593.                 SendFile(hPrinter, fd.m_TitleName, true);
  594.                 
  595.                 EndPagePrinter(hPrinter);
  596.                 EndDocPrinter(hPrinter);
  597.             }
  598.  
  599.             ClosePrinter(hPrinter);
  600.         }
  601.  
  602.         if ( pd.hDevMode )    GlobalFree(pd.hDevMode);
  603.         if ( pd.hDevNames ) GlobalFree(pd.hDevNames);
  604.     }
  605. }
  606.  
  607.  
  608. void Demo_OutputSetup(bool bShowDialog)
  609. {
  610.     KOutputSetup setup;
  611.  
  612.     DWORD flags = PD_RETURNDC;
  613.     if ( ! bShowDialog )
  614.         flags |= PD_RETURNDEFAULT;
  615.  
  616.     if ( IDOK == setup.PrintDialog(flags) )
  617.     {
  618.         HDC hDC = setup.GetPrinterDC();
  619.         
  620.         TCHAR temp[32];
  621.         wsprintf(temp, "Printer DC=%x", hDC);
  622.         MessageBox(NULL, temp, "KOutputSetup", MB_OK);
  623.     }
  624. }
  625.  
  626. class KMyMDIFrame : public KMDIFrame
  627. {
  628.     void CreateMDIChild(KCanvas * canvas, const TCHAR * klass, const TCHAR * title)
  629.     {
  630.         MDICREATESTRUCT mdic;
  631.  
  632.         mdic.szClass = klass;
  633.         mdic.szTitle = title;
  634.         mdic.hOwner  = m_hInst;
  635.         mdic.x       = CW_USEDEFAULT;
  636.         mdic.y       = CW_USEDEFAULT;
  637.         mdic.cx      = CW_USEDEFAULT;
  638.         mdic.cy      = CW_USEDEFAULT;
  639.         mdic.style   = WS_VISIBLE | WS_BORDER;
  640.         mdic.lParam  = (LPARAM) canvas;
  641.  
  642.         HWND hWnd = (HWND) SendMessage(m_hMDIClient, WM_MDICREATE, 0, (LPARAM) & mdic);
  643.     }
  644.  
  645.     BOOL CreatePageCanvas(const TCHAR * Title)
  646.     {
  647.         KPageCanvas  * pCanvas;
  648.         
  649.         pCanvas = new KTestPageCanvas(GetSysColorBrush(COLOR_BTNSHADOW));
  650.  
  651.         if ( pCanvas )
  652.         {
  653.             if ( pCanvas->Initialize(m_hInst, m_pStatus, IDR_DEMO) )
  654.             {
  655.                 CreateMDIChild(pCanvas, pCanvas->GetClassName(), Title);
  656.                 return TRUE;
  657.             }
  658.  
  659.             delete pCanvas;
  660.         }
  661.  
  662.         return FALSE;
  663.     }
  664.  
  665.     virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam)
  666.     {
  667.         switch ( LOWORD(wParam) )
  668.         {
  669.             case IDM_FILE_DIRECTPRINT:
  670.                 Demo_WritePort();
  671.                 return TRUE;
  672.  
  673.             case IDM_FILE_OPENPRINTER:
  674.                 Demo_WritePrinter();
  675.                 return TRUE;
  676.  
  677.             case IDM_FILE_PRINTDIALOGDEFAULT:
  678.                 Demo_OutputSetup(false);
  679.                 return TRUE;
  680.  
  681.             case IDM_FILE_PRINTDIALOGPROMPT:
  682.                 Demo_OutputSetup(true);
  683.                 return TRUE;
  684.  
  685.             case IDM_FILE_DEFAULTPRINTERDC:
  686.                 {
  687.                     TCHAR name[64];
  688.  
  689.                     DWORD size = 64;
  690.                     GetDefaultPrinter(name, & size);
  691.  
  692.                     HDC hDC = CreateDC(NULL, name, NULL, NULL);
  693.                     
  694.                     if ( hDC )
  695.                         MessageBox(NULL, "Printer DC Created", name, MB_OK);
  696.                     DeleteDC(hDC);
  697.                 }
  698.                 return TRUE;
  699.  
  700.             case IDM_FILE_SIMPLEPRINT:
  701.                 SimplePrint(2);
  702.                 return TRUE;
  703.  
  704.             case IDM_FILE_NEW:
  705.             {
  706.                 CreatePageCanvas(_T("Test Printer "));
  707.                 return TRUE;
  708.             }
  709.         }
  710.  
  711.         return FALSE;
  712.     }
  713.  
  714.     virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  715.     {
  716.         return KMDIFrame::WndProc(hWnd, uMsg, wParam, lParam);
  717.     }
  718.  
  719.     void GetWndClassEx(WNDCLASSEX & wc)
  720.     {
  721.         KMDIFrame::GetWndClassEx(wc);
  722.  
  723.         wc.hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_PRINT));
  724.     }
  725.  
  726. public:
  727.     KMyMDIFrame(HINSTANCE hInstance, const TBBUTTON * pButtons, int nCount,
  728.         KToolbar * pToolbar, KStatusWindow * pStatus) :
  729.         KMDIFrame(hInstance, pButtons, nCount, pToolbar, pStatus, Translate)
  730.     {
  731.     }
  732. };
  733.  
  734.  
  735. const TBBUTTON tbButtons[] =
  736. {
  737.     { STD_FILENEW,     IDM_FILE_NEW,   TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, IDS_FILENEW,  0 },
  738.     { STD_FILEOPEN,  IDM_FILE_OPEN,  TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, IDS_FILEOPEN, 0 }
  739. };
  740.  
  741.  
  742. int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nShow)
  743. {
  744.     KToolbar      toolbar;
  745.     KStatusWindow status;
  746.  
  747.     KMyMDIFrame frame(hInst, tbButtons, 2, & toolbar, & status);
  748.     
  749.     frame.CreateEx(0, _T("ClassName"), _T("Printer"),
  750.         WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  751.         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
  752.         NULL, LoadMenu(hInst, MAKEINTRESOURCE(IDR_MAIN)), hInst);
  753.  
  754.     frame.ShowWindow(nShow);
  755.     frame.UpdateWindow();
  756.  
  757.     frame.MessageLoop();
  758.  
  759.     return 0;
  760. }
  761.