home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / include / pagecanvas.cpp < prev    next >
C/C++ Source or Header  |  2000-05-11  |  9KB  |  366 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   : pagecanvas.cpp                                                         //
  10. //  Description: KSurface class implementation                                       //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define WIN32_LEAN_AND_MEAN
  16.  
  17. #include <windows.h>
  18. #include <tchar.h>
  19. #include <assert.h>
  20. #include <commdlg.h>
  21.  
  22. #include "outputsetup.h"
  23. #include "pagecanvas.h"
  24.  
  25. void DrawFrame(HDC hDC, int x0, int y0, int x1, int y1, COLORREF crPen, COLORREF crBrush, bool frame)
  26. {
  27. //    TCHAR temp[MAX_PATH];
  28.  
  29. //    wsprintf(temp, "%d %d %d %d   w=%d, h=%d\n", x0, y0, x1, y1, x1-x0, y1-y0);
  30. //    OutputDebugString(temp);
  31.  
  32.     HPEN   hPen   = CreatePen(PS_SOLID, 0, crPen);
  33.     HBRUSH hBrush = CreateSolidBrush(crBrush);
  34.  
  35.     HGDIOBJ hOldPen = SelectObject(hDC, hPen);
  36.     HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
  37.     
  38.     Rectangle(hDC, x0-1, y0-1, x1+1, y1+1);
  39.     
  40.     SelectObject(hDC, hOldPen);
  41.     SelectObject(hDC, hOldBrush);
  42.     DeleteObject(hOldPen);
  43.     DeleteObject(hOldBrush);
  44.  
  45.     if ( frame )
  46.     {
  47.         RECT rectr = { x1+1, y0+1, x1+3, y1+3 };
  48.         FillRect(hDC, & rectr, (HBRUSH) GetStockObject(BLACK_BRUSH));
  49.  
  50.         RECT rectb = { x0+1, y1+1, x1+3, y1+3 };
  51.         FillRect(hDC, & rectb, (HBRUSH) GetStockObject(BLACK_BRUSH));
  52.     }
  53. }
  54.  
  55. void KSurface::DrawPaper(HDC hDC, const RECT * rcPaint, int col, int row)
  56. {
  57.     // paper frame
  58.     DrawFrame(hDC, px(0, col), py(0, row), px(m_Paper.cx, col), py(m_Paper.cy, row), 
  59.         RGB(0, 0, 0), RGB(0xE0, 0xE0, 0xE0), true);
  60.  
  61.     // minimum margin : printable margin
  62.     DrawFrame(hDC, px(m_MinMargin.left, col), py(m_MinMargin.top, row),
  63.                    px(m_Paper.cx - m_MinMargin.right, col),
  64.                    py(m_Paper.cy - m_MinMargin.bottom, row), 
  65.                    RGB(0xF0, 0xF0, 0xF0), RGB(0xF0, 0xF0, 0xF0), false);
  66.  
  67.     // margin
  68.     DrawFrame(hDC, px(m_Margin.left, col), py(m_Margin.top, row),
  69.                    px(m_Paper.cx - m_Margin.right, col), py(m_Paper.cy - m_Margin.bottom, row), 
  70.                    RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), false);
  71. }
  72.  
  73.  
  74. // convert from 1/1000 inch to BASE_DPI
  75.     
  76. void KSurface::SetPaper(void)
  77. {
  78.     POINT paper;
  79.     RECT  margin;
  80.     RECT  minmargin; 
  81.     
  82.     m_OutputSetup.GetPaperSize(paper);
  83.     m_OutputSetup.GetMargin(margin);
  84.     m_OutputSetup.GetMinMargin(minmargin);
  85.  
  86.     m_Paper.cx     = paper.x * BASE_DPI / 1000;
  87.     m_Paper.cy     = paper.y * BASE_DPI / 1000;
  88.  
  89.     m_Margin.left  = margin.left   * BASE_DPI / 1000;
  90.     m_Margin.right = margin.right  * BASE_DPI / 1000;
  91.     m_Margin.top   = margin.top    * BASE_DPI / 1000;
  92.     m_Margin.bottom= margin.bottom * BASE_DPI / 1000;
  93.  
  94.     m_MinMargin.left  = minmargin.left   * BASE_DPI / 1000;
  95.     m_MinMargin.right = minmargin.right  * BASE_DPI / 1000;
  96.     m_MinMargin.top   = minmargin.top    * BASE_DPI / 1000;
  97.     m_MinMargin.bottom= minmargin.bottom * BASE_DPI / 1000;
  98. }
  99.  
  100.  
  101. // calculate overall surface size needed to fit nPage divided into nCol columns
  102. void KSurface::CalculateSize(void)
  103. {
  104.     int nPage = GetPageCount();
  105.     int nCol  = GetColumnCount();
  106.     int nRow  = (nPage + nCol - 1) / nCol;
  107.  
  108.     m_nSurfaceWidth  = px(m_Paper.cx, 0) * nCol + MARGIN_X;
  109.     m_nSurfaceHeight = py(m_Paper.cy, 0) * nRow + MARGIN_Y; 
  110. }
  111.  
  112. int gcd(int m, int n)
  113. {
  114.     if ( m==0 )
  115.         return n;
  116.     else
  117.         return gcd(n % m, m);
  118. }
  119.  
  120. void SetupULCS(HDC hDC, int zoom)
  121. {
  122.     SetMapMode(hDC, MM_ANISOTROPIC);
  123.  
  124.     int mul = ONEINCH                         * 100;
  125.     int div = GetDeviceCaps(hDC, LOGPIXELSX) * zoom;
  126.     int fac = gcd(mul, div);
  127.  
  128.     mul    /= fac;
  129.     div    /= fac;
  130.  
  131.       SetWindowExtEx(hDC, mul, mul, NULL);
  132.     SetViewportExtEx(hDC, div, div, NULL);
  133. }
  134.  
  135. bool KSurface::UponSetZoom(int zoom)
  136. {
  137.     if ( zoom == m_nZoom )
  138.         return false;
  139.  
  140.     m_nZoom = zoom;
  141.  
  142.     HDC hDC  = GetDC(NULL);
  143.     m_nScale = zoom * GetDeviceCaps(hDC, LOGPIXELSX) / 100;
  144.     DeleteDC(hDC);
  145.     
  146.     CalculateSize();
  147.  
  148.     return true;
  149. }
  150.  
  151.  
  152. void KSurface::RefreshPaper(void)
  153. {
  154.     int zoom = m_nZoom;
  155.  
  156.     m_nZoom = 0;
  157.     SetPaper();
  158.     UponSetZoom(zoom);
  159. }
  160.  
  161.  
  162. void KSurface::UponInitialize(HWND hWnd)
  163. {
  164.     m_OutputSetup.SetDefault(hWnd, 1, GetPageCount());
  165.  
  166.     m_nZoom = 100;
  167.     RefreshPaper();
  168. }
  169.  
  170.  
  171. void KSurface::UponDrawPage(HDC hDC, const RECT * rcPaint, int width, int height, int pageno)
  172. {
  173.     for (int h=0; h<=(height-BASE_DPI); h += BASE_DPI)
  174.     for (int w=0; w<=(width-BASE_DPI);  w += BASE_DPI)
  175.         Rectangle(hDC, w, h, w+BASE_DPI, h+BASE_DPI);
  176. }
  177.  
  178. // draw page on screen, with paper border, scale
  179. void KSurface::UponDraw(HDC hDC, const RECT * rcPaint)
  180. {
  181.     int nPage = GetPageCount();
  182.     int nCol  = GetColumnCount();
  183.     int nRow  = (nPage + nCol - 1) / nCol;
  184.  
  185.     for (int p=0; p<nPage; p++)
  186.     {
  187.         SaveDC(hDC);
  188.  
  189.         int col = p % nCol;
  190.         int row = p / nCol;
  191.         DrawPaper(hDC, rcPaint, col, row);
  192.         SetupULCS(hDC, m_nZoom);
  193.         OffsetViewportOrgEx(hDC, px(m_Margin.left, col), py(m_Margin.top, row), NULL);
  194.         UponDrawPage(hDC, rcPaint, GetDrawableWidth(), GetDrawableHeight(), p);
  195.  
  196.         RestoreDC(hDC, -1);
  197.     }
  198. }
  199.  
  200.  
  201. // print document to printer
  202. bool KSurface::UponPrint(HDC hDC, const TCHAR * pDocName)
  203. {
  204.     int scale = GetDeviceCaps(hDC, LOGPIXELSX);
  205.         
  206.     SetMapMode(hDC, MM_ANISOTROPIC);
  207.         
  208.       SetWindowExtEx(hDC, BASE_DPI, BASE_DPI, NULL);
  209.     SetViewportExtEx(hDC, scale,    scale,    NULL);
  210.  
  211.     OffsetViewportOrgEx(hDC, (m_Margin.left - m_MinMargin.left) * scale / BASE_DPI, 
  212.                              (m_Margin.top  - m_MinMargin.top ) * scale / BASE_DPI, NULL);
  213.  
  214.     DOCINFO docinfo;
  215.  
  216.     docinfo.cbSize       = sizeof(docinfo);
  217.     docinfo.lpszDocName  = pDocName;
  218.     docinfo.lpszOutput   = NULL; 
  219.     docinfo.lpszDatatype = _T("EMF");
  220.     docinfo.fwType         = 0; 
  221.  
  222.     if ( StartDoc(hDC, & docinfo) <= 0)
  223.         return false;
  224.  
  225.     int nFrom = 0;
  226.     int nTo   = GetPageCount();
  227.  
  228.     for (int pageno=nFrom; pageno<nTo; pageno++)
  229.     {
  230.         if ( StartPage(hDC) < 0 )
  231.         {
  232.             AbortDoc(hDC);
  233.             return FALSE;
  234.         }
  235.  
  236.         UponDrawPage(hDC, NULL, GetDrawableWidth(), GetDrawableHeight(), pageno);
  237.         EndPage(hDC);
  238.     }
  239.  
  240.     EndDoc(hDC);
  241.  
  242.     return true;
  243. }
  244.  
  245.  
  246. bool KSurface::UponFilePrint(void)
  247. {
  248.     int rslt = m_OutputSetup.PrintDialog(PD_RETURNDC | PD_SELECTION);
  249.  
  250.     if ( rslt==IDOK )
  251.         UponPrint(m_OutputSetup.GetPrinterDC(), GetDocumentName());
  252.  
  253.     m_OutputSetup.DeletePrinterDC();
  254.  
  255.     return false;
  256. }
  257.  
  258.  
  259. bool KSurface::UponFilePageSetup(void)
  260. {
  261.     if ( m_OutputSetup.PageSetup(PSD_MARGINS) )
  262.     {
  263.         RefreshPaper();
  264.         return true;
  265.     }
  266.     
  267.     return false;
  268. }
  269.  
  270. ////////////////////////////////////////////////////
  271.  
  272.  
  273. void KPageCanvas::Response(int rslt)
  274. {
  275.     if ( rslt & View_Resize )
  276.     {
  277.         SetSize(GetPixelWidth(), GetPixelHeight(), 20, 20, TRUE);
  278.         rslt |= View_Redraw;
  279.     }
  280.  
  281.     if ( rslt & View_Redraw )
  282.         InvalidateRect(m_hWnd, NULL, TRUE);
  283. }
  284.  
  285.  
  286. void KPageCanvas::OnCreate(void)
  287. {
  288.     UponInitialize(m_hWnd);        // initialize KSurface
  289.  
  290.     GetDimension();
  291.     SetSize(m_nPixelWidth, m_nPixelHeight, 20, 20, TRUE);
  292. }
  293.  
  294. LRESULT KPageCanvas::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  295. {
  296.     switch( uMsg )
  297.     {
  298.         case WM_CREATE:
  299.             m_hWnd        = hWnd;
  300.             m_hViewMenu = LoadMenu(m_hInst, MAKEINTRESOURCE(m_nMenuID));
  301.  
  302.             OnCreate();
  303.             return 0;
  304.  
  305.         case WM_PAINT:
  306.             return KScrollCanvas::WndProc(hWnd, uMsg, wParam, lParam);
  307.  
  308.         case WM_SIZE:
  309.         case WM_HSCROLL:
  310.         case WM_VSCROLL:
  311.             return KScrollCanvas::WndProc(hWnd, uMsg, wParam, lParam);
  312.  
  313.         case WM_COMMAND:
  314.             Response( OnCommand(LOWORD(wParam), hWnd) );
  315.             return 0;
  316.             break;
  317.  
  318.         default:
  319.             return CommonMDIChildProc(hWnd, uMsg, wParam, lParam, m_hViewMenu, 2);
  320.     }
  321. }
  322.  
  323.  
  324. void KPageCanvas::GetWndClassEx(WNDCLASSEX & wc)
  325. {
  326.     memset(& wc, 0, sizeof(wc));
  327.  
  328.     wc.cbSize      = sizeof(WNDCLASSEX);
  329.     wc.style       = CS_HREDRAW | CS_VREDRAW;
  330.     wc.lpfnWndProc = WindowProc;
  331.     wc.cbClsExtra  = 0;
  332.     wc.cbWndExtra  = 0;       
  333.     wc.hInstance   = NULL;
  334.     wc.hIcon       = NULL;
  335.     wc.hCursor     = LoadCursor(NULL, IDC_ARROW); 
  336.  
  337.     if ( m_hBackground )
  338.         wc.hbrBackground  = m_hBackground;
  339.     else
  340.         wc.hbrBackground  = (HBRUSH) (COLOR_WINDOW + 1);
  341.         
  342.     wc.lpszMenuName  = NULL;
  343.     wc.lpszClassName = NULL;
  344.     wc.hIconSm       = NULL;
  345. }
  346.     
  347.  
  348. bool KPageCanvas::Initialize(HINSTANCE hInstance, KStatusWindow * pStatus, int menuid)
  349. {
  350.     m_nMenuID  = menuid;
  351.     m_hInst    = hInstance;
  352.     m_pStatus  = pStatus;
  353.  
  354.     RegisterClass(GetClassName(), hInstance);
  355.         
  356.     return true;
  357. }
  358.  
  359.  
  360. KPageCanvas::KPageCanvas(HBRUSH hBackground)
  361. {
  362.     m_hBackground  = hBackground;
  363.     m_nPixelWidth  = 320;
  364.     m_nPixelHeight = 240;
  365. }
  366.