home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_16 / EMF / EMFMain.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-24  |  17.1 KB  |  756 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   : emfmain.cpp                                                         //
  10. //  Description: EMF demo program, Chapter 16                                         //
  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.  
  26. #include "..\..\include\wingraph.h"
  27. #include "..\..\include\ListView.h"
  28. #include "..\..\include\MVC.h"
  29. #include "..\..\include\GDIObject.h"
  30. #include "..\..\include\pen.h"
  31. #include "..\..\include\filedialog.h"
  32. #include "..\..\include\treeview.h"
  33. #include "..\..\include\emf.h"
  34. #include "..\..\include\fonttext.h"
  35. #include "..\..\include\axis.h"
  36.  
  37. #include "resource.h"
  38. #include "EMFView.h"
  39.  
  40. //////////////////////////////////////////////////////////////
  41.  
  42. class KEMFResourceDialog : public KDialog
  43. {
  44.     HENHMETAFILE hEmf;
  45.  
  46.     virtual BOOL DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  47.     {
  48.         switch (uMsg)
  49.         {
  50.             case WM_INITDIALOG:
  51.                 {
  52.                     hEmf = LoadEMF((HMODULE) GetWindowLong(hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDR_EMF1));
  53.  
  54.                     SendDlgItemMessage(hWnd, IDC_EMF, STM_SETIMAGE, IMAGE_ENHMETAFILE,
  55.                         (LPARAM) hEmf);
  56.  
  57.                     return TRUE;
  58.                 }
  59.  
  60.             case WM_NCDESTROY:
  61.                 if ( hEmf )
  62.                     DeleteEnhMetaFile(hEmf);
  63.                 return TRUE;
  64.  
  65.             case WM_COMMAND:
  66.                 if ( LOWORD(wParam)==IDOK )
  67.                     EndDialog(hWnd, IDOK);
  68.                 return TRUE;
  69.         }
  70.  
  71.         return FALSE;
  72.     }
  73. };
  74.  
  75.  
  76. void Demo_EMFResource(HINSTANCE hInst)
  77. {
  78.     KEMFResourceDialog dlg;
  79.  
  80.     dlg.Dialogbox(hInst, MAKEINTRESOURCE(IDD_EMFRES));
  81. }
  82.  
  83. //////////////////////////////////////////////////////////////
  84.  
  85. void SampleDraw(HDC hDC, int x, int y)
  86. {
  87.     Ellipse(hDC, x+25, y+25, x+75, y+75);
  88.  
  89.     SetTextAlign(hDC, TA_CENTER | TA_BASELINE);
  90.  
  91.     const TCHAR * mess = "Default Font";
  92.     TextOut(hDC, x+50, y+50, "Default Font", _tcslen(mess));
  93. }
  94.  
  95.  
  96. void Demo_Scale(HDC hDC)
  97. {
  98.     HENHMETAFILE hSample1;
  99.     HENHMETAFILE hSample2;
  100.     
  101.     {
  102.         HDC hDCEMF = CreateEnhMetaFile(hDC, NULL, NULL, NULL);
  103.         SampleDraw(hDCEMF, 0, 0);
  104.         hSample1 = CloseEnhMetaFile(hDCEMF);
  105.  
  106.  
  107.         RECT rect = { 0, 0, 100, 100 };
  108.         Map10um(hDC, rect);
  109.         hDCEMF = CreateEnhMetaFile(hDC, NULL, & rect, NULL);
  110.         SampleDraw(hDCEMF, 0, 0);
  111.         hSample2 = CloseEnhMetaFile(hDCEMF);
  112.     }
  113.  
  114.     HBRUSH yellow = CreateSolidBrush(RGB(0xFF, 0xFF, 0));
  115.  
  116.     // test EMF without proper frame rectangle
  117.     {
  118.         RECT rect = { 10, 10, 10+100, 10+100 }; 
  119.         
  120.         FillRect(hDC, & rect, yellow);
  121.         SampleDraw(hDC, 10, 10); // original
  122.     }
  123.  
  124.     for (int test=0, x=120; test<3; test++)
  125.     {
  126.         RECT rect = { x, 10, x+(test/2+1)*100, 10+((test+1)/2+1)*100 };
  127.     
  128.         FillRect(hDC, & rect, yellow);
  129.         PlayEnhMetaFile(hDC, hSample1, & rect);
  130.  
  131.         x = rect.right + 10;
  132.     }
  133.  
  134.     // test EMF with proper frame rectangle
  135.     {
  136.         RECT rect = { 10, 220, 10+100, 220+100 };
  137.         
  138.         FillRect(hDC, & rect, yellow); // original
  139.         SampleDraw(hDC, 10, 220);
  140.     }
  141.  
  142.     for (test=0, x=120; test<3; test++)
  143.     {
  144.         RECT rect = { x, 220, x+(test/2+1)*100, 220+((test+1)/2+1)*100 };
  145.     
  146.         FillRect(hDC, & rect, yellow);
  147.         PlayEnhMetaFile(hDC, hSample2, & rect);
  148.  
  149.         x = rect.right + 10;
  150.     }
  151.  
  152.     DeleteObject(yellow);
  153.  
  154.     DeleteEnhMetaFile(hSample1);
  155.     DeleteEnhMetaFile(hSample2);
  156. }
  157.  
  158.  
  159. ////////////////////////////////////
  160.  
  161.  
  162. void Demo_LineCurveArea(HDC hDC)
  163. {
  164.     {
  165.         int x= 300, y = 50;
  166.  
  167.         MoveToEx(hDC, x,    y,   NULL); LineTo(hDC, x +50, y);
  168.         MoveToEx(hDC, x+50, y+1, NULL); LineTo(hDC, x+100, y+1);
  169.  
  170.         Rectangle(hDC, x,    y+10, x +50, y+60);
  171.         Rectangle(hDC, x+50, y+30, x+100, y+80);
  172.  
  173.         Ellipse(hDC, x+110, y+10, x+160, y+100);
  174.         Ellipse(hDC, x+160, y+10, x+210, y+100);
  175.  
  176.         PatBlt(hDC, x,     y+100, 100, 100, BLACKNESS);
  177.         PatBlt(hDC, x+100, y+110, 100, 100, PATINVERT);
  178.  
  179.         RECT rect = { x, y+ 250, x+100, y+350 };
  180.         FillRect(hDC, & rect, GetSysColorBrush(COLOR_3DSHADOW));
  181.  
  182.         OffsetRect(& rect, 120, 0);
  183.         FrameRect(hDC, & rect, GetSysColorBrush(COLOR_ACTIVECAPTION));
  184.  
  185.         OffsetRect(& rect, 120, 0);
  186.         InvertRect(hDC, & rect);
  187.     }
  188.  
  189.     KPen Red (PS_DOT, 0, RGB(0xFF, 0, 0));
  190.     KPen Blue(PS_SOLID, 3, RGB(0, 0, 0xFF));
  191.  
  192.     for (int z=0; z<=160; z+=40)
  193.     {
  194.         int x = 10, y = 200;
  195.  
  196.         POINT p[4] = { x, y, x+ 40, y-z, x+80, y-z, x+120, y }; x+= 136;
  197.         POINT q[4] = { x, y, x+ 40, y-z, x+80, y+z, x+120, y }; 
  198.         
  199.         Red.Select(hDC);
  200.         Polyline(hDC, p, 4);
  201.         Polyline(hDC, q, 4);
  202.         Red.UnSelect();
  203.  
  204.         Blue.Select(hDC);
  205.         PolyBezier(hDC, p, 4);
  206.         PolyBezier(hDC, q, 4);
  207.         Blue.UnSelect();
  208.     } 
  209. }
  210.  
  211.  
  212. ////////////////////////////////
  213.  
  214. const BITMAPINFO * LoadDIB(HMODULE hModule, LPCTSTR pBitmapName)
  215. {
  216.     HRSRC   hRes = FindResource(hModule, pBitmapName, RT_BITMAP);
  217.  
  218.     if ( hRes==NULL )
  219.         return NULL;
  220.  
  221.     HGLOBAL hGlb = LoadResource(hModule, hRes);
  222.  
  223.     if ( hGlb==NULL )
  224.         return NULL;
  225.  
  226.     return (const BITMAPINFO *) LockResource(hGlb);
  227. }
  228.  
  229. int GetDIBColorCount(const BITMAPINFOHEADER & bmih)
  230. {
  231.     if ( bmih.biBitCount <= 8 )
  232.         if ( bmih.biClrUsed )
  233.             return bmih.biClrUsed;
  234.         else
  235.             return 1 << bmih.biBitCount;
  236.     else if ( bmih.biCompression==BI_BITFIELDS )
  237.         return 3 + bmih.biClrUsed;
  238.     else
  239.         return bmih.biClrUsed;
  240. }
  241.  
  242.  
  243. void DispResBitmap(HDC hDC, int x, int y, int resid, int & width, int & height)
  244. {
  245.     const BITMAPINFO * pBMI = LoadDIB(
  246.         (HINSTANCE) GetWindowLong(WindowFromDC(hDC), GWL_HINSTANCE), 
  247.         MAKEINTRESOURCE(resid));
  248.     
  249.     width  = pBMI->bmiHeader.biWidth;
  250.     height = abs(pBMI->bmiHeader.biHeight);
  251.  
  252.     const BYTE * pBits = (const BYTE *) & pBMI->bmiColors[GetDIBColorCount(pBMI->bmiHeader)];
  253.  
  254.     StretchDIBits(hDC, x, y, width, height, 
  255.         0, 0, width, height, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
  256. }
  257.  
  258.  
  259. void Demo_Bitmaps(HDC hDC)
  260. {
  261.     const BITMAPINFO * pBMI = LoadDIB(
  262.         (HINSTANCE) GetWindowLong(WindowFromDC(hDC), GWL_HINSTANCE), 
  263.         MAKEINTRESOURCE(IDB_PANDA));
  264.  
  265.     // load as DIB
  266.     const BYTE * pBits = (const BYTE *) & pBMI->bmiColors[GetDIBColorCount(pBMI->bmiHeader)];
  267.     
  268.     int width  = pBMI->bmiHeader.biWidth;
  269.     int height = abs(pBMI->bmiHeader.biHeight);
  270.  
  271.     int x = 10;
  272.     int y = 10;
  273.  
  274.     // full DIB, duplication: is GDI smart enough to merge: NO
  275.     {
  276.         StretchDIBits(hDC, x, y, width, height, 0, 0, width, height, 
  277.             pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
  278.         y += height + 10;
  279.  
  280.         StretchDIBits(hDC, x, y, width, height, 0, 0, width, height, 
  281.             pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
  282.         y += height + 10;
  283.     }
  284.  
  285.     x += width + 10;
  286.     y  = 10;
  287.  
  288.     // 1/2 DIB: is GDI smart enough to split: YES
  289.     {
  290.         StretchDIBits(hDC, x, y, width, height/2, 0, height/2, width, height/2, 
  291.             pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
  292.         y += height/2 + 1;
  293.  
  294.         StretchDIBits(hDC, x, y, width, height/2, 0, 0, width, height/2, 
  295.             pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
  296.         y += height/2 + 9;
  297.     }
  298.  
  299.     // 1/4 DIB: is GDI smart enough to split: NO
  300.  
  301.     {
  302.         StretchDIBits(hDC, x, y, width/2, height/2, 
  303.             0, height/2, width/2, height/2, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
  304.  
  305.         y += height/2 + 1;
  306.  
  307.         StretchDIBits(hDC, x, y, width/2, height/2, 
  308.             0, 0, width/2, height/2, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
  309.  
  310.         y -= height/2 + 1;
  311.  
  312.         x += width/2 + 1;
  313.  
  314.         
  315.         StretchDIBits(hDC, x, y, width/2, height/2, 
  316.             width/2, height/2, width/2, height/2, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
  317.  
  318.         y += height/2 + 1;
  319.  
  320.         StretchDIBits(hDC, x, y, width/2, height/2, 
  321.             width/2, 0, width/2, height/2, pBits, pBMI, DIB_RGB_COLORS, SRCCOPY);
  322.  
  323.         y -= height/2 + 1;
  324.  
  325.         x += width/2 + 1;
  326.  
  327.     }
  328. }
  329.  
  330.  
  331. void Comment(HDC hDC, const char * mess)
  332. {
  333.     GdiComment(hDC, _tcslen(mess), (const BYTE *) mess);
  334. }
  335.  
  336.  
  337. int LineSpace(HDC hDC)
  338. {
  339.     TEXTMETRIC tm;
  340.  
  341.     GetTextMetrics(hDC, & tm);
  342.  
  343.     return tm.tmHeight + tm.tmExternalLeading;
  344. }
  345.  
  346.  
  347. void Demo_Texts(HDC hDC)
  348. {
  349.     KLogFont lf(-PointSizetoLogical(hDC, 15), "Times New Roman");
  350.     KGDIObject font(hDC, lf.CreateFont());
  351.  
  352.     KGDIObject yellowbrush(hDC, CreateSolidBrush(RGB(0xFF, 0xFF, 0))); 
  353.  
  354.     const TCHAR * mess1 = "Quick\t Brown\t Fox\t Jumps\t Over\t a\t Lazy\t Dog.";
  355.  
  356.     int x = 10, y = 10;
  357.  
  358.     SetTextAlign(hDC, TA_LEFT | TA_TOP);
  359.  
  360.     Comment(hDC, "->TextOut");
  361.     TextOut(hDC, x, y, mess1, _tcslen(mess1));
  362.     Comment(hDC, "<-TextOut");
  363.  
  364.     y += LineSpace(hDC) + 10;
  365.  
  366.     Comment(hDC, "ExtTextOut");
  367.  
  368.     ExtTextOut(hDC, x, y, 0, NULL, mess1, _tcslen(mess1), NULL);
  369.     y += LineSpace(hDC) + 10;
  370.  
  371.     int tab[1] = { 50 };
  372.  
  373.     Comment(hDC, "->TabbedTextOut");
  374.     TabbedTextOut(hDC, x, y, mess1, _tcslen(mess1), 1, tab, x);
  375.     Comment(hDC, "<-TabbedTextOut");
  376.  
  377.     y += LineSpace(hDC) + 10;
  378.  
  379.     {
  380.  
  381.         const TCHAR * mess = 
  382.             "The DrawText function draws formatted text in the specified rectangle. "
  383.             "It formats the text according to the specified method (expanding tabs, "
  384.             "justifying characters, breaking lines, and so forth).";
  385.  
  386.         int width = 250;
  387.         int x     =  20;
  388.         RECT rect = { x, y, x+width, y+200 };
  389.     
  390.         SetTextAlign(hDC, TA_LEFT | TA_TOP | TA_NOUPDATECP);
  391.  
  392.         Comment(hDC, "->DrawText");
  393.         DrawText(hDC, mess, _tcslen(mess), & rect, DT_WORDBREAK | DT_LEFT);
  394.         Comment(hDC, "<-DrawText");
  395.     }
  396. }
  397.  
  398.  
  399. //////////////////////////////////////////
  400.  
  401. void Demo_Mapping(HDC hDC)
  402. {
  403.     KLogFont lf(-PointSizetoLogical(hDC, 16), "Times New Roman");
  404.     KGDIObject font(hDC, lf.CreateFont());
  405.  
  406.     KGDIObject yellowbrush(hDC, CreateSolidBrush(RGB(0xFF, 0xFF, 0))); 
  407.  
  408.     const TCHAR * mess = "A Quick Brown Fox Jumps Over a Lazy Dog.";
  409.     const TCHAR * mes2 = "Jackdaws Love My Big Sphinx of Quartz.";
  410.     int x = 0, y = 0;
  411.  
  412.     SetTextAlign(hDC, TA_LEFT | TA_CENTER);
  413.     
  414.     SetMapMode(hDC, MM_ANISOTROPIC);
  415.     SetViewportExtEx(hDC, 1, -1, 0);
  416.     SetViewportOrgEx(hDC, 200, 100, NULL);
  417.  
  418.     TextOut(hDC, x, y,      mess, _tcslen(mess));
  419.     TextOut(hDC, x, y+24, mes2, _tcslen(mes2));
  420.  
  421.     ShowAxes(hDC, 400, 200);
  422. }
  423.  
  424.  
  425. class KDemoView : public KView
  426. {
  427.     int        m_nCommand;
  428.     
  429.     virtual int OnDraw(HDC hDC, const RECT * rcPaint)
  430.     {
  431.         switch ( m_nCommand )
  432.         {
  433.             case IDM_VIEW_SCALE:
  434.                 Demo_Scale(hDC);
  435.                 break;
  436.  
  437.             case IDM_VIEW_LINECURVE:
  438.                 Demo_LineCurveArea(hDC);
  439.                 break;
  440.  
  441.             case IDM_VIEW_BITMAPS:
  442.                 Demo_Bitmaps(hDC);
  443.                 break;
  444.  
  445.             case IDM_VIEW_TEXT:
  446.                 Demo_Texts(hDC);
  447.                 break;
  448.  
  449.             case IDM_VIEW_MAPPING:
  450.                 Demo_Mapping(hDC);
  451.         }
  452.  
  453.         return View_NoChange;
  454.     }
  455.  
  456.     
  457. public:
  458.  
  459.     virtual int OnCommand(int cmd, HWND hWnd)
  460.     {
  461.         if ( cmd==m_nCommand )
  462.             return View_NoChange;
  463.  
  464.         switch ( cmd )
  465.         {
  466.             case IDM_VIEW_SCALE:
  467.                 m_nCommand = cmd;
  468.                 SetWindowText(hWnd, "EMF Scaling");
  469.                 return View_Redraw;
  470.  
  471.             case IDM_VIEW_LINECURVE:
  472.                 m_nCommand = cmd;
  473.                 SetWindowText(hWnd, "Lines, Curves, and Areas in EMF");
  474.                 return View_Redraw;
  475.  
  476.             case IDM_VIEW_BITMAPS:
  477.                 m_nCommand = cmd;
  478.                 SetWindowText(hWnd, "Bitmaps in EMF");
  479.                 return View_Redraw;
  480.  
  481.             case IDM_VIEW_TEXT:
  482.                 m_nCommand = cmd;
  483.                 SetWindowText(hWnd, "Texts in EMF");
  484.                 return View_Redraw;
  485.  
  486.             case IDM_VIEW_MAPPING:
  487.                 m_nCommand = cmd;
  488.                 SetWindowText(hWnd, "Mapping Mode in EMF");
  489.                 return View_Redraw;
  490.  
  491.             case IDM_FILE_SAVE:
  492.                 {
  493.                     RECT rect;
  494.  
  495.                     GetClientRect(hWnd, & rect);
  496.  
  497.                     HDC hDC = GetDC(hWnd);
  498.                     Map10um(hDC, rect);
  499.                     ReleaseDC(hWnd, hDC);
  500.  
  501.                     hDC = QuerySaveEMFFile("EMF Sample\0", & rect, NULL);
  502.  
  503.                     if ( hDC )
  504.                     {
  505.                         OnDraw(hDC, NULL);
  506.                         HENHMETAFILE hEmf = CloseEnhMetaFile(hDC);
  507.                         DeleteEnhMetaFile(hEmf);
  508.                     }
  509.                 }
  510.                 break;
  511.  
  512.             case IDM_EDIT_COPY:
  513.                 {
  514.                     HDC hDC = CreateEnhMetaFile(NULL, NULL, NULL, NULL);
  515.                     
  516.                     if ( hDC )
  517.                     {
  518.                         OnDraw(hDC, NULL);
  519.  
  520.                         HENHMETAFILE hEmf = CloseEnhMetaFile(hDC);
  521.                         CopyToClipboard(hWnd, hEmf);
  522.                         DeleteEnhMetaFile(hEmf);
  523.                     }
  524.                     else
  525.                         assert(false);
  526.                 }
  527.                 break;
  528.         }
  529.  
  530.         return View_NoChange;
  531.     }
  532.     
  533.     KDemoView(void)
  534.     {
  535.         m_nCommand  = IDM_VIEW_LINECURVE;
  536.     }
  537. };
  538.  
  539.  
  540. ////////////////////////// MDI Frame Window
  541.  
  542. const int Translate[] =
  543. {
  544.     IDM_FILE_CLOSE,
  545.     IDM_FILE_EXIT,
  546.     IDM_WINDOW_TILE,
  547.     IDM_WINDOW_CASCADE,
  548.     IDM_WINDOW_ARRANGE,
  549.     IDM_WINDOW_CLOSEALL
  550. };
  551.  
  552.  
  553. HENHMETAFILE TestEMFGen(void)
  554. {
  555.     RECT rect;
  556.  
  557.     HDC hdcRef = GetDC(NULL);
  558.  
  559.     GetClientRect(GetDesktopWindow(), &rect);
  560.     Map10um(hdcRef, rect);
  561.  
  562.     HDC hDC = CreateEnhMetaFile(hdcRef, "c:\\test.emf", & rect, "EMF.EXE\0TestEMF\0");
  563.  
  564.     ReleaseDC(NULL, hdcRef);
  565.  
  566.     if ( hDC )
  567.     {
  568.         GetClientRect(GetDesktopWindow(), &rect);
  569.  
  570.         Rectangle(hDC, rect.right/3, rect.bottom/3, rect.right*2/3, rect.bottom*2/3);
  571.         
  572.         HENHMETAFILE hEmf = CloseEnhMetaFile(hDC);
  573.  
  574.         if ( hEmf )
  575.             MyMessageBox(NULL, _T("c:\\test.emf generated."), _T("EMF"), MB_OK, IDI_GRAPH);
  576.         else
  577.             MyMessageBox(NULL, _T("c:\\test.emf generation failed."), _T("EMF"), MB_OK, IDI_GRAPH);
  578.  
  579.         return hEmf;
  580.     }
  581.     
  582.     return NULL;
  583. }
  584.  
  585.  
  586. class KMyMDIFrame : public KMDIFrame
  587. {
  588.     HWND            m_Children[100];
  589.     int                m_nChild;
  590.  
  591.     void CreateMDIChild(KCanvas * canvas, const TCHAR * klass, const TCHAR * title)
  592.     {
  593.         MDICREATESTRUCT mdic;
  594.  
  595.         mdic.szClass = klass;
  596.         mdic.szTitle = title;
  597.         mdic.hOwner  = m_hInst;
  598.         mdic.x       = CW_USEDEFAULT;
  599.         mdic.y       = CW_USEDEFAULT;
  600.         mdic.cx      = CW_USEDEFAULT;
  601.         mdic.cy      = CW_USEDEFAULT;
  602.         mdic.style   = WS_VISIBLE | WS_BORDER;
  603.         mdic.lParam  = (LPARAM) canvas;
  604.  
  605.         HWND hWnd = (HWND) SendMessage(m_hMDIClient, WM_MDICREATE, 0, (LPARAM) & mdic);
  606.  
  607.         if ( (hWnd) && (m_nChild<100) )
  608.             m_Children[m_nChild++] = hWnd;
  609.     }
  610.  
  611.     BOOL CreateCanvas(KView * pView, const TCHAR * Title)
  612.     {
  613.         if ( pView==NULL )
  614.             return FALSE;
  615.  
  616.         KMDICanvas   * pCanvas = new KMDICanvas();
  617.  
  618.         if ( pCanvas )
  619.         {
  620.             if ( pCanvas->Initialize(m_hInst, m_pStatus, pView, IDR_DEMO, IDI_GRAPH) )
  621.             {
  622.                 CreateMDIChild(pCanvas, pCanvas->GetClassName(), Title);
  623.                 return TRUE;
  624.             }
  625.  
  626.             delete pCanvas;
  627.         }
  628.  
  629.         delete pView;
  630.         return FALSE;
  631.     }
  632.  
  633.     virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam)
  634.     {
  635.         switch ( LOWORD(wParam) )
  636.         {
  637.             case IDM_FILE_DEMO:
  638.                 CreateCanvas(new KDemoView(), _T("Demo - "));
  639.                 return TRUE;
  640.  
  641.             case IDM_FILE_SIMPLEEMF:
  642.                 {
  643.                     HENHMETAFILE hEmf = TestEMFGen();
  644.                     DeleteEnhMetaFile(hEmf);
  645.                 }
  646.                 return TRUE;
  647.  
  648.             case IDM_FILE_OPEN:
  649.                 {
  650.                     TCHAR filename[MAX_PATH];
  651.  
  652.                     filename[0] = 0;
  653.                     HENHMETAFILE hEmf = QueryOpenEMFFile(filename);
  654.  
  655.                     if ( hEmf || filename[0] )
  656.                     {
  657.                         KEMFView * pView = new KEMFView;
  658.  
  659.                         if ( pView )
  660.                             if ( pView->Initialize(m_hInst, m_pStatus, m_hWnd, hEmf, filename) )
  661.                                 CreateMDIChild(pView, _T("EMFViewClass"), filename);
  662.                             else
  663.                                 delete pView;
  664.                     }
  665.                 }
  666.                 return TRUE;
  667.             
  668.             case IDM_FILE_EMFRES:
  669.                 Demo_EMFResource(m_hInst);
  670.                 return TRUE;
  671.  
  672.             case IDM_EDIT_PASTE:
  673.                 {
  674.                     HENHMETAFILE hEmf = PasteFromClipboard(m_hWnd);
  675.  
  676.                     if ( hEmf )
  677.                     {
  678.                         KEMFView * pView = new KEMFView;
  679.  
  680.                         if ( pView )
  681.                             if ( pView->Initialize(m_hInst, m_pStatus, m_hWnd, hEmf, NULL) )
  682.                                 CreateMDIChild(pView, _T("EMFViewClass"), "Clipbpard");
  683.                             else
  684.                                 delete pView;
  685.                     }
  686.                 }
  687.                 return TRUE;
  688.         }
  689.  
  690.         return FALSE;
  691.     }
  692.  
  693.     virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  694.     {
  695.         switch ( uMsg )
  696.         {
  697.             case WM_PALETTECHANGED:
  698.                 {
  699.                     if ( hWnd != (HWND) wParam )
  700.                         for (int i=0; i<m_nChild; i++)
  701.                             SendMessage(m_Children[i], uMsg, wParam, lParam);
  702.                 }
  703.                 return 0;
  704.         }
  705.  
  706.         return KMDIFrame::WndProc(hWnd, uMsg, wParam, lParam);
  707.     }
  708.  
  709.     
  710.     void GetWndClassEx(WNDCLASSEX & wc)
  711.     {
  712.         KMDIFrame::GetWndClassEx(wc);
  713.         wc.hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_GRAPH));
  714.     }
  715.  
  716. public:
  717.     KMyMDIFrame(HINSTANCE hInstance, const TBBUTTON * pButtons, int nCount,
  718.         KToolbar * pToolbar, KStatusWindow * pStatus) :
  719.         KMDIFrame(hInstance, pButtons, nCount, pToolbar, pStatus, Translate)
  720.     {
  721.         m_nChild = 0;
  722.     }
  723. };
  724.  
  725.  
  726. const TBBUTTON tbButtons[] =
  727. {
  728.     { STD_FILENEW,     IDM_FILE_NEW,   TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, IDS_FILENEW,  0 },
  729.     { STD_FILEOPEN,  IDM_FILE_OPEN,  TBSTATE_ENABLED, TBSTYLE_BUTTON, { 0, 0 }, IDS_FILEOPEN, 0 }
  730. };
  731.  
  732.  
  733. HINSTANCE hModule;
  734.  
  735. int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nShow)
  736. {
  737.     KToolbar      toolbar;
  738.     KStatusWindow status;
  739.  
  740.     hModule = hInst;
  741.  
  742.     KMyMDIFrame frame(hInst, tbButtons, 2, & toolbar, & status);
  743.     
  744.     frame.CreateEx(0, _T("ClassName"), _T("EMF"),
  745.         WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  746.         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
  747.         NULL, LoadMenu(hInst, MAKEINTRESOURCE(IDR_MAIN)), hInst);
  748.  
  749.     frame.ShowWindow(nShow);
  750.     frame.UpdateWindow();
  751.  
  752.     frame.MessageLoop();
  753.  
  754.     return 0;
  755. }
  756.