home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_16 / EMFScope / CANVAS.CPP next >
Encoding:
C/C++ Source or Header  |  2000-07-10  |  10.9 KB  |  458 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   : canvas.cpp                                                             //
  10. //  Description: Canvas window for EMFScope                                          //
  11. //  Version    : 1.00.001, July 10, 2000                                             //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #include <windows.h>
  16. #include <assert.h>
  17.  
  18. #include "Winpp.h"
  19. #include "Progress.h"
  20. #include "Stream.h"
  21.  
  22. #include "emfscope.h"
  23. #include "canvas.h"
  24. #include "spehon32\\spehon32.h"
  25. #include "resource.h"
  26. #include "toolbar.h"
  27. #include "Spoolfil.h"
  28. #include "Examemf.h"
  29.  
  30.  
  31. #define maxx  MetaHeader.szlDevice.cx
  32. #define maxy  MetaHeader.szlDevice.cy
  33.  
  34.  
  35. KCanvasWindow::KCanvasWindow(HINSTANCE hInst, HWND hWnd, int x, int y, int w, int h)
  36. {
  37.     scale            = 1;
  38.     hMetaFile        = NULL;
  39.     hNTMetaFile      = NULL;
  40.  
  41.     page_margin      = 10;
  42.     canvas_backcolor = RGB(0xFF, 0xFF, 0x80);
  43.     hInstance        = hInst;
  44.  
  45.     Createwindow("CanvasClass",
  46.                  IDI_COLIVE,
  47.                  0,
  48.                  "Canvas", 
  49.                  WS_VISIBLE | WS_CHILD | WS_BORDER,
  50.                  mapx(x), mapy(y), mapx(w), mapy(h), 
  51.                  hWnd,
  52.                  hInst,
  53.                  NULL, 0, (HBRUSH) GetStockObject(WHITE_BRUSH) );
  54. }
  55.  
  56. void KCanvasWindow::GetDisplayRect(RECT *r)
  57. {
  58.     int    xScroll = GetScrollPos  (m_hWnd, SB_HORZ);
  59.     int yScroll = GetScrollPos  (m_hWnd, SB_VERT);
  60.  
  61.     r->left   =            - xScroll + page_margin;
  62.     r->right  = maxx/scale - xScroll + page_margin;
  63.     r->top    =            - yScroll + page_margin;
  64.     r->bottom = maxy/scale - yScroll + page_margin;
  65. }
  66.  
  67.  
  68. int CALLBACK SlowPaintEMF(HDC hDC, HANDLETABLE *lpHTable,
  69.                           ENHMETARECORD *lpEMFR, int nObj, LPVOID lpData)
  70. {
  71.     if (lpData)
  72.     {
  73.         KProgress *Progress = (KProgress *) lpData;
  74.  
  75.         if (Progress->Active())
  76.             if (Progress->AbortDraw())
  77.                 Progress->Destroy();
  78.             else
  79.             {
  80.                 Progress->Delay();
  81.  
  82.                 if (lpEMFR->iType==EMR_HEADER)
  83.                     Progress->SetRange(0, ((ENHMETAHEADER *)lpEMFR)->nRecords);
  84.                 else
  85.                     Progress->Move();
  86.             }
  87.     }
  88.     
  89.     return PlayEnhMetaFileRecord(hDC, lpHTable, lpEMFR, nObj);
  90. }
  91.  
  92.  
  93. LRESULT KCanvasWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  94. {
  95.     switch (uMsg)
  96.     {
  97.         case WM_CREATE:
  98.             m_hWnd = hWnd;
  99.             break;
  100.  
  101.         case WM_PAINT:
  102.             if (hMetaFile || hNTMetaFile)
  103.             {
  104.                 PAINTSTRUCT ps;
  105.                 RECT        rect;
  106.                 HBRUSH      bbrush;
  107.  
  108.                 BeginPaint(hWnd, &ps);
  109.                 
  110.                 GetDisplayRect(&rect);
  111.                 
  112.                 bbrush = CreateSolidBrush(canvas_backcolor);
  113.                 FillRect(ps.hdc, &rect, bbrush);
  114.                 DeleteObject(bbrush);
  115.  
  116.                 if (hMetaFile)
  117.                     if (canvas_delay==0)
  118.                         PlayEnhMetaFile(ps.hdc, hMetaFile, &rect);
  119.                     else
  120.                     {
  121.                         KProgress Progress;
  122.  
  123.                         Progress.Create(EmfScope.hinst_EmfScope, EmfScope.m_hWnd, IDD_PROGRESS, IDC_PROGRESS, IDC_NUMBER, canvas_delay);    
  124.  
  125.                         EnumEnhMetaFile(ps.hdc, hMetaFile, 
  126.                                         (ENHMFENUMPROC) SlowPaintEMF,
  127.                                         & Progress, 
  128.                                         &rect);
  129.  
  130.                         Progress.Destroy();
  131.                         SetFocus(EmfScope.m_hWnd);
  132.                     }
  133.                 else if (hNTMetaFile)
  134.                     PlayNTEnhMetaFile(ps.hdc, hNTMetaFile, &rect);
  135.  
  136.                 EndPaint(hWnd, &ps);
  137.             }
  138.             else
  139.                 return DefWindowProc(hWnd, uMsg, wParam, lParam);
  140.             break;
  141.  
  142.         
  143.         case WM_DESTROY:
  144.             if (hMetaFile)
  145.             {
  146.                 DeleteEnhMetaFile(hMetaFile);
  147.                 hMetaFile = NULL;
  148.             }
  149.  
  150.             if (hNTMetaFile)
  151.             {
  152.                 delete hNTMetaFile;
  153.                 hNTMetaFile = NULL;
  154.             }
  155.             break;
  156.  
  157.         
  158.         case WM_HSCROLL:
  159.         case WM_VSCROLL:
  160.             Scroll (uMsg, HIWORD (wParam), LOWORD(wParam));
  161.             break;
  162.  
  163.         case WM_SIZE:
  164.             SetScaleColor(0, 0);
  165.             break;
  166.  
  167.         default:
  168.             return DefWindowProc(hWnd, uMsg, wParam, lParam);
  169.     }
  170.  
  171.     return 0;
  172. }
  173.  
  174.  
  175. void KCanvasWindow::SetDelay(int delay)
  176. {
  177.     if (canvas_delay != delay)
  178.     {
  179.         canvas_delay = delay;
  180.         InvalidateRect(m_hWnd, NULL, TRUE);
  181.     }
  182. }
  183.  
  184.  
  185. void KCanvasWindow::SetScaleColor(int newscale, COLORREF backcolor)
  186. {
  187.     RECT rect;
  188.  
  189.     if ((newscale==scale) && (canvas_backcolor==backcolor))
  190.         return;
  191.  
  192.     if (backcolor)  // no black
  193.         canvas_backcolor = backcolor;
  194.  
  195.     // newscale==0 will force repaint
  196.     if (newscale) 
  197.         scale = newscale;
  198.  
  199.     GetClientRect(m_hWnd, &rect);
  200.  
  201.     if ((maxx/scale+page_margin*2) < rect.right)
  202.         ShowScrollBar(m_hWnd, SB_HORZ, FALSE);           // no scroll bar needed    
  203.     else
  204.     {
  205.         ShowScrollBar(m_hWnd, SB_HORZ, TRUE);
  206.  
  207.         EnableScrollBar(m_hWnd, SB_HORZ, ESB_ENABLE_BOTH);
  208.         SetScrollRange(m_hWnd, SB_HORZ, 0, (maxx/scale+page_margin*2) - rect.right, FALSE);
  209.     }
  210.     // always reset scrool bar position, 
  211.     // we need that inf WS_PAINT processing, even if we don't have show scroll bar
  212.     SetScrollPos(m_hWnd, SB_HORZ, 0, FALSE);
  213.     
  214.     if ((maxy/scale+page_margin*2) < rect.bottom)
  215.         ShowScrollBar(m_hWnd, SB_VERT, FALSE);
  216.     else
  217.     {    
  218.         ShowScrollBar(m_hWnd, SB_VERT, TRUE);
  219.  
  220.         SetScrollRange(m_hWnd, SB_VERT, 0, (maxy/scale+page_margin*2) - rect.bottom, FALSE);
  221.     }
  222.     // always reset scrool bar position, 
  223.     // we need that inf WS_PAINT processing, even if we don't have show scroll bar
  224.     SetScrollPos(m_hWnd, SB_VERT, 0, FALSE);
  225.     
  226.     InvalidateRect(m_hWnd, NULL, TRUE);
  227. }
  228.  
  229.  
  230. BOOL KCanvasWindow::UnloadEmfFile(const char *filename)
  231. {
  232.     if ( strcmp(filename, CurEmfFileName) == 0 )
  233.     {
  234.         if (hMetaFile)
  235.             DeleteEnhMetaFile(hMetaFile);
  236.         hMetaFile = NULL;
  237.  
  238.         if (hNTMetaFile)
  239.         {
  240.             delete hNTMetaFile;
  241.             hNTMetaFile = NULL;
  242.         }
  243.  
  244.         CurEmfFileName[0] = 0;
  245.  
  246.         InvalidateRect(m_hWnd, NULL, TRUE);    // clear the window
  247.         return TRUE;
  248.     }
  249.     else
  250.         return FALSE;
  251. }
  252.  
  253.  
  254. BOOL KCanvasWindow::LoadEmfFile(const char *filename)
  255. {
  256.     HENHMETAFILE  hNew;
  257.     int              len;
  258.  
  259.     hNew = GetEnhMetaFile(filename);
  260.     
  261.     if (hNew!=NULL)                            // standard EMF file
  262.     {
  263.         len = GetEnhMetaFileHeader(hNew, sizeof(MetaHeader), &MetaHeader);
  264.         assert(len != 0);
  265.     }
  266.     else
  267.     {
  268.         KInputFile * ntemf = new KInputFile;
  269.  
  270.         if (ntemf==NULL)
  271.             return FALSE;
  272.  
  273.         if (!ntemf->Open(filename))
  274.             return FALSE;
  275.  
  276.         if (!CheckNTSpoolEmfFile(ntemf, & MetaHeader))
  277.         {
  278.             ntemf->Close();
  279.             return FALSE;
  280.         }
  281.  
  282.         if (hNTMetaFile)
  283.             delete hNTMetaFile;
  284.  
  285.         hNTMetaFile = ntemf;
  286.     }
  287.  
  288.     if (hMetaFile)
  289.         DeleteEnhMetaFile(hMetaFile);
  290.     hMetaFile = hNew;
  291.  
  292.     strcpy(CurEmfFileName, filename);
  293.     
  294.     // make sure canvas window in visible and big enough, by resizing it's parent
  295.     EmfScope.WakeUp();
  296.     SetScaleColor(0, 0);    // force redraw with current scale
  297.  
  298.     return TRUE;
  299. }
  300.  
  301.  
  302. const char szEmfFilter[] = "Enhanced Metafiles (*.emf)\0*.emf\0"
  303.                            "Windows Metafiles (*.wmf)\0*.wmf\0"
  304.                            "WinNT Enhanced Metafiles (*.spl)\0*.spl\0"
  305.                            "All Files (*.*)\0*.*\0";
  306.  
  307.  
  308. const char *KCanvasWindow::OpenFile(void)
  309. {
  310.     OPENFILENAME    ofn;
  311.     static char     szFile[256];        // full filename with path, reply filename to caller
  312.     char            szFileTitle[256];    // filename without path
  313.  
  314.     strcpy(szFile, "");
  315.  
  316.     memset(&ofn, 0, sizeof(ofn));
  317.  
  318.     ofn.lStructSize       = sizeof(OPENFILENAME);
  319.     ofn.hwndOwner         = m_hWnd;
  320.     ofn.lpstrFilter       = szEmfFilter;
  321.     ofn.lpstrCustomFilter = (LPSTR) NULL;
  322.     ofn.nMaxCustFilter    = 0L;
  323.     ofn.nFilterIndex      = 1;
  324.     ofn.lpstrFile         = szFile;
  325.     ofn.nMaxFile          = sizeof(szFile);
  326.     ofn.lpstrFileTitle    = szFileTitle;
  327.     ofn.nMaxFileTitle     = sizeof(szFileTitle);
  328.     ofn.lpstrInitialDir   = NULL;
  329.     ofn.lpstrTitle        = "Load Metafile";
  330.     ofn.Flags             = 0L;
  331.     ofn.nFileOffset       = 0;
  332.     ofn.nFileExtension    = 0;
  333.     ofn.lpstrDefExt       = "EMF";
  334.  
  335.     if (!GetOpenFileName(&ofn))
  336.         return NULL;
  337.  
  338.     if (LoadEmfFile(szFile))
  339.         return szFile;
  340.  
  341.     return NULL;
  342. }
  343.  
  344.  
  345. BOOL KCanvasWindow::Exam(void)
  346. {
  347.     HDC  dc;
  348.     RECT rect;
  349.  
  350.     dc = GetDC(m_hWnd);
  351.  
  352.     rect.left   = 0;
  353.     rect.right  = maxx-1;
  354.     rect.top    = 0;
  355.     rect.bottom = maxy-1;
  356.  
  357. //    EnumEnhMetaFile(dc, hMetaFile, (ENHMFENUMPROC) MyEnhMetaFileProc, this, &rect);
  358.     ReleaseDC(m_hWnd, dc);
  359.     return FALSE;
  360. }
  361.  
  362.  
  363. BOOL KCanvasWindow::Print(void)
  364. {
  365.     HDC             hDCPrinter;
  366.     int             iEntries;
  367.     
  368.     if (hMetaFile == NULL) 
  369.         return FALSE;
  370.  
  371.     {
  372.         PRINTDLG        pd;
  373.     
  374.         memset(&pd, 0, sizeof(pd));
  375.         pd.lStructSize = sizeof(PRINTDLG);
  376.         pd.hwndOwner   = m_hWnd;
  377.         pd.Flags       = PD_RETURNDC;
  378.         pd.hInstance   = hInstance;
  379.  
  380.         if (!PrintDlg(&pd) || (pd.hDC==NULL)) 
  381.             return FALSE;
  382.  
  383.         hDCPrinter = pd.hDC;
  384.     }
  385.  
  386.     
  387.     {
  388.         DOCINFO         DocInfo;
  389.         char            title[128];
  390.  
  391.         // put a special tag before the title so spehon32 can ignore it
  392.         strcpy(title, ItsMe);
  393.         GetEnhMetaFileDescription(hMetaFile, sizeof(title)-strlen(title), title+strlen(title));
  394.  
  395.         memset(&DocInfo, 0, sizeof(DocInfo));
  396.         DocInfo.cbSize      = sizeof(DOCINFO);
  397.         DocInfo.lpszDocName = title;
  398.         DocInfo.lpszOutput  = NULL;
  399.         StartDoc(hDCPrinter, &DocInfo);
  400.     }
  401.  
  402.     
  403.     StartPage(hDCPrinter);
  404.     
  405.     iEntries = GetEnhMetaFilePaletteEntries(hMetaFile, 0, NULL);
  406.  
  407.     if (iEntries) 
  408.     {
  409.         PLOGPALETTE     plogPal;
  410.         PBYTE           pjTmp;
  411.         HPALETTE        hPal;
  412.  
  413.         if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  414.                 sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) 
  415.         {
  416.             MessageBox(m_hWnd, "Failed in Creating Palette!", "Error", MB_OK);
  417.         }
  418.  
  419.         plogPal->palVersion = 0x300;
  420.         plogPal->palNumEntries = (WORD) iEntries;
  421.         pjTmp = (PBYTE) plogPal;
  422.         pjTmp += 8;
  423.  
  424.         GetEnhMetaFilePaletteEntries(hMetaFile, iEntries, (PPALETTEENTRY)pjTmp);
  425.         hPal = CreatePalette(plogPal);
  426.         GlobalFree(plogPal);
  427.  
  428.         SelectPalette(hDCPrinter, hPal, FALSE);
  429.         RealizePalette(hDCPrinter);
  430.     }
  431.  
  432.  
  433.     {
  434.         RECT rc;
  435.         ENHMETAHEADER   EnhMetaHdr;
  436.     
  437.         GetEnhMetaFileHeader(hMetaFile, sizeof(ENHMETAHEADER), &EnhMetaHdr);
  438.  
  439.         rc.top    = 0;
  440.         rc.left   = 0;
  441.         rc.right  = EnhMetaHdr.szlDevice.cx;
  442.         rc.bottom = EnhMetaHdr.szlDevice.cy;
  443.         
  444.         if (!PlayEnhMetaFile(hDCPrinter, hMetaFile, &rc)) 
  445.         {
  446.             char    text[128];
  447.  
  448.             wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError());
  449.             MessageBox(0, text, "Play", MB_OK);
  450.         }
  451.     }
  452.  
  453.     EndPage(hDCPrinter);
  454.     EndDoc(hDCPrinter);
  455.  
  456.     return TRUE;
  457. }
  458.