home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / vrac / mfedit32.zip / MFEDIT.C < prev    next >
C/C++ Source or Header  |  1994-09-04  |  162KB  |  4,688 lines

  1. /******************************Module*Header*******************************\
  2. * Module Name: mfedit.c
  3. *
  4. * Main module for the Enhanced Metafile Editor
  5. *       contains everything
  6. *
  7. * Created: 28-May-1992 14:24:00
  8. * Author: Petrus Wong
  9. *
  10. * Copyright (c) 1992 Microsoft Corporation
  11. *
  12. * The Enhanced Metafile Editor serves to demonstrate the enhanced metafile
  13. * APIs in Windows NT.
  14. *
  15. * The Editor provides the following functions:
  16. *       1.  Playback and recording of GDI calls
  17. *       2.  Embedding bitmap and enhanced metafile into another enhanced
  18. *           metafile with transformation
  19. *       3.  Hit-testing against enhanced metafile records
  20. *       4.  Random access playback
  21. *       5.  Playback metafile records one-by-one
  22. *       6.  Selective recording of existing enhanced metafile records into
  23. *           a new enhanced metafile
  24. *       7.  drawing with pen, text, bezier, line, ellipse, rectangle and
  25. *           embedding bitmap and enhanced metafile tools
  26. *
  27. * Dependencies:
  28. *
  29. *   metadef.h   - contains definition for enhanced metafile records
  30. *
  31. \**************************************************************************/
  32. #include <stdlib.h>
  33. #include "mfedit.h"
  34. #include <stdarg.h>
  35. #include <string.h>
  36. #include <stdio.h>
  37. #include <commdlg.h>
  38. #include <shellapi.h>
  39. #include <math.h>
  40.  
  41.  
  42. #if 0
  43. //
  44. // TEST!!!
  45. //
  46. HBITMAP hbmp;
  47.  
  48.  
  49. typedef struct tagLOGPAL {
  50.     WORD        palVersion;
  51.     WORD        palNumEntries;
  52.     PALETTEENTRY        palPalEntry[48];
  53. } LOGPAL;
  54.  
  55. #define exp 17        // explicit entries on end
  56. #define pb 6        // palette base
  57.  
  58. HPALETTE hPal, hOldPal;
  59. LOGPAL LogPal =
  60. {
  61.     0x300, pb+16+9+exp,
  62.     {
  63. #if pb
  64.            { 0,    0,    0,    PC_RESERVED  },
  65.            { 0,    0,    0,    PC_RESERVED  },
  66.            { 0,    0,    0,    PC_RESERVED  },
  67.            { 0,    0,    0,    PC_RESERVED  },
  68.            { 0,    0,    0,    PC_RESERVED  },
  69.            { 0,    0,    0,    PC_RESERVED  },
  70. #endif
  71.            { 0,    0,    0,    PC_RESERVED  }, // black
  72.            { 0,    0,    255,  PC_RESERVED  }, // blue
  73.            { 255,  0,    0,    PC_RESERVED  }, // red
  74.            { 0,    255,  0,    PC_RESERVED  }, // green
  75.            { 255,  0,    255,  PC_RESERVED  }, // magenta
  76.            { 0,    255,  255,  PC_RESERVED  }, // cyan
  77.            { 255,  255,  0,    PC_RESERVED  }, // yellow
  78.            { 192,  192,  192,  PC_RESERVED  }, // white
  79.            { 96,   96,   96,   PC_RESERVED  }, // dark grey
  80.            { 0,    0,    185,  PC_RESERVED  }, // blue
  81.            { 185,  0,    0,    PC_RESERVED  }, // red
  82.            { 0,    185,  0,    PC_RESERVED  }, // green
  83.            { 185,  0,    185,  PC_RESERVED  }, // magenta
  84.            { 0,    185,  185,  PC_RESERVED  }, // cyan
  85.            { 185,  185,  0,    PC_RESERVED  }, // yellow
  86.            { 255,  255,  255,  PC_RESERVED  }, // white
  87.            { 0,    0,    0,    PC_RESERVED  },
  88.            { 0,    0,    0,    PC_RESERVED  },
  89.            { 0,    0,    0,    PC_RESERVED  },
  90.            { 0,    0,    0,    PC_RESERVED  },
  91.            { 0,    0,    0,    PC_RESERVED  },
  92.            { 0,    0,    0,    PC_RESERVED  },
  93.            { 0,    0,    0,    PC_RESERVED  },
  94.            { 0,    0,    0,    PC_RESERVED  },
  95.            { 0,    0,    0,    PC_RESERVED  },
  96.            { 0,    0,    0,    PC_EXPLICIT  }, // physical palette index 0 (Windows black)
  97.            { 1,    0,    0,    PC_EXPLICIT  }, // physical palette index 1
  98.            { 2,    0,    0,    PC_EXPLICIT  }, // physical palette index 2
  99.            { 3,    0,    0,    PC_EXPLICIT  }, // physical palette index 3
  100.            { 4,    0,    0,    PC_EXPLICIT  }, // physical palette index 4
  101.            { 5,    0,    0,    PC_EXPLICIT  }, // physical palette index 5
  102.            { 6,    0,    0,    PC_EXPLICIT  }, // physical palette index 6
  103.            { 7,    0,    0,    PC_EXPLICIT  }, // physical palette index 7
  104.            { 8,    0,    0,    PC_EXPLICIT  }, // physical palette index 8
  105.            { 9,    0,    0,    PC_EXPLICIT  }, // physical palette index 9
  106.            { 10,   0,    0,    PC_EXPLICIT  }, // physical palette index 10
  107.            { 11,   0,    0,    PC_EXPLICIT  }, // physical palette index 11
  108.            { 12,   0,    0,    PC_EXPLICIT  }, // physical palette index 12
  109.            { 13,   0,    0,    PC_EXPLICIT  }, // physical palette index 13
  110.            { 14,   0,    0,    PC_EXPLICIT  }, // physical palette index 14
  111.            { 15,   0,    0,    PC_EXPLICIT  }, // physical palette index 15
  112.            { 255,  0,    0,    PC_EXPLICIT  }  // Windows white
  113.     }
  114. };
  115.  
  116. typedef struct BMAPINFO
  117. {
  118.     BITMAPINFOHEADER    bmiHeader;
  119.     union
  120.     {
  121.         WORD            awColors[16];
  122.         RGBQUAD            aRGBQuad[16];
  123.     } u;
  124. } BMAPINFO;
  125.  
  126. BMAPINFO DIBHdr =
  127. {
  128.     {
  129.         sizeof(BITMAPINFOHEADER),    // biSize
  130.         64,                // biWidth
  131.         64,                // biHeight
  132.         1,                // biPlanes
  133.         4,                // biBitCount
  134.         BI_RGB,                // biCompression
  135.         2048,                // biSizeImage
  136.         0,                // biXPelsPerMeter
  137.         0,                // biYPelsPerMeter
  138.         0,                // biClrUsed
  139.         0                // biClrImportant
  140.     },
  141.     // Here the indices map 1 to 1 with our logical palette, they may change
  142.     // depending on the index of the first color but they always follow in order:
  143.     {{0+pb,1+pb,2+pb,3+pb,4+pb,5+pb,6+pb,7+pb,8+pb,9+pb,10+pb,11+pb,12+pb,13+pb,14+pb,15+pb}}
  144. };
  145.  
  146. static BYTE dib[] = {
  147.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  148.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  149.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  150.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  151.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  152.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  153.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  154.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  155.     0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
  156.     0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
  157.     0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
  158.     0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
  159.     0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
  160.     0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
  161.     0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
  162.     0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
  163.     0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
  164.     0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
  165.     0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
  166.     0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
  167.     0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
  168.     0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
  169.     0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
  170.     0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
  171.     0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
  172.     0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
  173.     0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
  174.     0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
  175.     0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
  176.     0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
  177.     0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
  178.     0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
  179.     0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  180.     0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  181.     0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  182.     0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  183.     0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  184.     0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  185.     0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  186.     0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  187.     0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  188.     0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  189.     0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  190.     0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  191.     0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  192.     0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  193.     0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  194.     0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  195.     0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
  196.     0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
  197.     0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
  198.     0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
  199.     0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
  200.     0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
  201.     0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
  202.     0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
  203.     0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
  204.     0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
  205.     0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
  206.     0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
  207.     0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
  208.     0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
  209.     0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
  210.     0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
  211.     0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
  212.     0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
  213.     0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
  214.     0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
  215.     0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
  216.     0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
  217.     0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
  218.     0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
  219.     0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
  220.     0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
  221.     0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
  222.     0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
  223.     0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
  224.     0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
  225.     0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
  226.     0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
  227.     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  228.     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  229.     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  230.     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  231.     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  232.     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  233.     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  234.     0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  235.     0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
  236.     0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
  237.     0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
  238.     0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
  239.     0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
  240.     0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
  241.     0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
  242.     0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
  243.     0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
  244.     0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
  245.     0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
  246.     0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
  247.     0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
  248.     0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
  249.     0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
  250.     0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
  251.     0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
  252.     0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
  253.     0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
  254.     0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
  255.     0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
  256.     0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
  257.     0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
  258.     0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
  259.     0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
  260.     0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
  261.     0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
  262.     0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
  263.     0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
  264.     0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
  265.     0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
  266.     0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
  267.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  268.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  269.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  270.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  271.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  272.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  273.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  274.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  275. };
  276. #endif
  277.  
  278.  
  279. //
  280. // Forward declarations.
  281. //
  282. BOOL InitializeApp   (void);
  283. LONG APIENTRY MainWndProc     (HWND, UINT, DWORD, LONG);
  284. LONG APIENTRY DrawSurfWndProc (HWND, UINT, DWORD, LONG);
  285. BOOL CALLBACK About           (HWND, UINT, DWORD, LONG);
  286. LONG APIENTRY TextWndProc     (HWND, UINT, DWORD, LONG);
  287. LONG APIENTRY CtrlPanelDlgProc(HWND, UINT, DWORD, LONG);
  288. BOOL bDrawStuff      (HDC, INT, INT, INT, INT, BOOL, BOOL, BOOL, LPSTR);
  289. HENHMETAFILE hemfLoadMetafile(HWND);
  290. HDC  hDCRecordMetafileAs(HWND, LPSTR);
  291. BOOL APIENTRY bPlayRecord(HDC, LPHANDLETABLE, LPENHMETARECORD, UINT, LPVOID);
  292. BOOL APIENTRY bDoHitTest(HDC, LPHANDLETABLE, LPENHMETARECORD, UINT, LPVOID);
  293. BOOL bHitTest(HDC, INT, INT);
  294. HBITMAP hBmpLoadBitmapFile(HDC, PSTR);
  295. BOOL bGetBMP(HWND, BOOL);
  296. BOOL bChooseNewFont(HWND, PLOGFONT, COLORREF * );
  297. BOOL bChooseNewColor(HWND, LPDWORD);
  298. BOOL bPrintMf(PPRTDATA);
  299. HBRUSH hBrCreateBrush(HDC, DWORD);
  300. BOOL bSelectDIBPal(HDC, LPBITMAPINFO, BOOL);
  301. BOOL bFreeDibFile(PDIBDATA);
  302. BOOL bPlgBlt(HDC, LPPOINT);
  303. HPALETTE CopyPalette(HPALETTE hPalSrc);
  304. int CALLBACK iTT(LPLOGFONT, LPTEXTMETRIC, DWORD, LPARAM);
  305. CMTMLTFMT *pLoadMltFmtFile(VOID);
  306. HLOCAL Free(CMTMLTFMT *pMfmt);
  307. BOOL bGetEPSBounds(LPVOID, RECTL *);
  308. BOOL bIsAdobe(char *szStr);
  309. BOOL bIsEPS(char *szStr);
  310. BOOL bIsBndBox(char *szStr);
  311. BOOL bIsEOF(char *szStr);
  312. //BOOL bGetWord(LPVOID, char *, char **);
  313. //BOOL bGoNextLine(LPVOID, char **);
  314. BOOL bGetWord(LPVOID, char *, int*);
  315. BOOL bGoNextLine(LPVOID, int*);
  316.  
  317. /***************************************************************************\
  318. * WinMain
  319. *
  320. * History:
  321. * 11-Feb-1992   Petrus Wong
  322. \***************************************************************************/
  323. int WINAPI WinMain(
  324. #if 0
  325.            HANDLE hInstance,
  326.            HANDLE hPrevInstance,
  327. #endif
  328.            HINSTANCE hInstance,
  329.            HINSTANCE hPrevInstance,
  330.            LPSTR lpCmdLine,
  331.            int nShowCmd)
  332. {
  333.     MSG    msg;
  334.     HANDLE hAccel;
  335.  
  336.     ghModule = GetModuleHandle(NULL);
  337.     if (!InitializeApp()) {
  338.     MessageBox(ghwndMain, "MfEdit: InitializeApp failure!", "Error", MB_OK);
  339.         return 0;
  340.     }
  341.  
  342.     if (!(hAccel = LoadAccelerators (ghModule, MAKEINTRESOURCE(ACCEL_ID))))
  343.     MessageBox(ghwndMain, "MfEdit: Load Accel failure!", "Error", MB_OK);
  344.  
  345.  
  346.     while (GetMessage(&msg, NULL, 0, 0)) {
  347.         if (!TranslateAccelerator( ghwndMain, hAccel, &msg) ) {
  348.             TranslateMessage(&msg);
  349.             DispatchMessage(&msg);
  350.         }
  351.     }
  352.  
  353.     return 1;
  354.  
  355.     UNREFERENCED_PARAMETER(lpCmdLine);
  356.     UNREFERENCED_PARAMETER(nShowCmd);
  357.     UNREFERENCED_PARAMETER(hInstance);
  358.     UNREFERENCED_PARAMETER(hPrevInstance);
  359. }
  360.  
  361.  
  362. /***************************************************************************\
  363. * InitializeApp
  364. *
  365. * History:
  366. * 11-Feb-1992   Petrus Wong
  367. *   Name changes.
  368. * 09-09-91      Petrus Wong    Created.
  369. \***************************************************************************/
  370.  
  371. BOOL InitializeApp(void)
  372. {
  373.     WNDCLASS wc;
  374.     int index;
  375.     HDC hDC;
  376.  
  377.     wc.style            = CS_DBLCLKS;
  378.     wc.lpfnWndProc      = (WNDPROC)MainWndProc;
  379.     wc.cbClsExtra       = 0;
  380.     wc.cbWndExtra    = sizeof(DWORD);
  381.     wc.hInstance        = ghModule;
  382.     wc.hIcon            = LoadIcon(ghModule, MAKEINTRESOURCE(APP_ICON));
  383.     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
  384.     wc.hbrBackground    = (HBRUSH)(COLOR_APPWORKSPACE + 1);
  385.     wc.lpszMenuName     = "MainMenu";
  386.     wc.lpszClassName    = "MetafDemoClass";
  387.  
  388.     if (!RegisterClass(&wc))
  389.     return FALSE;
  390.  
  391.     wc.style            = CS_OWNDC | CS_SAVEBITS;
  392.     wc.lpfnWndProc      = (WNDPROC)DrawSurfWndProc;
  393.     wc.hIcon            = NULL;
  394.     wc.hCursor          = NULL;
  395.     wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW + 1);
  396.     wc.lpszMenuName     = NULL;
  397.     wc.lpszClassName    = "DrawSurfClass";
  398.  
  399.     if (!RegisterClass(&wc))
  400.     return FALSE;
  401.  
  402.     wc.style        = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  403.     wc.lpfnWndProc    = (WNDPROC)TextWndProc;
  404.     wc.hIcon        = NULL;
  405.     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
  406.     wc.hbrBackground    = (HBRUSH)(COLOR_BTNFACE + 1);
  407.     wc.lpszMenuName    = NULL;
  408.     wc.lpszClassName    = "Text";
  409.  
  410.     if (!RegisterClass(&wc))
  411.             return FALSE;
  412.  
  413.  
  414.  
  415.     hMenu    = LoadMenu(ghModule, "MainMenu");
  416.  
  417.     for (index = 0; index < OD_BTN_CNT; index++) {
  418.         ghBmpDn[index] = (PVOID)LoadBitmap(ghModule, (LPCSTR)MAKEINTRESOURCE(BMID_BASED+index));
  419.         ghBmpUp[index] = (PVOID)LoadBitmap(ghModule, (LPCSTR)MAKEINTRESOURCE(BMID_BASEU+index));
  420.     }
  421.     for (index = 0; index < OD_TOOL_CNT; index++) {
  422.         ghToolBmpDn[index] = (PVOID)LoadBitmap(ghModule, (LPCSTR)MAKEINTRESOURCE(BMID_TOOLBASED+index));
  423.         ghToolBmpUp[index] = (PVOID)LoadBitmap(ghModule, (LPCSTR)MAKEINTRESOURCE(BMID_TOOLBASEU+index));
  424.  
  425.     }
  426.  
  427.     ghwndMain = CreateWindowEx(0L, "MetafDemoClass", "Enhanced Metafile Editor",
  428.         WS_OVERLAPPED   | WS_CAPTION     | WS_BORDER       |
  429.         WS_THICKFRAME   | WS_MAXIMIZEBOX | WS_MINIMIZEBOX  |
  430.         WS_CLIPCHILDREN | WS_VISIBLE     | WS_SYSMENU,
  431.             80, 70, 600, 300,
  432.         NULL, hMenu, ghModule, NULL);
  433.  
  434.     if (ghwndMain == NULL)
  435.     return FALSE;
  436.  
  437.     SetWindowLong(ghwndMain, GWL_USERDATA, 0L);
  438.     ghwndNext = SetClipboardViewer(ghwndMain);
  439.  
  440.     if (gbFit2Wnd)
  441.         CheckMenuItem(hMenu, MM_FIT2WND, MF_CHECKED);
  442.     else
  443.         CheckMenuItem(hMenu, MM_FIT2WND, MF_UNCHECKED);
  444.  
  445.     if (gbImport3X)
  446.         CheckMenuItem(hMenu, MM_IMPORT_3X, MF_CHECKED);
  447.     else
  448.         CheckMenuItem(hMenu, MM_IMPORT_3X, MF_UNCHECKED);
  449.  
  450.     if (gbExport3X)
  451.         CheckMenuItem(hMenu, MM_EXPORT_3X, MF_CHECKED);
  452.     else
  453.         CheckMenuItem(hMenu, MM_EXPORT_3X, MF_UNCHECKED);
  454.  
  455.     SetFocus(ghwndMain);    /* set initial focus */
  456.  
  457.     gDib.ulFiles = gDib.ulFrames = 0;
  458.     hDC = GetDC(NULL);
  459.     ghHT = CreateHalftonePalette(hDC);
  460.     ReleaseDC(NULL, hDC);
  461.  
  462.     return TRUE;
  463. }
  464.  
  465.  
  466. /***************************************************************************\
  467. * MainWndProc
  468. *
  469. * History:
  470. * 11-Feb-1992   Petrus Wong
  471. *   Name changes.  Added comments.
  472. * 09-09-91      Petrus Wong    Created.
  473. \***************************************************************************/
  474.  
  475. long APIENTRY MainWndProc(
  476.     HWND hwnd,
  477.     UINT message,
  478.     DWORD wParam,
  479.     LONG lParam)
  480. {
  481.     static int         iMetafCnt=0;
  482.     static char        szFilename[256] = "c:\\metaf";
  483.     static BOOL        bReset=FALSE;
  484.     static char        szLoadedMetaf[256] = " ";
  485.  
  486.     switch (message) {
  487.  
  488.       case WM_CREATE: {
  489.  
  490.     SetWindowLong(hwnd, 0, (LONG)NULL);
  491.         ghDCMem = CreateCompatibleDC(NULL);
  492.  
  493.         ghwndCtrlPanel = CreateDialog(ghModule, (LPCSTR)MAKEINTRESOURCE(DID_CTRLPANEL),
  494.                      hwnd, (DLGPROC) CtrlPanelDlgProc);
  495.  
  496.         ghwndDrawSurf = CreateWindow("DrawSurfClass", NULL,
  497.                                     WS_BORDER | WS_CHILD | WS_VISIBLE,
  498.                                     0, 0, 0, 0,
  499.                                     hwnd,
  500.                                     NULL,
  501.                                     ghModule,
  502.                                     NULL);
  503.  
  504.         ghTextWnd = CreateWindow("Text", NULL,
  505.                                 WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
  506.                                 0, 0, 0, 0,
  507.                                 hwnd,
  508.                                 NULL,               //(HMENU) 2,
  509.                                 ghModule,
  510.                                 NULL);
  511.  
  512.         ghbrRed = CreateSolidBrush(RGB(255, 0, 0));
  513.         ghbrAppBkgd = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));
  514.         ghpnWide = CreatePen(PS_SOLID, 5, RGB(0, 0, 0));
  515.         return 0L;
  516.       }
  517.       case WM_DRAWCLIPBOARD:
  518.         if ((IsClipboardFormatAvailable(CF_METAFILEPICT)) ||
  519.             (IsClipboardFormatAvailable(CF_ENHMETAFILE)) )
  520.             EnableMenuItem(hMenu, MM_PASTE, MF_ENABLED);
  521.         else
  522.             EnableMenuItem(hMenu, MM_PASTE,  MF_GRAYED);
  523.  
  524.         if (ghwndNext)
  525.             SendMessage(ghwndNext, message, wParam, lParam);
  526.         return 0L;
  527.  
  528.       case WM_SIZE: {
  529.           RECT        rc;
  530.           LONG        lcyCtrlPanel, lcyDrawSurf;
  531.  
  532.           GetWindowRect(ghwndCtrlPanel, &rc);
  533.           lcyCtrlPanel = rc.bottom-rc.top;
  534.           lcyDrawSurf = HIWORD(lParam) - lcyCtrlPanel - glcyStatus;
  535.  
  536.           //
  537.           // CR!! Alternatively, this window can be created with cy
  538.           //      equals to cy of the screen and saving this call
  539.           //      altogether.
  540.           //
  541.           MoveWindow(ghwndCtrlPanel,
  542.                      0, 0, LOWORD(lParam), lcyCtrlPanel, TRUE);
  543.  
  544.           //
  545.           // This ordering guarantees the text window paints correctly
  546.           //
  547.           MoveWindow(ghTextWnd,
  548.                      0, lcyCtrlPanel + lcyDrawSurf,
  549.                      LOWORD(lParam),                    // cx of hwnd
  550.                      glcyStatus, TRUE);
  551.  
  552.           MoveWindow(ghwndDrawSurf,
  553.                      0, lcyCtrlPanel,
  554.                      LOWORD(lParam),                    // cx of hwnd
  555.                      lcyDrawSurf, TRUE);
  556.           //break;
  557.           return DefWindowProc(hwnd, message, wParam, lParam);
  558.       }
  559.  
  560.       case WM_DESTROY: {
  561.         DeleteDC(ghDCMem);
  562.         DeleteEnhMetaFile(ghMetaf);
  563.         DestroyWindow(ghwndCtrlPanel);
  564.         DeleteObject(ghbrRed);
  565.         DeleteObject(ghbrCur);
  566.         DeleteObject(ghpnCur);
  567.         DeleteObject(ghbrAppBkgd);
  568.         DeleteObject(ghpnWide);
  569.         if (ghHT)
  570.             DeleteObject(ghHT);
  571.         ChangeClipboardChain(ghwndMain, ghwndNext);
  572.         bFreeDibFile(&gDib);
  573.     PostQuitMessage(0);
  574.     return 0L;
  575.       }
  576.  
  577.       case WM_COMMAND: {
  578.         static int     iPlus=0;
  579.  
  580.  
  581.     switch (LOWORD(wParam)) {
  582.             case DID_ZERO:
  583.             case DID_ONE:
  584.             case DID_TWO:
  585.             case DID_THREE:
  586.             case DID_FOUR:
  587.             case DID_FIVE:
  588.             case DID_SIX:
  589.             case DID_SEVEN:
  590.             case DID_EIGHT:
  591.             case DID_NINE: {
  592.                 HDC           hDCDrawSurf;
  593.                 ENHMETAHEADER EnhMetaHdr;
  594.                 RECT          rcClientDS;
  595.                 int           iRecord;
  596.                 PLAYINFO      PlayInfo;
  597.  
  598.                 if (ghMetaf == 0)
  599.                     return 0L;
  600.  
  601.                 GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr);
  602.                 iRecord = LOWORD(wParam) - DID_ZERO + iPlus;
  603.                 SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, iRecord, FALSE);
  604.                 PlayInfo.iRecord = iRecord;
  605.                 PlayInfo.bPlayContinuous = FALSE;
  606.                 iPlus = 0;
  607.  
  608.                 if ((EnhMetaHdr.nRecords > 1) && (iRecord > 0) &&
  609.                     (iRecord <= (INT) EnhMetaHdr.nRecords)) {
  610.                     hDCDrawSurf = GetDC(ghwndDrawSurf);
  611.                     if (gbFit2Wnd) {
  612.                         GetClientRect(ghwndDrawSurf, &rcClientDS);
  613.                         EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, &rcClientDS);
  614.                     } else {
  615.                         EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds);
  616.                     }
  617.                     //
  618.                     // Enabling the user to record a metafile record selectively
  619.                     //
  620.                     if ((gbRecording) && (ghDCMetaf != NULL)) {
  621.                         EnumEnhMetaFile(ghDCMetaf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds);
  622.                     }
  623.                     ReleaseDC(ghwndDrawSurf, hDCDrawSurf);
  624.                 }
  625.                 return 0L;
  626.             }
  627.             case DID_TEN_PLUS: {
  628.                 if (ghMetaf == 0)
  629.                     return 0L;
  630.  
  631.                 iPlus += 10;
  632.                 SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, iPlus, FALSE);
  633.                 return 0L;
  634.             }
  635.             case MM_PAGESETUP:
  636.             case MM_CUT:
  637.                 return 0L;
  638.  
  639.             case MM_COPY:   {
  640.  
  641.                 if ((ghMetaf == 0) && (ghmf == 0)) {
  642.                     SetWindowText(ghTextWnd, "No Metafile for copying");
  643.                     return 0L;
  644.                 }
  645.  
  646.                 OpenClipboard(ghwndMain);
  647.                 EmptyClipboard();
  648.  
  649.                 if (gbExport3X)
  650.                 {
  651.                     HGLOBAL          hmem;
  652.                     LPMETAFILEPICT  lpmfp;
  653.                     RECT            rcClientDS;
  654.                     DWORD           x, y, mm;
  655.                     HDC             hDCDrawSurf;
  656.                     LPBYTE          pjData;
  657.                     UINT            uiSize;
  658.  
  659.                     hDCDrawSurf = GetDC(ghwndDrawSurf);
  660.  
  661.                     if (ghmf == 0) {
  662.                         SetWindowText(ghTextWnd, "Converting Enhanced Metafile to 3X format");
  663.  
  664.                         if (!(uiSize = GetWinMetaFileBits(ghMetaf, 0, NULL, MM_ANISOTROPIC, hDCDrawSurf))) {
  665.                             MessageBox(ghwndMain, "Fail in 1st GetWinMetaFileBits!", "Error", MB_OK);
  666.                             goto COPY_3X_EXIT;
  667.                         }
  668.  
  669.                         if ((pjData = (LPBYTE) LocalAlloc(LMEM_FIXED, uiSize)) == NULL) {
  670.                             MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK);
  671.                             goto COPY_3X_EXIT;
  672.                         }
  673.  
  674.                         if (!(uiSize = GetWinMetaFileBits(ghMetaf, uiSize, pjData, MM_ANISOTROPIC, hDCDrawSurf))) {
  675.                             MessageBox(ghwndMain, "Fail in 2nd GetWinMetaFileBits!", "Error", MB_OK);
  676.                             LocalFree(pjData);
  677.                             goto COPY_3X_EXIT;
  678.                         }
  679.  
  680.                         ghmf = SetMetaFileBitsEx(uiSize, (LPBYTE) pjData);
  681.                         LocalFree(pjData);
  682.                     }
  683.  
  684.                     if ((hmem = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE,
  685.                                         sizeof(METAFILEPICT))) == NULL) {
  686.  
  687.                         SetWindowText(ghTextWnd, "Failed in allocating memory");
  688.                         goto COPY_3X_EXIT;
  689.  
  690.                     }
  691.  
  692.                     lpmfp = (LPMETAFILEPICT)GlobalLock(hmem);
  693.                     lpmfp->mm = mm = MM_ANISOTROPIC;
  694.  
  695.                     GetClientRect(ghwndDrawSurf, &rcClientDS);
  696.                     x = rcClientDS.right - rcClientDS.left;
  697.                     x *= 2540;
  698.                     x /= GetDeviceCaps(hDCDrawSurf, LOGPIXELSX);
  699.                     lpmfp->xExt = x;                                // ie. in 0.01mm
  700.  
  701.                     y = rcClientDS.bottom - rcClientDS.top;
  702.                     y *= 2540;
  703.                     y /= GetDeviceCaps(hDCDrawSurf, LOGPIXELSY);
  704.                     lpmfp->yExt = y;                                // ie. in 0.01mm
  705.  
  706.                     lpmfp->hMF = CopyMetaFile(ghmf, NULL);
  707.  
  708.                     GlobalUnlock(hmem);
  709.                     SetWindowText(ghTextWnd, "Copying 3X Metafile to Clipboard");
  710.                     SetClipboardData(CF_METAFILEPICT, hmem);
  711.  
  712. COPY_3X_EXIT:
  713.                     ReleaseDC(ghwndDrawSurf, hDCDrawSurf);
  714.                     goto COPY_EXIT;
  715.  
  716.                 }
  717.  
  718.                 //
  719.                 // gbExport3X == FALSE
  720.                 //
  721.                 if (ghMetaf == 0)           // requires conversion
  722.                 {
  723.                     UINT            uiSize;
  724.                     LPVOID          pvData;
  725.                     HDC             hDCDrawSurf;
  726.  
  727.                     SetWindowText(ghTextWnd, "Converting 3X Metafile to Enhanced Metafile format");
  728.                     if (!(uiSize = GetMetaFileBitsEx(ghmf, 0, NULL))) {
  729.                         MessageBox(ghwndMain, "Fail in 1st GetMetaFileBitsEx!", "Error", MB_OK);
  730.                         SetWindowText(ghTextWnd, "Conversion Failed");
  731.                         goto COPY_EXIT;
  732.                     }
  733.  
  734.                     if ((pvData = (LPVOID) LocalAlloc(LMEM_FIXED, uiSize)) == NULL) {
  735.                         MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK);
  736.                         SetWindowText(ghTextWnd, "Conversion Failed");
  737.                         goto COPY_EXIT;
  738.                     }
  739.  
  740.                     if (!(uiSize = GetMetaFileBitsEx(ghmf, uiSize, pvData))) {
  741.                         MessageBox(ghwndMain, "Fail in 2nd GetMetaFileBitsEx!", "Error", MB_OK);
  742.                         goto COPY_ENH_EXIT;
  743.                     }
  744.  
  745.                     hDCDrawSurf = GetDC(ghwndDrawSurf);
  746.  
  747.                     // !!! provide the correct picture extents in the METAFILEPICT structure
  748.                     // where possible
  749.                     ghMetaf = SetWinMetaFileBits(uiSize, (LPBYTE)pvData, hDCDrawSurf, NULL);
  750.  
  751. COPY_ENH_EXIT:
  752.                     LocalFree(pvData);
  753.                     ReleaseDC(ghwndDrawSurf ,hDCDrawSurf);
  754.  
  755.                     if (ghMetaf == 0) {
  756.                         SetWindowText(ghTextWnd, "Conversion Failed");
  757.                         goto COPY_EXIT;
  758.                     }
  759.  
  760.                 }
  761.  
  762.                 //
  763.                 // No Conversion required
  764.                 //
  765.                 {
  766.  
  767.                     HENHMETAFILE hEmfTmp;
  768.  
  769.                     hEmfTmp = CopyEnhMetaFile(ghMetaf, NULL);
  770.  
  771.                     if (hEmfTmp) {
  772.                         SetWindowText(ghTextWnd, "Copying Enhanced Metafile to Clipboard");
  773.                         SetClipboardData(CF_ENHMETAFILE, hEmfTmp);
  774.                         DeleteEnhMetaFile(hEmfTmp);
  775.                     }
  776.  
  777.                 }
  778.  
  779. COPY_EXIT:
  780.  
  781.                 CloseClipboard();
  782.                 return 0L;
  783.             }
  784.  
  785.             case MM_PASTE:  {
  786.                 OpenClipboard(ghwndMain);
  787.  
  788.                 if (gbImport3X)
  789.                 {
  790.                     HANDLE      hmem;
  791.                     DWORD       dwXSugExt, dwYSugExt, dwMM;
  792.                     HDC         hDCDrawSurf;
  793.                     RECT        rc;
  794.                     INT         iSavedDC;
  795.  
  796.  
  797.                     hmem = GetClipboardData(CF_METAFILEPICT);
  798.  
  799.                     if (hmem)
  800.                     {
  801.                         LPMETAFILEPICT lpmfp;
  802.  
  803.                         SetWindowText(ghTextWnd, "Pasting 3X Metafile");
  804.                         lpmfp = (LPMETAFILEPICT)GlobalLock(hmem);
  805.                         ghmf  = lpmfp->hMF;
  806.                         dwMM  = lpmfp->mm;
  807.                         dwXSugExt = lpmfp->xExt;        // in 0.01 mm
  808.                         dwYSugExt = lpmfp->yExt;
  809.                         GlobalUnlock(hmem);
  810.  
  811.                         hDCDrawSurf = GetDC(ghwndDrawSurf);
  812.  
  813.                         iSavedDC = SaveDC(hDCDrawSurf);
  814.  
  815.                         GetClientRect(ghwndDrawSurf, &rc);
  816.  
  817.                         SetMapMode(hDCDrawSurf, dwMM);
  818.                         if ((dwXSugExt > 0 )&& (dwYSugExt > 0))
  819.                         {                               // suggested width & height of image
  820.                             DWORD x;
  821.                             DWORD y;
  822.  
  823.                             // no. of pixels in x and y
  824.                             x = dwXSugExt;
  825.                             x *= GetDeviceCaps(hDCDrawSurf,LOGPIXELSX);
  826.                             x /= 2540;
  827.  
  828.                             y = dwYSugExt;
  829.                             y *= GetDeviceCaps(hDCDrawSurf,LOGPIXELSY);
  830.                             y /= 2540;
  831.  
  832.                             SetWindowExtEx(hDCDrawSurf, x, y, NULL);
  833.  
  834.                             if (gbFit2Wnd)
  835.                                 SetViewportExtEx(hDCDrawSurf, rc.right, rc.bottom, NULL);
  836.                             else
  837.                                 SetViewportExtEx(hDCDrawSurf, x, y, NULL);
  838.  
  839.                         } else {
  840.                             SetWindowText(ghTextWnd, "No information on 3X Metafile's extensions");
  841.                             SetWindowExtEx(hDCDrawSurf, rc.right, rc.bottom, NULL);
  842.                             SetViewportExtEx(hDCDrawSurf, rc.right, rc.bottom, NULL);
  843.                         }
  844.  
  845.                         SetViewportOrgEx(hDCDrawSurf, 0, 0, NULL);
  846.                         SetWindowOrgEx(hDCDrawSurf, 0, 0, NULL);
  847.  
  848.                         SetBoundsRect(hDCDrawSurf, NULL, DCB_ENABLE | DCB_SET);
  849.                         PlayMetaFile(hDCDrawSurf, ghmf);
  850.                         {
  851.                         UINT    uiRC;
  852.                         char    text[128];
  853.  
  854.                         wsprintf(text, "dwMM = %d\n", dwMM);
  855.                         OutputDebugString(text);
  856.                         wsprintf(text, "dwXSugExt = %d\n", dwXSugExt);
  857.                         OutputDebugString(text);
  858.                         wsprintf(text, "dwYSugExt = %d\n", dwYSugExt);
  859.                         OutputDebugString(text);
  860.  
  861.                         uiRC = GetBoundsRect(hDCDrawSurf, &rc, DCB_RESET); // in logical coordinates
  862.                         wsprintf(text, "GetBoundsRect = %d\n", uiRC);
  863.                         OutputDebugString(text);
  864.                         wsprintf(text, "left     = %d\n", rc.left);
  865.                         OutputDebugString(text);
  866.                         wsprintf(text, "right    = %d\n", rc.right);
  867.                         OutputDebugString(text);
  868.                         wsprintf(text, "top      = %d\n", rc.top);
  869.                         OutputDebugString(text);
  870.                         wsprintf(text, "bottom   = %d\n", rc.bottom);
  871.                         OutputDebugString(text);
  872.                         }
  873.  
  874. // !!!
  875. // saving the wmf as an Aldus mf
  876. //
  877. {
  878. OPENFILENAME    ofn;
  879. char            szFile[256], szFileTitle[256];
  880. static char     *szFilter;
  881. UINT            uiSize;
  882. HANDLE          hFile, hMapFile;
  883. LPVOID          pMapFile;
  884. DWORD           dwHigh, dwLow;
  885.  
  886. szFilter =
  887.   "EnhMeta files Windows Metafiles (*.wmf)\0*.wmf\0\0";
  888.  
  889. strcpy(szFile, "*.wmf\0");
  890. ofn.lStructSize = sizeof(OPENFILENAME);
  891. ofn.hwndOwner = hwnd;
  892. ofn.lpstrFilter = szFilter;
  893. ofn.lpstrCustomFilter = (LPSTR) NULL;
  894. ofn.nMaxCustFilter = 0L;
  895. ofn.nFilterIndex = 1;
  896. ofn.lpstrFile = szFile;
  897. ofn.nMaxFile = sizeof(szFile);
  898. ofn.lpstrFileTitle = szFileTitle;
  899. ofn.nMaxFileTitle = sizeof(szFileTitle);
  900. ofn.lpstrInitialDir = NULL;
  901. ofn.lpstrTitle = "Save Metafile";
  902. ofn.Flags = 0L;
  903. ofn.nFileOffset = 0;
  904. ofn.nFileExtension = 0;
  905. ofn.lpstrDefExt = "WMF";
  906.  
  907. if (!GetOpenFileName(&ofn))
  908.     return 0L;
  909.  
  910. uiSize = GetMetaFileBitsEx(ghmf, 0, NULL);
  911. dwHigh = 0;
  912. dwLow  = uiSize;
  913.  
  914. if ((hFile = CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,
  915.         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == (HANDLE)-1) {
  916.     MessageBox(ghwndMain, "Fail in file open!", "Error", MB_OK);
  917.     return 0L;
  918. }
  919.  
  920. //
  921. // Create a map file of the opened file
  922. //
  923. if ((hMapFile = CreateFileMapping(hFile, NULL,
  924.                          PAGE_READWRITE, dwHigh, dwLow, "MapF")) == NULL) {
  925.     MessageBox(ghwndMain, "Fail in creating map file!", "Error", MB_OK);
  926.     goto ErrorExit1;
  927. }
  928.  
  929. //
  930. // Map a view of the whole file
  931. //
  932. if ((pMapFile = MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, uiSize)) == NULL) {
  933.     MessageBox(ghwndMain, "Fail in mapping view of the Map File object!", "Error", MB_OK);
  934.     goto ErrorExit2;
  935. }
  936.  
  937. if (uiSize) {
  938.     APMFILEHEADER   AldHdr;
  939.     PAPMFILEHEADER  pAldHdr;
  940.     PBYTE           pjTmp;
  941.     INT             iSize;
  942.     char            text[128];
  943.  
  944.     AldHdr.key = ALDUS_ID;
  945.     AldHdr.hmf = 0;                                 // Unused; must be zero
  946.     AldHdr.bbox.Left   = 0;                         // in metafile units
  947.     AldHdr.bbox.Top    = 0;
  948.     //AldHdr.bbox.Right  = rc.right - rc.left;        // in logical coordinates
  949.     //AldHdr.bbox.Bottom = rc.bottom - rc.top;
  950.  
  951.     switch (dwMM) {
  952.         case MM_HIENGLISH:
  953.             AldHdr.inch = 1000;
  954.             AldHdr.bbox.Right  = (SHORT)dwXSugExt;
  955.             AldHdr.bbox.Bottom = (SHORT)dwYSugExt;
  956.             break;
  957.         case MM_HIMETRIC:
  958.             AldHdr.inch = 1440;
  959.             AldHdr.bbox.Right  = (SHORT)(dwXSugExt / 2540 * 1440);
  960.             AldHdr.bbox.Bottom = (SHORT)(dwYSugExt / 2540 * 1440);
  961.             break;
  962.         case MM_LOENGLISH:
  963.             AldHdr.inch = 100;
  964.             AldHdr.bbox.Right  = (SHORT)dwXSugExt;
  965.             AldHdr.bbox.Bottom = (SHORT)dwYSugExt;
  966.             break;
  967.         case MM_LOMETRIC:
  968.             AldHdr.inch = 254;
  969.             AldHdr.bbox.Right  = (SHORT)dwXSugExt;
  970.             AldHdr.bbox.Bottom = (SHORT)dwYSugExt;
  971.             break;
  972.         case MM_TEXT:
  973.             AldHdr.inch = (WORD) (GetDeviceCaps(hDCDrawSurf, HORZRES) * 25.4 /
  974.                           GetDeviceCaps(hDCDrawSurf, HORZSIZE));
  975.             AldHdr.bbox.Right  = (SHORT)dwXSugExt;
  976.             AldHdr.bbox.Bottom = (SHORT)dwYSugExt;
  977.             break;
  978.         case MM_TWIPS:
  979.             AldHdr.inch = 1440;
  980.             AldHdr.bbox.Right  = (SHORT)dwXSugExt;
  981.             AldHdr.bbox.Bottom = (SHORT)dwYSugExt;
  982.             break;
  983.         default:
  984.             AldHdr.inch = 1440;
  985.             AldHdr.bbox.Right  = (SHORT)(dwXSugExt / 2540 * 1440);
  986.             AldHdr.bbox.Bottom = (SHORT)(dwYSugExt / 2540 * 1440);
  987.             break;
  988.     }
  989.  
  990.     wsprintf(text, "MM           = %d\n", dwMM);
  991.     OutputDebugString(text);
  992.     wsprintf(text, "AldHdr.inch  = %d\n", AldHdr.inch);
  993.     OutputDebugString(text);
  994.  
  995.     AldHdr.reserved = 0;
  996.     AldHdr.checksum = 0;
  997.     {
  998.     WORD    *p;
  999.  
  1000.     for (p = (WORD *)&AldHdr, AldHdr.checksum = 0;
  1001.             p < (WORD *)&(AldHdr.checksum); ++p)
  1002.         AldHdr.checksum ^= *p;
  1003.     }
  1004.  
  1005.     pAldHdr = &AldHdr;
  1006.     pjTmp = (PBYTE)pMapFile;
  1007.  
  1008.     iSize = 22;
  1009.  
  1010.     //!!! use memcpy...
  1011.     while (iSize--) {
  1012.         *(((PBYTE)pjTmp)++) = *(((PBYTE)pAldHdr)++);
  1013.     }
  1014.  
  1015.     pMapFile = (PBYTE)pMapFile + 22;
  1016.     GetMetaFileBitsEx(ghmf, uiSize, pMapFile);
  1017. }
  1018.  
  1019.  
  1020. UnmapViewOfFile(pMapFile);
  1021.  
  1022. ErrorExit2:
  1023.   CloseHandle(hMapFile);
  1024. ErrorExit1:
  1025.   CloseHandle(hFile);
  1026. }
  1027.  
  1028.                         RestoreDC(hDCDrawSurf, iSavedDC);
  1029.                         ReleaseDC(ghwndDrawSurf, hDCDrawSurf);
  1030.  
  1031.                     } else {
  1032.                         SetWindowText(ghTextWnd, "Cannot get 3X metafile from clipboard!");
  1033.                     }
  1034.  
  1035.                     goto PASTE_EXIT;
  1036.  
  1037.                 }
  1038.  
  1039.                 //
  1040.                 // gbImport3X == FALSE
  1041.                 //
  1042.                 {
  1043.                     HENHMETAFILE hEmfTmp;
  1044.                     ENHMETAHEADER EnhMetaHdr;
  1045.  
  1046.                     hEmfTmp = GetClipboardData(CF_ENHMETAFILE);
  1047.                     if (hEmfTmp) {
  1048.                         SetWindowText(ghTextWnd, "Pasting Enhanced Metafile");
  1049.                         DeleteEnhMetaFile(ghMetaf);
  1050.                         ghMetaf = CopyEnhMetaFile(hEmfTmp, NULL);
  1051.                         DeleteEnhMetaFile(hEmfTmp);
  1052.                         GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr);
  1053.                         SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, EnhMetaHdr.nRecords, FALSE);
  1054.                         bReset = TRUE;
  1055.                     } else {
  1056.                         SetWindowText(ghTextWnd, "Cannot get Enhanced metafile from clipboard!");
  1057.                     }
  1058.                 }
  1059. PASTE_EXIT:
  1060.  
  1061.                 CloseClipboard();
  1062.                 EnableMenuItem(hMenu, MM_COPY,  MF_ENABLED);
  1063.                 return 0L;
  1064.             }
  1065.  
  1066.             case MM_DEL:    {
  1067.                 OpenClipboard(ghwndMain);
  1068.                 EmptyClipboard();
  1069.                 CloseClipboard();
  1070.                 return 0L;
  1071.             }
  1072.  
  1073.             case MM_PEN: {
  1074.                 HDC     hDC;
  1075.                 DWORD   dwRGB;
  1076.  
  1077.                 if (bChooseNewColor(hwnd, &dwRGB)) {
  1078.                     hDC = GetDC(ghwndDrawSurf);
  1079.                     if (ghpnCur != NULL)
  1080.                         DeleteObject(ghpnCur);
  1081.                     ghpnCur = CreatePen(PS_SOLID, 1, dwRGB);
  1082.                     SelectObject(hDC, ghpnCur);
  1083.                     if (ghDCMetaf != NULL)
  1084.                         SelectObject(ghDCMetaf, ghpnCur);
  1085.                     ReleaseDC(ghwndDrawSurf, hDC);
  1086.                 }
  1087.                 return 0L;
  1088.             }
  1089.             case MM_BRUSH: {
  1090.                 HDC     hDC;
  1091.                 static DWORD   dwRGB=RGB(255, 255, 255);
  1092.  
  1093.                 if (bChooseNewColor(hwnd, &dwRGB)) {
  1094.                     hDC = GetDC(ghwndDrawSurf);
  1095.                     if (ghbrCur != NULL)
  1096.                         DeleteObject(ghbrCur);
  1097.                     ghbrCur = hBrCreateBrush(hDC, dwRGB);
  1098.                     SelectObject(hDC, ghbrCur);
  1099.                     if (ghDCMetaf != NULL)
  1100.                         SelectObject(ghDCMetaf, ghbrCur);
  1101.                     ReleaseDC(ghwndDrawSurf, hDC);
  1102.                 }
  1103.                 return 0L;
  1104.             }
  1105.             case MM_FONT: {
  1106.                 HDC     hDC;
  1107.                 char    text[128];
  1108.  
  1109.                 if (bChooseNewFont(ghwndMain, &glf, &gCrText)) {
  1110.                     ghCurFont = CreateFontIndirect(&glf);
  1111.  
  1112.                     hDC = GetDC(ghwndDrawSurf);
  1113.                     EnumFonts(hDC, glf.lfFaceName, (FONTENUMPROC)iTT, (LPARAM)&gbTT);
  1114.                     wsprintf(text, "gbTT = %d\n", gbTT);
  1115.                     //OutputDebugString(text);
  1116.                     ReleaseDC(ghwndDrawSurf, hDC);
  1117.  
  1118.                     if (ghDCMetaf != NULL)
  1119.                         SelectObject(ghDCMetaf, ghCurFont);
  1120.                 }
  1121.                 return 0L;
  1122.             }
  1123.  
  1124.             case MM_TTOUTLN_STROKEFILL: {
  1125.                 gbSFOutln = (gbSFOutln ? FALSE : TRUE);
  1126.                 if (gbSFOutln) {
  1127.                     CheckMenuItem(hMenu, MM_TTOUTLN_STROKEFILL, MF_CHECKED);
  1128.                     CheckMenuItem(hMenu, MM_TTOUTLN_POLYDRAW, MF_UNCHECKED);
  1129.                     gbPDOutln = FALSE;
  1130.                 }
  1131.                 return 0L;
  1132.             }
  1133.  
  1134.             case MM_TTOUTLN_POLYDRAW: {
  1135.                 gbPDOutln = (gbPDOutln ? FALSE : TRUE);
  1136.                 if (gbPDOutln) {
  1137.                     CheckMenuItem(hMenu, MM_TTOUTLN_STROKEFILL, MF_UNCHECKED);
  1138.                     CheckMenuItem(hMenu, MM_TTOUTLN_POLYDRAW, MF_CHECKED);
  1139.                     gbSFOutln = FALSE;
  1140.                 }
  1141.                 return 0L;
  1142.             }
  1143.  
  1144.             case MM_C_WND_MF:
  1145.                 return 0L;
  1146.             case MM_C_BEGIN_GP:
  1147.             case MM_C_END_GP:
  1148.                 return 0L;
  1149.             case MM_C_MLTFMTS: {
  1150.                 CMTMLTFMT *pMfmt;
  1151.  
  1152.                 if ((gbRecording) && (ghDCMetaf != NULL)) {
  1153.                     if ((pMfmt = pLoadMltFmtFile()) != NULL) {
  1154.                         GdiComment(ghDCMetaf,
  1155.                                    sizeof(CMTMLTFMT)+pMfmt->aemrformat[0].cbData,
  1156.                                    (CONST BYTE *) pMfmt);
  1157.                         Free(pMfmt);
  1158.                     }
  1159.                     else
  1160.                         MessageBox(ghwndMain,
  1161.                                    "Fail to load Multiformat file!",
  1162.                                    "Error",
  1163.                                    MB_OK);
  1164.                 }
  1165.  
  1166.                 return 0L;
  1167.             }
  1168.             case MM_HITTEST: {
  1169.                 static BOOL bHitTest=FALSE;
  1170.                 HWND        hwndRecBtn;
  1171.  
  1172.                 bHitTest = (bHitTest ? FALSE : TRUE);
  1173.                 hwndRecBtn = GetDlgItem(ghwndCtrlPanel, DID_RECORD);
  1174.                 if (bHitTest) {
  1175.                     CheckMenuItem(hMenu, MM_HITTEST, MF_CHECKED);
  1176.                     EnableMenuItem(hMenu, MM_RECORD, MF_GRAYED);
  1177.                     EnableWindow(hwndRecBtn, FALSE);
  1178.                     gbHitTest = TRUE;
  1179.                 } else {
  1180.                     CheckMenuItem(hMenu, MM_HITTEST, MF_UNCHECKED);
  1181.                     EnableMenuItem(hMenu, MM_RECORD, MF_ENABLED);
  1182.                     EnableWindow(hwndRecBtn, TRUE);
  1183.                     gbHitTest = FALSE;
  1184.                     return 0L;
  1185.                 }
  1186.  
  1187.                 if (ghMetaf == 0) {
  1188.                     SetWindowText(ghTextWnd, "No Metafile loaded for hit-testing");
  1189.                     return 0L;
  1190.                 }
  1191.                 return 0L;
  1192.             }
  1193.  
  1194.         case MM_LEABOUT:
  1195.         if (DialogBox(ghModule, (LPCSTR)"AboutBox", ghwndMain, (DLGPROC)About) == -1)
  1196.             MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK);
  1197.                 return 0L;
  1198.  
  1199.         case MM_ABOUT:
  1200.         if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)About) == -1)
  1201.            MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK);
  1202.         return 0L;
  1203.  
  1204.             case MM_LOAD_MASKBMP:
  1205.                 SetWindowText(ghTextWnd, "Load Mask Bitmap");
  1206.                 bGetBMP(hwnd, TRUE);
  1207.                 return 0L;
  1208.  
  1209.             case MM_LOAD_BMP:
  1210.                 SetWindowText(ghTextWnd, "Load Bitmap");
  1211.                 bGetBMP(hwnd, FALSE);
  1212.                 return 0L;
  1213.  
  1214.             case MM_SAVE_BMP:
  1215.                 SetWindowText(ghTextWnd, "Save Drawing Surface as Bitmap");
  1216.                 return 0L;
  1217.  
  1218.             case MM_LOAD:
  1219.         case DID_OPEN: {
  1220.                 ENHMETAHEADER EnhMetaHdr;
  1221.                 HENHMETAFILE  hEmfTmp;
  1222.  
  1223.                 SetWindowText(ghTextWnd, "Load Metafile");
  1224.                 //
  1225.                 // If user hit cancel, we still have the original metafile
  1226.                 //
  1227.                 //DeleteEnhMetaFile(ghMetaf);
  1228.                 //ghMetaf = hemfLoadMetafile(hwnd);
  1229.                 hEmfTmp = hemfLoadMetafile(hwnd);
  1230.                 if (hEmfTmp != 0) {
  1231.                     char     szDesc[256];
  1232.  
  1233.                     DeleteEnhMetaFile(ghMetaf);
  1234.                     ghMetaf = CopyEnhMetaFile(hEmfTmp, NULL);
  1235.                     GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr);
  1236.                     SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, EnhMetaHdr.nRecords, FALSE);
  1237.                     DeleteEnhMetaFile(hEmfTmp);
  1238.                     EnableMenuItem(hMenu, MM_COPY,  MF_ENABLED);
  1239.                     if (GetEnhMetaFileDescription(ghMetaf, 256, szDesc) != 0) {
  1240.                         char    szText[256];
  1241.                         char    *szTmp, szSource[256];
  1242.  
  1243.                         szTmp = (char *)strtok(szDesc, "\\0");
  1244.                         strcpy(szSource, szTmp);
  1245.                         szTmp = (char *)strtok(NULL, "\\0\\0");
  1246.                         wsprintf(szText, "Source: %s  Title: %s", szSource, szTmp);
  1247.                         SetWindowText(ghTextWnd, szText);
  1248.                         strcpy(szLoadedMetaf, szTmp);
  1249.                     } else {
  1250.                         strcpy(szLoadedMetaf, "");
  1251.                     }
  1252.                 //} else {
  1253.                 //    SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, 0, FALSE);
  1254.                 }
  1255.                 bReset = TRUE;
  1256.                 return 0L;
  1257.             }
  1258.             case MM_RECORD:
  1259.                 if (gbHitTest) {
  1260.                     SetWindowText(ghTextWnd, "Please CANCEL Hit Testing Mode First!");
  1261.                     return 0L;
  1262.                 }
  1263.  
  1264.                 SetWindowText(ghTextWnd, "Recording...");
  1265.                 if (!gbRecording) {
  1266.                     ghDCMetaf = hDCRecordMetafileAs(hwnd, szFilename);
  1267.                 }
  1268.  
  1269.                 if (ghDCMetaf == NULL) {
  1270.                    SetWindowText(ghTextWnd, "ERROR: Failed in creating the metafile DC!");
  1271.                    return 0L;
  1272.                 }
  1273.  
  1274.                 // Parse the szFilename for the title and GdiComment the metafile with it.
  1275.                 {
  1276.                     char    szComment[256];
  1277.                     char    *szTmp, szTmp2[256];
  1278.  
  1279.                     szTmp = (char *)strtok(szFilename, "\\");
  1280.                     strcpy(szTmp2, szTmp);
  1281.                     while (szTmp != NULL) {
  1282.                         szTmp = (char *)strtok(NULL, "\\");
  1283.                         if (szTmp != NULL) {
  1284.                             strcpy(szTmp2, szTmp);
  1285.                         }
  1286.                     }
  1287.                     szTmp = (char *)strtok(szTmp2, ".");
  1288.                     wsprintf((LPSTR) szComment, "MfEdit:\\0%s\\0\\0", szTmp);
  1289. #if 0
  1290.                     if (!GdiComment(ghDCMetaf, 256, szComment)) {
  1291.                         MessageBox(ghwndMain, "Fail in adding comment!", "Error", MB_OK);
  1292.                     }
  1293. #endif
  1294.                 }
  1295.  
  1296.                 gbRecording = TRUE;
  1297.  
  1298.                 if (ghpnCur != NULL)
  1299.                     SelectObject(ghDCMetaf, ghpnCur);
  1300.  
  1301.                 if (ghbrCur != NULL)
  1302.                     SelectObject(ghDCMetaf, ghbrCur);
  1303.  
  1304.                 if (ghCurFont != NULL)
  1305.                     SelectObject(ghDCMetaf, ghCurFont);
  1306.                 return 0L;
  1307.  
  1308.         case DID_RECORD: {
  1309.                 int  iWidthMM, iHeightMM, iWidthPels, iHeightPels, iMMPerPelX, iMMPerPelY;
  1310.                 char szComment[256];
  1311.                 char szTitle[256];
  1312.                 RECT rc;
  1313.                 HDC  hDC;
  1314.  
  1315.  
  1316.                 if (gbHitTest) {
  1317.                     SetWindowText(ghTextWnd, "Please CANCEL Hit Testing Mode First!");
  1318.                     return 0L;
  1319.                 }
  1320.  
  1321.                 SetWindowText(ghTextWnd, "Recording...");
  1322.                 if (!gbRecording) {
  1323.  
  1324.                     hDC = GetDC(hwnd);
  1325.                     iWidthMM    = GetDeviceCaps(hDC, HORZSIZE);
  1326.                     iHeightMM   = GetDeviceCaps(hDC, VERTSIZE);
  1327.                     iWidthPels  = GetDeviceCaps(hDC, HORZRES);
  1328.                     iHeightPels = GetDeviceCaps(hDC, VERTRES);
  1329.                     ReleaseDC(hwnd, hDC);
  1330.                     iMMPerPelX  = (iWidthMM * 100)/iWidthPels;
  1331.                     iMMPerPelY  = (iHeightMM * 100)/iHeightPels;
  1332.                     GetClientRect(ghwndDrawSurf, &rc);
  1333.                     rc.left   = rc.left * iMMPerPelX;
  1334.                     rc.top    = rc.top * iMMPerPelY;
  1335.                     rc.right  = rc.right * iMMPerPelX;
  1336.                     rc.bottom = rc.bottom * iMMPerPelY;
  1337.  
  1338.                     {
  1339.                        char szFilenameWithExt[256];
  1340.                        char suffix[20];
  1341.                        char szDesc[256];
  1342.                        char *szTmp, szTmp2[256];
  1343.  
  1344.                        //
  1345.                        // assemble a new metafile name with the emf extension from
  1346.                        // the generic szFilename
  1347.                        //
  1348.                        wsprintf((LPSTR) suffix, "%d.emf", iMetafCnt);
  1349.                        iMetafCnt++;
  1350.                        strcpy(szFilenameWithExt, szFilename);
  1351.                        strcat(szFilenameWithExt, suffix);
  1352.  
  1353.                        //
  1354.                        // parse szFilename for the title for description
  1355.                        //
  1356.                        szTmp = (char *)strtok(szFilename, "\\");
  1357.                        strcpy(szTmp2, szTmp);
  1358.                        while (szTmp != NULL) {
  1359.                            szTmp = (char *)strtok(NULL, "\\");
  1360.                            if (szTmp != NULL) {
  1361.                                strcpy(szTmp2, szTmp);
  1362.                            }
  1363.                        }
  1364.                        szTmp = (char *)strtok(szTmp2, ".");
  1365.                        strcpy(szTitle, szTmp);
  1366.                        wsprintf(szDesc, "SDK Enhanced Metafile Editor\\0%s\\0\\0", szTitle);
  1367.                        ghDCMetaf = CreateEnhMetaFile((HDC)NULL, szFilenameWithExt, (LPRECT)&rc, (LPSTR)szDesc);
  1368.                     }
  1369.  
  1370.                     if ((SetGraphicsMode(ghDCMetaf, GM_ADVANCED)) == 0) {
  1371.                        MessageBox(ghwndMain, "Fail in setting Advanced Graphics Mode!", "Error", MB_OK);
  1372.                     }
  1373.                 }
  1374.  
  1375.                 if (ghDCMetaf == NULL) {
  1376.                    SetWindowText(ghTextWnd, "ERROR: Failed in creating the metafile DC!");
  1377.                    return 0L;
  1378.                 }
  1379.                 wsprintf((LPSTR) szComment, "MfEdit:\\0%s\\0\\0", szTitle);
  1380. #if 0
  1381.                 if (!GdiComment(ghDCMetaf, 256, szComment)) {
  1382.                     MessageBox(ghwndMain, "Fail in adding comment!", "Error", MB_OK);
  1383.                 }
  1384. #endif
  1385.                 gbRecording = TRUE;
  1386.  
  1387.                 if (ghpnCur != NULL)
  1388.                     SelectObject(ghDCMetaf, ghpnCur);
  1389.  
  1390.                 if (ghbrCur != NULL)
  1391.                     SelectObject(ghDCMetaf, ghbrCur);
  1392.  
  1393.                 if (ghCurFont != NULL)
  1394.                     SelectObject(ghDCMetaf, ghCurFont);
  1395.  
  1396.                 return 0L;
  1397.             }
  1398.         case DID_STOP:
  1399.                 SetWindowText(ghTextWnd, "Stop");
  1400.                 if (gbRecording) {
  1401.                     ghMetaf = CloseEnhMetaFile(ghDCMetaf);
  1402.                     gbRecording = FALSE;
  1403.                 }
  1404.                 return 0L;
  1405.  
  1406.         case DID_PLAY: {
  1407.                 HDC hDCDrawSurf;
  1408.                 ENHMETAHEADER EnhMetaHdr;
  1409.                 RECT          rcClientDS;
  1410.                 int           iEntries;
  1411.                 PLOGPALETTE     plogPal;
  1412.                 PBYTE           pjTmp;
  1413.                 HPALETTE        hPal;
  1414.                 char            szTmp[256];
  1415.  
  1416.                 wsprintf(szTmp, "Playing Metafile: %s", szLoadedMetaf);
  1417.                 SetWindowText(ghTextWnd, szTmp);
  1418.                 if (ghMetaf != NULL) {
  1419.                     hDCDrawSurf = GetDC(ghwndDrawSurf);
  1420.                     GetEnhMetaFileHeader(ghMetaf, sizeof(ENHMETAHEADER), &EnhMetaHdr);
  1421.  
  1422.                     iEntries = GetEnhMetaFilePaletteEntries(ghMetaf, 0, NULL);
  1423.  
  1424.                     if (iEntries) {
  1425.                         if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  1426.                                 sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) {
  1427.                             MessageBox(ghwndMain, "Failed in Creating Palette!", "Error", MB_OK);
  1428.                         }
  1429.  
  1430.                         plogPal->palVersion = 0x300;
  1431.                         plogPal->palNumEntries = (WORD) iEntries;
  1432.                         pjTmp = (PBYTE) plogPal;
  1433.                         pjTmp += 8;
  1434.  
  1435.                         GetEnhMetaFilePaletteEntries(ghMetaf, iEntries, (PPALETTEENTRY)pjTmp);
  1436.                         hPal = CreatePalette(plogPal);
  1437.                         GlobalFree(plogPal);
  1438.  
  1439.                         SelectPalette(hDCDrawSurf, hPal, FALSE);
  1440.                         RealizePalette(hDCDrawSurf);
  1441.                     }
  1442.  
  1443.  
  1444.                     if (gbFit2Wnd) {
  1445.                         GetClientRect(ghwndDrawSurf, &rcClientDS);
  1446.                         if (!PlayEnhMetaFile( hDCDrawSurf, ghMetaf, (LPRECT) &rcClientDS)) {
  1447.                             char    text[128];
  1448.  
  1449.                             wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError());
  1450.                             OutputDebugString(text);
  1451.                         }
  1452.                     } else {
  1453.                         RECT rc;
  1454.  
  1455.                         rc.top = rc.left = 0;
  1456.                         rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left;
  1457.                         rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top;
  1458.                         if (!PlayEnhMetaFile( hDCDrawSurf, ghMetaf, (LPRECT) &rc)) {
  1459.                             char    text[128];
  1460.  
  1461.                             wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError());
  1462.                             OutputDebugString(text);
  1463.                         }
  1464.  
  1465.                     }
  1466.                     //
  1467.                     // Enabling the user to embed another metafile
  1468.                     //
  1469.                     if ((gbRecording) && (ghDCMetaf != NULL)) {
  1470.                         if (hPal != (HPALETTE)NULL) {
  1471.                             SelectPalette(ghDCMetaf, hPal, FALSE);
  1472.                             RealizePalette(ghDCMetaf);
  1473.                         }
  1474.                         {
  1475.                         RECT rc;
  1476.  
  1477.                         rc.top = rc.left = 0;
  1478.                         rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left;
  1479.                         rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top;
  1480.                         if (!PlayEnhMetaFile( ghDCMetaf, ghMetaf, (LPRECT) &rc)) {
  1481.                             char    text[128];
  1482.  
  1483.                             wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError());
  1484.                             OutputDebugString(text);
  1485.                         }
  1486.  
  1487.                         }
  1488.                     }
  1489.  
  1490.                     ReleaseDC(ghwndDrawSurf, hDCDrawSurf);
  1491.                 } else {
  1492.                     SetWindowText(ghTextWnd, "No Metafile for Playing");
  1493.                 }
  1494.  
  1495.                 return 0L;
  1496.             }
  1497.         case DID_FF: {
  1498.                 HDC           hDCDrawSurf;
  1499.                 ENHMETAHEADER EnhMetaHdr;
  1500.                 RECT          rcClientDS;
  1501.                 static int    iRecord = 0;
  1502.                 PLAYINFO      PlayInfo;
  1503.                 int           iEntries;
  1504.                 PLOGPALETTE     plogPal;
  1505.                 PBYTE           pjTmp;
  1506.                 HPALETTE        hPal;
  1507.  
  1508.  
  1509.                 if (ghMetaf == 0)
  1510.                     return 0L;
  1511.  
  1512.                 PlayInfo.iRecord = ++iRecord;
  1513.                 PlayInfo.bPlayContinuous = TRUE;
  1514.  
  1515.                 GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr);
  1516.                 SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, iRecord, FALSE);
  1517.                 if ((EnhMetaHdr.nRecords > 1) && (iRecord <= (INT)EnhMetaHdr.nRecords)) {
  1518.                     hDCDrawSurf = GetDC(ghwndDrawSurf);
  1519.  
  1520.                     iEntries = GetEnhMetaFilePaletteEntries(ghMetaf, 0, NULL);
  1521.  
  1522.                     if (iEntries) {
  1523.                         if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  1524.                                 sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) {
  1525.                             MessageBox(ghwndMain, "Failed in Creating Palette!", "Error", MB_OK);
  1526.                         }
  1527.  
  1528.                         plogPal->palVersion = 0x300;
  1529.                         plogPal->palNumEntries = (WORD) iEntries;
  1530.                         pjTmp = (PBYTE) plogPal;
  1531.                         pjTmp += 8;
  1532.  
  1533.                         GetEnhMetaFilePaletteEntries(ghMetaf, iEntries, (PPALETTEENTRY)pjTmp);
  1534.                         hPal = CreatePalette(plogPal);
  1535.                         GlobalFree(plogPal);
  1536.  
  1537.                         SelectPalette(hDCDrawSurf, hPal, FALSE);
  1538.                         RealizePalette(hDCDrawSurf);
  1539.                     }
  1540.  
  1541.                     if (gbFit2Wnd) {
  1542.                         GetClientRect(ghwndDrawSurf, &rcClientDS);
  1543.                         EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT) &rcClientDS);
  1544.                     } else {
  1545.                         EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT) &EnhMetaHdr.rclBounds);
  1546.                     }
  1547.                     //
  1548.                     // Enabling the user to record a metafile records selectively
  1549.                     //
  1550.                     if ((gbRecording) && (ghDCMetaf != NULL)) {
  1551.                         SelectPalette(ghDCMetaf, hPal, FALSE);
  1552.                         RealizePalette(ghDCMetaf);
  1553.                         EnumEnhMetaFile(ghDCMetaf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds);
  1554.                     }
  1555.  
  1556.                     ReleaseDC(ghwndDrawSurf, hDCDrawSurf);
  1557.                 }
  1558.  
  1559.                 if ((iRecord == (INT) EnhMetaHdr.nRecords) || bReset) {
  1560.                     iRecord = 0;
  1561.                     if (bReset)
  1562.                         SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, 0, FALSE);
  1563.                     bReset = FALSE;
  1564.                 }
  1565.                 return 0L;
  1566.             }
  1567.         case DID_CLEAR: {
  1568.                 HDC     hDCDrawSurf;
  1569.                 HGDIOBJ hObjOld;
  1570.                 RECT    rcDrawSurf;
  1571.  
  1572.                 SetWindowText(ghTextWnd, "Drawing Surface cleared");
  1573.                 hDCDrawSurf = GetDC(ghwndDrawSurf);
  1574.                 ghbrAppBkgd = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  1575.                 hObjOld = SelectObject(hDCDrawSurf, ghbrAppBkgd);
  1576.                 GetClientRect(ghwndDrawSurf, &rcDrawSurf);
  1577.                 PatBlt(hDCDrawSurf, 0, 0, rcDrawSurf.right, rcDrawSurf.bottom, PATCOPY);
  1578.                 ReleaseDC(ghwndDrawSurf, hDCDrawSurf);
  1579.                 SelectObject(hDCDrawSurf, hObjOld);
  1580.                 return 0L;
  1581.             }
  1582.  
  1583.             case DID_PEN:
  1584.                 SetWindowText(ghTextWnd, "Pen");
  1585.                 return 0L;
  1586.             case DID_TEXT:
  1587.                 SetWindowText(ghTextWnd, "Text");
  1588.                 return 0L;
  1589.             case DID_RECT:
  1590.                 SetWindowText(ghTextWnd, "Rectangle");
  1591.                 return 0L;
  1592.             case DID_FILLRECT:
  1593.                 SetWindowText(ghTextWnd, "Filled Rectangle");
  1594.                 return 0L;
  1595.             case DID_ELLIPSE:
  1596.                 SetWindowText(ghTextWnd, "Ellipse");
  1597.                 return 0L;
  1598.             case DID_FILLELLIPSE:
  1599.                 SetWindowText(ghTextWnd, "Filled Ellipse");
  1600.                 return 0L;
  1601.             case DID_LINE:
  1602.                 SetWindowText(ghTextWnd, "Line");
  1603.                 return 0L;
  1604.             case DID_BEZIER:
  1605.                 SetWindowText(ghTextWnd,
  1606.                     "Bezier: Click with Left button for placing control points");
  1607.                 return 0L;
  1608.             case DID_BMPOBJ:
  1609.                 SetWindowText(ghTextWnd,
  1610.                     "Bitmap: Click three points for the destination of the bitmap");
  1611.                 return 0L;
  1612.             case DID_METAF:
  1613.                 SetWindowText(ghTextWnd,
  1614.                     "External Metafile: Click three points for the destination of the Metafile");
  1615.                 return 0L;
  1616.             case MM_IMPORT_3X:
  1617.                 gbImport3X = (gbImport3X ? FALSE : TRUE);
  1618.  
  1619.                 if (gbImport3X)
  1620.                     CheckMenuItem(hMenu, MM_IMPORT_3X, MF_CHECKED);
  1621.                 else
  1622.                     CheckMenuItem(hMenu, MM_IMPORT_3X, MF_UNCHECKED);
  1623.                 return 0L;
  1624.  
  1625.             case MM_EXPORT_3X:
  1626.                 gbExport3X = (gbExport3X ? FALSE : TRUE);
  1627.  
  1628.                 if (gbExport3X)
  1629.                     CheckMenuItem(hMenu, MM_EXPORT_3X, MF_CHECKED);
  1630.                 else
  1631.                     CheckMenuItem(hMenu, MM_EXPORT_3X, MF_UNCHECKED);
  1632.                 return 0L;
  1633.             case MM_FIT2WND:
  1634.                 gbFit2Wnd = (gbFit2Wnd ? FALSE : TRUE);
  1635.  
  1636.                 if (gbFit2Wnd)
  1637.                     CheckMenuItem(hMenu, MM_FIT2WND, MF_CHECKED);
  1638.                 else
  1639.                     CheckMenuItem(hMenu, MM_FIT2WND, MF_UNCHECKED);
  1640.                 return 0L;
  1641.  
  1642.             case MM_PRINT: {
  1643.                 DWORD   dwThrdID;
  1644.                 HANDLE  hThrd;
  1645.                 PPRTDATA pPrtData;
  1646.  
  1647.                 if (ghMetaf == 0) {
  1648.                     SetWindowText(ghTextWnd, "NO Metafile to print");
  1649.                     return 0L;
  1650.                 }
  1651.  
  1652.                 //
  1653.                 // bPrintMf is supposed to free up the memory when done.
  1654.                 //
  1655.                 if ((pPrtData = (PPRTDATA) GlobalAlloc(GPTR, sizeof(PRTDATA))) == NULL) {
  1656.                     SetWindowText(ghTextWnd, "Failed in allocating memory");
  1657.                     return 0L;
  1658.                 }
  1659.  
  1660.                 pPrtData->hMetaf = ghMetaf;
  1661.                 pPrtData->bFit2Wnd = gbFit2Wnd;
  1662.  
  1663.                 hThrd = CreateThread(NULL, 0,
  1664.                              (LPTHREAD_START_ROUTINE)bPrintMf,
  1665.                              pPrtData, STANDARD_RIGHTS_REQUIRED,
  1666.                              &dwThrdID);
  1667.  
  1668.                 //
  1669.                 // Free the memory if CreateThread fails...
  1670.                 //
  1671.                 if (hThrd == NULL) {
  1672.                     SetWindowText(ghTextWnd, "Failed in creating printing thread");
  1673.                     GlobalFree(pPrtData);
  1674.                 }
  1675.  
  1676.                 return 0L;
  1677.  
  1678.             }
  1679.  
  1680.         default:
  1681.                 return DefWindowProc(hwnd, message, wParam, lParam);
  1682.         }
  1683.       }     // WM_COMMAND
  1684.       default:
  1685.         return DefWindowProc(hwnd, message, wParam, lParam);
  1686.     }
  1687. }
  1688.  
  1689. /******************************Public*Routine******************************\
  1690. *
  1691. * DrawSurfWndProc
  1692. *       Drawing surface window procedure
  1693. *
  1694. * Effects:  Trapping all mouse messages and call the DrawStuff appropriately
  1695. *           for drawing to the drawing surface DC and metafile DC as needed.
  1696. *
  1697. * Warnings:
  1698. *
  1699. * History:
  1700. *  30-Apr-1992 -by- Petrus Wong
  1701. * Wrote it.
  1702. \**************************************************************************/
  1703.  
  1704. long APIENTRY DrawSurfWndProc(
  1705.     HWND hwnd,
  1706.     UINT message,
  1707.     DWORD wParam,
  1708.     LONG lParam)
  1709. {
  1710.     static BOOL    bTrack = FALSE;
  1711.     static int     OrgX, OrgY;
  1712.     static int     PrevX, PrevY;
  1713.     static HDC     hDC;
  1714.     static HCURSOR hCurArrow, hCurHT;
  1715.  
  1716.     switch (message) {
  1717.       case WM_CREATE:
  1718.           {
  1719.               RECT       rect;
  1720.  
  1721.               hDC = GetDC(hwnd);
  1722.               if ((SetGraphicsMode(hDC, GM_ADVANCED)) == 0) {
  1723.                  MessageBox(ghwndMain, "Fail in setting Advanced Graphics Mode!", "Error", MB_OK);
  1724.               }
  1725.               ReleaseDC(hwnd, hDC);
  1726.  
  1727.               GetClientRect(GetParent(hwnd), &rect);
  1728.  
  1729.               SetWindowPos(hwnd, NULL,
  1730.                       0,
  1731.                       30,
  1732.                       rect.right-rect.left,
  1733.                       rect.bottom-rect.top-30,
  1734.                       SWP_NOZORDER | SWP_NOMOVE);
  1735.  
  1736. #if 0
  1737. //CreateCaret(hwnd, NULL, 1, 12);
  1738. //hbmp = LoadBitmap(ghModule, (LPCSTR)MAKEINTRESOURCE(BMID_TOOLBASED));
  1739.  
  1740. hPal = CreatePalette((LOGPALETTE *)&LogPal);
  1741. hDC = GetDC(hwnd);
  1742. hOldPal = SelectPalette(hDC, hPal, FALSE);
  1743. RealizePalette(hDC);
  1744.  
  1745. hbmp = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)&DIBHdr, CBM_CREATEDIB, &dib, (LPBITMAPINFO)&DIBHdr, DIB_PAL_COLORS);
  1746. CreateCaret(hwnd, hbmp, 1, 12);
  1747.  
  1748. ReleaseDC(hwnd, hDC);
  1749. #endif
  1750.  
  1751.               ghCurFont = GetStockObject(SYSTEM_FONT);
  1752.               GetObject(ghCurFont, sizeof(LOGFONT), &glf);
  1753.               hCurArrow = LoadCursor(NULL, IDC_ARROW);
  1754.               hCurHT = LoadCursor(NULL, IDC_CROSS);
  1755.               break;
  1756.           }
  1757.  
  1758.       case WM_LBUTTONDOWN: {
  1759.         int    x, y;
  1760.  
  1761.         x = (int) LOWORD(lParam);
  1762.         y = (int) HIWORD(lParam);
  1763.  
  1764.         if (gbHitTest) {
  1765.             hDC = GetDC(hwnd);
  1766.             bHitTest(hDC, x, y);
  1767.             ReleaseDC(hwnd, hDC);
  1768.             break;
  1769.         }
  1770.  
  1771.         bTrack = TRUE;
  1772.         OrgX = PrevX = x;
  1773.         OrgY = PrevY = y;
  1774.  
  1775.         hDC = GetDC(hwnd);
  1776.         SetCapture(hwnd);
  1777.         break;
  1778.       }
  1779.  
  1780.       case WM_MOUSEMOVE: {
  1781.         RECT rectClient;
  1782.         int NextX;
  1783.         int NextY;
  1784.  
  1785.         if (gbHitTest) {
  1786.             SetCursor(hCurHT);
  1787.         } else {
  1788.             SetCursor(hCurArrow);
  1789.         }
  1790.  
  1791.         // Update the selection region
  1792.         if (bTrack) {
  1793.             NextX = (SHORT) LOWORD(lParam);
  1794.             NextY = (SHORT) HIWORD(lParam);
  1795.  
  1796.             // Do not draw outside the window's client area
  1797.  
  1798.             GetClientRect (hwnd, &rectClient);
  1799.             if (NextX < rectClient.left) {
  1800.                 NextX = rectClient.left;
  1801.             } else if (NextX >= rectClient.right) {
  1802.                 NextX = rectClient.right - 1;
  1803.             }
  1804.             if (NextY < rectClient.top) {
  1805.                 NextY = rectClient.top;
  1806.             } else if (NextY >= rectClient.bottom) {
  1807.                 NextY = rectClient.bottom - 1;
  1808.             }
  1809.             if ((NextX != PrevX) || (NextY != PrevY)) {
  1810.                SetROP2(hDC, R2_NOT);           // Erases the previous box
  1811.                bDrawStuff(hDC, OrgX, OrgY, PrevX, PrevY, TRUE, TRUE, FALSE, NULL);
  1812.  
  1813.                //
  1814.                // Optimization.  Do not record in metafile DC if it is going
  1815.                // to be erased.  So only call bDrawStuff with the PEN tool.
  1816.                //
  1817.                if (gbRecording && (ghDCMetaf != NULL) && (gdwCurTool == DID_PEN)) {
  1818.                    bDrawStuff(ghDCMetaf, OrgX, OrgY, PrevX, PrevY, TRUE, TRUE, FALSE, NULL);
  1819.                }
  1820.  
  1821.  
  1822.             // Get the current mouse position
  1823.                PrevX = NextX;
  1824.                PrevY = NextY;
  1825.  
  1826.                //
  1827.                // SetROP2(hDC, R2_COPYPEN);
  1828.                //   This is commented out because we don't want to erase
  1829.                //   the background as it sweeps.
  1830.                //
  1831.                bDrawStuff(hDC, OrgX, OrgY, PrevX, PrevY, FALSE, TRUE, FALSE, NULL);
  1832.  
  1833.                if (gbRecording && (ghDCMetaf != NULL) && (gdwCurTool == DID_PEN)) {
  1834.                    bDrawStuff(ghDCMetaf, OrgX, OrgY, PrevX, PrevY, FALSE, TRUE, FALSE, NULL);
  1835.                }
  1836.  
  1837.             }
  1838.         }
  1839.         break;
  1840.  
  1841.       }
  1842.  
  1843.       case WM_LBUTTONUP: {
  1844.         int NextX;
  1845.         int NextY;
  1846.  
  1847.         if (!bTrack)
  1848.            break;
  1849.  
  1850.         // End the selection
  1851.            ReleaseCapture();
  1852.            bTrack = FALSE;
  1853.  
  1854.         // Erases the box
  1855.            //
  1856.            // SetROP2(hDC, R2_NOT);
  1857.            //   This is assumed to be R2_NOT, thus unnecessary
  1858.            //
  1859.            bDrawStuff(hDC, OrgX, OrgY, PrevX, PrevY, TRUE, FALSE, FALSE, NULL);
  1860.  
  1861.            if (gbRecording && (ghDCMetaf != NULL) && (gdwCurTool == DID_PEN)) {
  1862.                bDrawStuff(ghDCMetaf, OrgX, OrgY, PrevX, PrevY, TRUE, FALSE, FALSE, NULL);
  1863.            }
  1864.  
  1865.            NextX = (SHORT) LOWORD(lParam);
  1866.            NextY = (SHORT) HIWORD(lParam);
  1867.  
  1868.         // Draws the new box
  1869.            SetROP2(hDC, R2_COPYPEN);
  1870.            bDrawStuff(hDC, OrgX, OrgY, NextX, NextY, FALSE, FALSE, TRUE, NULL);
  1871.  
  1872.            ReleaseDC(hwnd, hDC);
  1873.  
  1874.            if (gbRecording && (ghDCMetaf != NULL)) {
  1875.                 bDrawStuff(ghDCMetaf, OrgX, OrgY, NextX, NextY, FALSE, FALSE, FALSE, NULL);
  1876.            }
  1877.  
  1878.         break;
  1879.       } // case WM_LBUTTONUP
  1880.  
  1881.       case WM_CHAR: {
  1882.  
  1883.         if (gdwCurTool != DID_TEXT)
  1884.             break;
  1885.  
  1886.         hDC = GetDC(hwnd);
  1887.         bDrawStuff(hDC, 0, 0, 0, 0, TRUE, FALSE, FALSE, (LPSTR)&wParam);
  1888.         ReleaseDC(hwnd, hDC);
  1889.  
  1890.         if (gbRecording && (ghDCMetaf != NULL)) {
  1891.             bDrawStuff(ghDCMetaf, 0, 0, 0, 0, TRUE, FALSE, FALSE, (LPSTR)&wParam);
  1892.         }
  1893.  
  1894.         break;
  1895.       }
  1896.  
  1897.       case WM_DESTROY: {
  1898.         DestroyCaret();
  1899.         DeleteObject(ghCurFont);
  1900.     PostQuitMessage(0);
  1901.     return 0L;
  1902.       }
  1903.  
  1904.       default:
  1905.     return DefWindowProc(hwnd, message, wParam, lParam);
  1906.     }
  1907. }
  1908.  
  1909.  
  1910. /***************************************************************************\
  1911. * About
  1912. *
  1913. * About dialog proc.
  1914. *
  1915. * History:
  1916. * 09-09-91 Petrus Wong    Rewrote.
  1917. * 04-13-91 ????         Created.
  1918. \***************************************************************************/
  1919.  
  1920. BOOL CALLBACK About (
  1921.     HWND hDlg,
  1922.     UINT message,
  1923.     DWORD wParam,
  1924.     LONG lParam)
  1925. {
  1926.     switch (message) {
  1927.     case WM_INITDIALOG:
  1928.         return TRUE;
  1929.  
  1930.     case WM_COMMAND:
  1931.         if (wParam == IDOK)
  1932.             EndDialog(hDlg, wParam);
  1933.         break;
  1934.     }
  1935.  
  1936.     return FALSE;
  1937.  
  1938.     UNREFERENCED_PARAMETER(lParam);
  1939.     UNREFERENCED_PARAMETER(hDlg);
  1940. }
  1941.  
  1942. /***************************************************************************\
  1943. *
  1944. * TextWndProc
  1945. *
  1946. * Text Window procedure for displaying miscellaneous messages to user.
  1947. *
  1948. * History:
  1949. * 10-07-91  Petrus Wong
  1950. *   3D text output
  1951. *
  1952. \***************************************************************************/
  1953.  
  1954. LONG APIENTRY TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
  1955. {
  1956.     static HFONT hFont = (HFONT) NULL;
  1957.  
  1958.     switch (message)
  1959.     {
  1960.     case WM_CREATE:
  1961.         {
  1962.         LOGFONT    lf;
  1963.         HDC        hDC;
  1964.         HFONT      hOldFont;
  1965.             TEXTMETRIC tm;
  1966.         //RECT       rect;
  1967.  
  1968.             SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), (PVOID) &lf, (UINT)FALSE);
  1969.  
  1970.         hDC = GetDC(hwnd);
  1971.         // this is the height for 8 point size font in pixels
  1972.         lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
  1973.  
  1974.         hFont = CreateFontIndirect(&lf);
  1975.         hOldFont = SelectObject(hDC, hFont);
  1976.         GetTextMetrics(hDC, &tm);
  1977.  
  1978.         // base the height of the window on size of text
  1979.         glcyStatus = tm.tmHeight+6*GetSystemMetrics(SM_CYBORDER)+2;
  1980.             ReleaseDC(hwnd, hDC);
  1981.             break;
  1982.         }
  1983.  
  1984.     case WM_DESTROY:
  1985.         if (hFont)
  1986.         DeleteObject(hFont);
  1987.         break;
  1988.  
  1989.     case WM_SETTEXT:
  1990.             DefWindowProc(hwnd, message, wParam, lParam);
  1991.             InvalidateRect(hwnd,NULL,FALSE);
  1992.             UpdateWindow(hwnd);
  1993.             return 0L;
  1994.  
  1995.     case WM_PAINT:
  1996.         {
  1997.             PAINTSTRUCT ps;
  1998.             RECT   rc;
  1999.             char   ach[128];
  2000.             int    len, nxBorder, nyBorder;
  2001.             HFONT  hOldFont = NULL;
  2002.  
  2003.             BeginPaint(hwnd, &ps);
  2004.  
  2005.             GetClientRect(hwnd,&rc);
  2006.  
  2007.             nxBorder = GetSystemMetrics(SM_CXBORDER);
  2008.         rc.left  += 9*nxBorder;
  2009.             rc.right -= 9*nxBorder;
  2010.  
  2011.             nyBorder = GetSystemMetrics(SM_CYBORDER);
  2012.         rc.top    += 3*nyBorder;
  2013.         rc.bottom -= 3*nyBorder;
  2014.  
  2015.         // 3D Text
  2016.             len = GetWindowText(hwnd, ach, sizeof(ach));
  2017.         SetBkColor(ps.hdc, GetSysColor(COLOR_BTNFACE));
  2018.  
  2019.         SetBkMode(ps.hdc, TRANSPARENT);
  2020.         SetTextColor(ps.hdc, RGB(64,96,96));
  2021.         if (hFont)
  2022.         hOldFont = SelectObject(ps.hdc, hFont);
  2023.         ExtTextOut(ps.hdc, rc.left+2*nxBorder+2, rc.top+2, ETO_OPAQUE | ETO_CLIPPED,
  2024.                     &rc, ach, len, NULL);
  2025.  
  2026.         SetTextColor(ps.hdc, RGB(128,128,128));
  2027.           if (hFont)
  2028.         hOldFont = SelectObject(ps.hdc, hFont);
  2029.         ExtTextOut(ps.hdc, rc.left+2*nxBorder+1, rc.top+1, ETO_CLIPPED,
  2030.             &rc, ach, len, NULL);
  2031.  
  2032.         SetTextColor(ps.hdc, RGB(255,255,255));
  2033.         if (hFont)
  2034.         hOldFont = SelectObject(ps.hdc, hFont);
  2035.         ExtTextOut(ps.hdc, rc.left+2*nxBorder, rc.top, ETO_CLIPPED,
  2036.             &rc, ach, len, NULL);
  2037.  
  2038.         SetBkMode(ps.hdc, OPAQUE);
  2039.  
  2040.         if (hOldFont)
  2041.         SelectObject(ps.hdc, hOldFont);
  2042.  
  2043.             EndPaint(hwnd, &ps);
  2044.             return 0L;
  2045.         }
  2046.     }
  2047.     return DefWindowProc(hwnd, message, wParam, lParam);
  2048. }
  2049.  
  2050. /******************************Public*Routine******************************\
  2051. *
  2052. * CtrlPanelDlgProc
  2053. *       The Control Panel dialog procedure
  2054. *
  2055. * Effects:  Responsible for drawing the owner draw buttons.  Notifying
  2056. *           parent of user's action.
  2057. *
  2058. * Warnings:
  2059. *
  2060. * History:
  2061. *  27-May-1992 -by- Petrus Wong
  2062. * Wrote it.
  2063. \**************************************************************************/
  2064.  
  2065. LONG APIENTRY CtrlPanelDlgProc(HWND hwnd, UINT msg, DWORD dwParam, LONG lParam)
  2066. {
  2067.     switch (msg) {
  2068.         case WM_INITDIALOG: {
  2069.             int index;
  2070.  
  2071.             for (index = 0; index < OD_BTN_CNT; index++) {
  2072.                 grHwndCtrlBtn[index] = (PVOID)GetDlgItem(hwnd, (INT)(ID_OD_BTN_BASE+index));
  2073.             }
  2074.             for (index = 0; index < OD_TOOL_CNT; index++) {
  2075.                 grHwndToolBtn[index] = (PVOID)GetDlgItem(hwnd, (INT)(ID_OD_TOOL_BASE+index));
  2076.             }
  2077.             return TRUE;
  2078.         }
  2079.  
  2080.         case WM_DRAWITEM: {
  2081.             PDRAWITEMSTRUCT pDIS = (PDRAWITEMSTRUCT) lParam;
  2082.             HBITMAP hBmpOld;
  2083.             BITMAP  bm;
  2084.             HANDLE  hCtl;
  2085.             HDC     hDCCtl;
  2086.  
  2087.             if (pDIS->CtlID == gdwCurCtrl) {
  2088.                 GetObject((HBITMAP) ghBmpDn[pDIS->CtlID - ID_OD_BTN_BASE], sizeof(BITMAP), (LPSTR)&bm);
  2089.                 hBmpOld = SelectObject(ghDCMem, (HBITMAP) ghBmpDn[pDIS->CtlID - ID_OD_BTN_BASE]);
  2090.             }
  2091.  
  2092.             if (pDIS->CtlID == gdwCurTool) {
  2093.                 GetObject((HBITMAP)ghToolBmpDn[pDIS->CtlID - ID_OD_TOOL_BASE], sizeof(BITMAP), (LPSTR)&bm);
  2094.                 hBmpOld = SelectObject(ghDCMem, (HBITMAP)ghToolBmpDn[pDIS->CtlID - ID_OD_TOOL_BASE]);
  2095.             }
  2096.  
  2097.             if ((pDIS->CtlID < ID_OD_TOOL_BASE) && (pDIS->CtlID != gdwCurCtrl)) {
  2098.                 GetObject((HBITMAP)ghBmpUp[pDIS->CtlID - ID_OD_BTN_BASE], sizeof(BITMAP), (LPSTR)&bm);
  2099.                 hBmpOld = SelectObject(ghDCMem, (HBITMAP)ghBmpUp[pDIS->CtlID - ID_OD_BTN_BASE]);
  2100.             }
  2101.  
  2102.             if ((pDIS->CtlID >= ID_OD_TOOL_BASE) && (pDIS->CtlID != gdwCurTool)) {
  2103.                 GetObject((HBITMAP)ghToolBmpUp[pDIS->CtlID - ID_OD_TOOL_BASE], sizeof(BITMAP), (LPSTR)&bm);
  2104.                 hBmpOld = SelectObject(ghDCMem, (HBITMAP)ghToolBmpUp[pDIS->CtlID - ID_OD_TOOL_BASE]);
  2105.             }
  2106.  
  2107.             //
  2108.             // pDIS->hDC is clipped to the update region but unfortunately
  2109.             // that doesn't work well with StretchBlt.  StretchBlt is used
  2110.             // because I don't have to make sure that the bitmap size is
  2111.             // exactly the same as the size of the button.
  2112.             //
  2113.             hCtl   = GetDlgItem(hwnd, pDIS->CtlID);
  2114.             hDCCtl = GetDC(hCtl);
  2115.             StretchBlt(hDCCtl,                                //pDIS->hDC,
  2116.                    pDIS->rcItem.left, pDIS->rcItem.top,
  2117.                    pDIS->rcItem.right - pDIS->rcItem.left,
  2118.                    pDIS->rcItem.bottom - pDIS->rcItem.top,
  2119.                    ghDCMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
  2120.             ReleaseDC(hCtl, hDCCtl);
  2121.             SelectObject(ghDCMem, hBmpOld);
  2122.             break;
  2123.         }
  2124.  
  2125.         case WM_COMMAND: {
  2126.             DWORD dwOldCtrl = gdwCurCtrl;
  2127.             DWORD dwOldTool = gdwCurTool;
  2128.  
  2129.             switch (dwParam) {
  2130.                 case DID_ONE:
  2131.                 case DID_TWO:
  2132.                 case DID_THREE:
  2133.                 case DID_FOUR:
  2134.                 case DID_FIVE:
  2135.                 case DID_SIX:
  2136.                 case DID_SEVEN:
  2137.                 case DID_EIGHT:
  2138.                 case DID_NINE:
  2139.                 case DID_ZERO:
  2140.                 case DID_TEN_PLUS:
  2141.                     //SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, dwParam - DID_ZERO, FALSE);
  2142.                     SendMessage(ghwndMain, WM_COMMAND, dwParam, lParam);
  2143.                     break;
  2144.                 case DID_OPEN:
  2145.                 case DID_RECORD:
  2146.                 case DID_STOP:
  2147.                 case DID_PLAY:
  2148.                 case DID_FF:
  2149.                     SendMessage(ghwndMain, WM_COMMAND, dwParam, lParam);
  2150.                     gdwCurCtrl = dwParam;
  2151.                     InvalidateRect((HWND)grHwndCtrlBtn[dwOldCtrl - ID_OD_BTN_BASE], NULL, FALSE);
  2152.                     InvalidateRect((HWND)grHwndCtrlBtn[gdwCurCtrl - ID_OD_BTN_BASE], NULL, FALSE);
  2153.                     break;
  2154.                 case DID_CLEAR:
  2155.                     SendMessage(ghwndMain, WM_COMMAND, dwParam, lParam);
  2156.                     break;
  2157.                 case DID_TEXT:
  2158.                 case DID_PEN:
  2159.                 case DID_RECT:
  2160.                 case DID_FILLRECT:
  2161.                 case DID_ELLIPSE:
  2162.                 case DID_FILLELLIPSE:
  2163.                 case DID_LINE:
  2164.                 case DID_BEZIER:
  2165.                 case DID_BMPOBJ:
  2166.                 case DID_METAF:
  2167.                     SendMessage(ghwndMain, WM_COMMAND, dwParam, lParam);
  2168.                     gdwCurTool = dwParam;
  2169.                     InvalidateRect((HWND)grHwndToolBtn[dwOldTool - ID_OD_TOOL_BASE], NULL, FALSE);
  2170.                     InvalidateRect((HWND)grHwndToolBtn[gdwCurTool - ID_OD_TOOL_BASE], NULL, FALSE);
  2171.                     break;
  2172.             }
  2173.             break;
  2174.         }
  2175.  
  2176.  
  2177.         case WM_PAINT:
  2178.             {
  2179.                 HDC hdc;
  2180.                 RECT rc, rcDlg;
  2181.                 PAINTSTRUCT ps;
  2182.                 HPEN hpenWindowFrame, hpenDarkGray;
  2183.                 int  icyDlg;
  2184.                 int  icyBorder;
  2185.  
  2186.                 icyBorder = GetSystemMetrics(SM_CYBORDER);
  2187.  
  2188.                 GetWindowRect(hwnd, &rcDlg);
  2189.                 icyDlg = rcDlg.right - rcDlg.left;
  2190.  
  2191.                 /*
  2192.                  * Draw our border lines.
  2193.                  */
  2194.                 GetClientRect(hwnd, &rc);
  2195.                 hdc = BeginPaint(hwnd, &ps);
  2196.  
  2197.                 SelectObject(hdc, GetStockObject(WHITE_PEN));
  2198.                 MoveToEx(hdc, rc.left, rc.top, NULL);
  2199.                 LineTo(hdc, rc.right, rc.top);
  2200.  
  2201.                 hpenDarkGray = CreatePen(PS_SOLID, 1, DARKGRAY);
  2202.                 SelectObject(hdc, hpenDarkGray);
  2203.                 MoveToEx(hdc, rc.left, (rc.top + icyDlg) - icyBorder - 1, NULL);
  2204.                 LineTo(hdc, rc.right, (rc.top + icyDlg) - icyBorder - 1);
  2205.  
  2206.                 hpenWindowFrame = CreatePen(PS_SOLID, icyBorder,
  2207.                         GetSysColor(COLOR_WINDOWFRAME));
  2208.                 SelectObject(hdc, hpenWindowFrame);
  2209.                 MoveToEx(hdc, rc.left, (rc.top + icyDlg) - icyBorder, NULL);
  2210.                 LineTo(hdc, rc.right, (rc.top + icyDlg) - icyBorder);
  2211.  
  2212.                 EndPaint(hwnd, &ps);
  2213.                 DeleteObject(hpenWindowFrame);
  2214.                 DeleteObject(hpenDarkGray);
  2215.             }
  2216.  
  2217.             break;
  2218.  
  2219.  
  2220.         //case WM_CTLCOLOR:
  2221.         case WM_CTLCOLORDLG:
  2222.         //case WM_CTLCOLORLISTBOX:
  2223.         case WM_CTLCOLORSTATIC:
  2224.             switch (GET_WM_CTLCOLOR_TYPE(dwParam, lParam, msg)) {
  2225.                 case CTLCOLOR_DLG:
  2226.                 //case CTLCOLOR_LISTBOX:
  2227.                     return (BOOL)GetStockObject(LTGRAY_BRUSH);
  2228.  
  2229.                 case CTLCOLOR_STATIC:
  2230.                     SetBkMode(GET_WM_CTLCOLOR_HDC(dwParam, lParam, msg),
  2231.                               TRANSPARENT);
  2232.                 //    SetTextColor(GET_WM_CTLCOLOR_HDC(dwParam, lParam, msg),
  2233.                 //              RGB(255,0,0));
  2234.                 //    SetBkColor(GET_WM_CTLCOLOR_HDC(dwParam, lParam, msg),
  2235.                 //            LIGHTGRAY);
  2236.                 //              RGB(255, 255,0));
  2237.                     return (BOOL)GetStockObject(DKGRAY_BRUSH);
  2238.             }
  2239.             //return (BOOL)NULL;
  2240.             return (BOOL)GetStockObject(LTGRAY_BRUSH);
  2241.  
  2242.         default:
  2243.             return FALSE;
  2244.     }
  2245.  
  2246.     return FALSE;
  2247. }
  2248.  
  2249.  
  2250.  
  2251. /******************************Public*Routine******************************\
  2252. *
  2253. * bDrawStuff
  2254. *
  2255. * Effects:  The drawing routines are localized here.
  2256. *           bErase is TRUE if this fcn is called for erasing previous object.
  2257. *           (as in tracking objects.)  It is FALSE, otherwise.
  2258. *
  2259. *           bMove is TRUE if this fcn is called inside the WM_MOUSEMOVE (as
  2260. *           in tracking objects.)  It is FALSE, otherwise.
  2261. *
  2262. *           bCntPt is TRUE if this fcn is to increment either the iCnt or
  2263. *           iCntMF counter (used only in processing metafile or bezier.)
  2264. *           It is FALSE, otherwise.
  2265. *
  2266. *           lpstr contains the character to be drawn by TextOut when it is
  2267. *           not NULL.
  2268. *
  2269. * Warnings: Metafile and Bezier assume that the caller is calling this fcn
  2270. *           to draw in the screen DC first. Then draw it to the metafile DC.
  2271. *           Thus, when it is called to draw on the metafile DC, the points
  2272. *           would have been set already.
  2273. *
  2274. * History:
  2275. *  10-May-1992 -by- Petrus Wong
  2276. * Wrote it.
  2277. \**************************************************************************/
  2278.  
  2279. BOOL bDrawStuff(HDC hDC, INT OrgX, INT OrgY,
  2280.                          INT NextX, INT NextY,
  2281.                          BOOL bErase,
  2282.                          BOOL bMove,
  2283.                          BOOL bCntPt,
  2284.                          LPSTR lpstr) {
  2285.     BOOL bSuccess;
  2286.     HGDIOBJ hObjOld;
  2287.     static POINT rgPts[MAX_POINTS], rgPtsMF[MAX_POINTS_MF], rgPtsBMP[MAX_POINTS_BMP];
  2288.     static int   iCnt=0, iCntMF=0, iCntBMP=0;
  2289.     static BOOL  bCaretShown=FALSE;
  2290.  
  2291.     bSuccess = TRUE;
  2292.     if (bCaretShown) {
  2293.         HideCaret(ghwndDrawSurf);
  2294.         bCaretShown = FALSE;
  2295.     }
  2296.  
  2297.     switch (gdwCurTool) {
  2298.         case DID_PEN:
  2299.             if (bErase) {
  2300.                 MoveToEx(hDC, NextX, NextY, NULL);
  2301.             } else {
  2302.                 //
  2303.                 // Override the ROP2 st. the pen won't erase its track
  2304.                 //
  2305.                 SetROP2(hDC, R2_COPYPEN);
  2306.                 LineTo(hDC, NextX, NextY);
  2307.             }
  2308.             break;
  2309.         case DID_TEXT: {
  2310.             POINT   Pt;
  2311. #if 0
  2312. HDC hDCMem;
  2313. #endif
  2314.  
  2315.             if (lpstr == NULL) {
  2316.                 ShowCaret(ghwndDrawSurf);
  2317.                 bCaretShown = TRUE;
  2318.                 SetCaretPos(NextX, NextY);
  2319.                 MoveToEx(hDC, NextX, NextY, NULL);
  2320.  
  2321. #if 0
  2322. StretchDIBits(hDC, 20, 20+120, 64, 64, 0, 64, 64, -64, &dib,
  2323.                     (LPBITMAPINFO)&DIBHdr, DIB_PAL_COLORS, SRCCOPY);
  2324.  
  2325. hDCMem = CreateCompatibleDC(hDC);
  2326. SelectPalette(hDCMem, hPal, FALSE);
  2327. RealizePalette(hDCMem);
  2328. SelectObject(hDCMem, hbmp);
  2329. BitBlt(hDC, 0,0,64,64,hDCMem, 0,0,SRCCOPY);
  2330. DeleteDC(hDCMem);
  2331. #endif
  2332.  
  2333.  
  2334.  
  2335.  
  2336.                 SetFocus(ghwndDrawSurf);
  2337.                 break;
  2338.             }
  2339.  
  2340.             SetTextAlign(hDC, TA_BASELINE | TA_LEFT | TA_UPDATECP);
  2341.             hObjOld = SelectObject(hDC, ghCurFont);
  2342.             SetTextColor(hDC, gCrText);
  2343.  
  2344.             if ((gbSFOutln || gbPDOutln) && gbTT) {
  2345.                 // get rid of the char box
  2346.                 SetBkMode(hDC, TRANSPARENT);
  2347.                 BeginPath(hDC);
  2348.                 TextOut(hDC, NextX,    NextY,    lpstr, 1);
  2349.                 EndPath(hDC);
  2350.  
  2351.                 if (gbSFOutln) {
  2352.                     StrokeAndFillPath(hDC);
  2353.                     goto DT_UPDATE;
  2354.                 }
  2355.  
  2356.                 //
  2357.                 // Get path and polydraw
  2358.                 //
  2359.                 {
  2360.                 int     iNumPt;
  2361.                 PBYTE   pjTypes;
  2362.                 PPOINT  pPts;
  2363.  
  2364.                 if (iNumPt = GetPath(hDC, NULL, NULL, 0)) {
  2365.                     if ((pPts = (PPOINT)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  2366.                                                 sizeof(POINT)*iNumPt )) == NULL) {
  2367.                         MessageBox(ghwndMain, "Failed in Creating POINT!", "Error", MB_OK);
  2368.                         break;
  2369.                     }
  2370.  
  2371.                     if ((pjTypes = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  2372.                                                 sizeof(BYTE)*iNumPt )) == NULL) {
  2373.                         MessageBox(ghwndMain, "Failed in Creating PBYTE!", "Error", MB_OK);
  2374.                         goto GP_EXIT1;
  2375.                     }
  2376.  
  2377.                     GetPath(hDC, pPts, pjTypes, iNumPt);
  2378.                 }
  2379.                 PolyDraw(hDC, pPts, pjTypes, iNumPt);
  2380.                 LocalFree(pjTypes);
  2381.  
  2382. GP_EXIT1:
  2383.                 LocalFree(pPts);
  2384.  
  2385.                 }
  2386.  
  2387.             } else {
  2388.                 TextOut(hDC, NextX,    NextY,    lpstr, 1);
  2389.             }
  2390. DT_UPDATE:
  2391.             //
  2392.             // Updating current position
  2393.             //
  2394.             {
  2395.             LONG    lHeight;
  2396.             LONG    lWidth;
  2397.             TEXTMETRIC     tm;
  2398.  
  2399.                 if (GetTextMetrics(hDC, &tm)) {
  2400.                     lHeight = tm.tmHeight;
  2401.                     lWidth  = tm.tmMaxCharWidth;
  2402.                 }
  2403.  
  2404.                 GetCurrentPositionEx(hDC, (LPPOINT) &Pt);
  2405.                 SetCaretPos(Pt.x+lWidth, Pt.y);
  2406.  
  2407.             }
  2408.             ShowCaret(ghwndDrawSurf);
  2409.             bCaretShown = TRUE;
  2410.  
  2411.             break;
  2412.  
  2413. #if 0
  2414.  
  2415. #define PT_LINECLOSE     (PT_LINETO | PT_CLOSEFIGURE)
  2416. #define PT_BEZIERCLOSE (PT_BEZIERTO | PT_CLOSEFIGURE)
  2417.  
  2418.             hpnRed = CreatePen(PS_SOLID, 0, RGB(255,0,0));
  2419.             SelectObject(hDC, hpnRed);
  2420.  
  2421.             while (iNumPt--) {
  2422.                 static POINT pPnt[3];
  2423.                 static int   iCnt=0;
  2424.  
  2425.                 switch (*pjTypes++) {
  2426.                     case PT_MOVETO: {
  2427.                         MoveToEx(hDC, pPts->x, pPts->y, NULL);
  2428.                         pPts++;
  2429.                         break;
  2430.                     }
  2431.                     case PT_LINETO: {
  2432.                         LineTo(hDC, pPts->x, pPts->y);
  2433.                         pPts++;
  2434.                         break;
  2435.  
  2436.                     }
  2437.                     case PT_LINECLOSE: {
  2438.                         LineTo(hDC, pPts->x, pPts->y);
  2439.                         pPts++;
  2440.                         goto GP_EXIT2;
  2441.                     }
  2442.                     case PT_BEZIERTO: {
  2443.                         pPnt[iCnt].x = pPts->x;
  2444.                         pPnt[iCnt].y = pPts->y;
  2445.                         pPts++;
  2446.  
  2447.                         if (iCnt < 2) {
  2448.                             iCnt++;
  2449.                         } else {
  2450.                             PolyBezierTo(hDC, pPnt, 3);
  2451.                             iCnt = 0;
  2452.                         }
  2453.                         break;
  2454.                     }
  2455.                     case PT_BEZIERCLOSE: {
  2456.                         pPnt[iCnt].x = pPts->x;
  2457.                         pPnt[iCnt].y = pPts->y;
  2458.                         pPts++;
  2459.  
  2460.                         if (iCnt < 2) {
  2461.                             iCnt++;
  2462.                         } else {
  2463.                             PolyBezierTo(hDC, pPnt, 3);
  2464.                             iCnt = 0;
  2465.                         }
  2466.                         goto GP_EXIT2;
  2467.                     }
  2468.  
  2469.                     default:
  2470.                         break;
  2471.                 }
  2472.  
  2473.             }
  2474.  
  2475. #endif
  2476.         }
  2477.         case DID_RECT:
  2478.             hObjOld = SelectObject(hDC, GetStockObject(NULL_BRUSH));
  2479.             Rectangle(hDC, OrgX, OrgY, NextX, NextY);
  2480.             SelectObject(hDC, hObjOld);
  2481.             break;
  2482.         case DID_FILLRECT:
  2483.             Rectangle(hDC, OrgX, OrgY, NextX, NextY);
  2484.             break;
  2485.         case DID_ELLIPSE:
  2486.             hObjOld = SelectObject(hDC, GetStockObject(NULL_BRUSH));
  2487.             Ellipse(hDC, OrgX, OrgY, NextX, NextY);
  2488.             SelectObject(hDC, hObjOld);
  2489.             break;
  2490.         case DID_FILLELLIPSE:
  2491.             Ellipse(hDC, OrgX, OrgY, NextX, NextY);
  2492.             break;
  2493.         case DID_LINE:
  2494.             MoveToEx(hDC, OrgX, OrgY, NULL);
  2495.             LineTo(hDC, NextX, NextY);
  2496.             break;
  2497.         case DID_BEZIER:
  2498.             if (bErase || bMove)
  2499.                 return bSuccess;
  2500.  
  2501.             if (bCntPt) {
  2502.                 rgPts[iCnt].x = NextX;
  2503.                 rgPts[iCnt].y = NextY;
  2504.                 iCnt++;
  2505.  
  2506.                 if (iCnt == MAX_POINTS - 1)
  2507.                     iCnt = 0;
  2508.             }
  2509.  
  2510.             if ((iCnt % 3) == 1) {              // (iCnt + 1) % 3 == 1
  2511.                 //
  2512.                 // Override the ROP2 st. the pen won't erase its track
  2513.                 //
  2514.                 SetROP2(hDC, R2_COPYPEN);
  2515.                 PolyBezier(hDC, (LPPOINT)&rgPts, (DWORD) iCnt);
  2516.             }
  2517.             return bSuccess;
  2518.  
  2519.         case DID_BMPOBJ: {
  2520.             static BOOL          bBltReady = FALSE;
  2521.  
  2522.             if (bErase || bMove)
  2523.                 return bSuccess;
  2524.  
  2525.             if (ghBmp == NULL) {
  2526.                 SetWindowText(ghTextWnd, "ERROR: No bitmap to embed!");
  2527.                 return bSuccess;
  2528.             }
  2529.  
  2530.             if (bCntPt) {
  2531.                 bBltReady = FALSE;
  2532.                 rgPtsBMP[iCntBMP].x = NextX;
  2533.                 rgPtsBMP[iCntBMP].y = NextY;
  2534.                 iCntBMP++;
  2535.  
  2536.                 if (iCntBMP < MAX_POINTS_BMP) {
  2537.                     return bSuccess;
  2538.                 }
  2539.             } else {
  2540.                 //
  2541.                 // Caller don't want to increment counter, so must be doing
  2542.                 // recording, so we just Blt again...
  2543.                 //
  2544.                 // But, if the Blt data is no good, bail out...
  2545.                 //
  2546.                 if (!bBltReady) {
  2547.                     return bSuccess;
  2548.                 }
  2549.                 bPlgBlt(hDC, rgPtsBMP);
  2550.                 return bSuccess;
  2551.             }
  2552.             bBltReady = TRUE;
  2553.  
  2554.             bPlgBlt(hDC, rgPtsBMP);
  2555.             iCntBMP = 0;                         // reset
  2556.             return bSuccess;
  2557.         }
  2558.  
  2559.         case DID_METAF: {
  2560.             ENHMETAHEADER EnhMetaHdr;
  2561.             RECT          rcClientDS;
  2562.             static XFORM         xform;
  2563.             static BOOL          bXformReady = FALSE;
  2564.             int           iEntries;
  2565.             PLOGPALETTE     plogPal;
  2566.             PBYTE           pjTmp;
  2567.             HPALETTE        hPal;
  2568.  
  2569.  
  2570.             if (bErase || bMove)
  2571.                 return bSuccess;
  2572.  
  2573.             if (ghMetaf == NULL) {
  2574.                 SetWindowText(ghTextWnd, "ERROR: No metafile to embed!");
  2575.                 return bSuccess;
  2576.             }
  2577.  
  2578.             if (bCntPt) {
  2579.                 bXformReady = FALSE;
  2580.                 rgPtsMF[iCntMF].x = NextX;
  2581.                 rgPtsMF[iCntMF].y = NextY;
  2582.                 iCntMF++;
  2583.  
  2584.                 if (iCntMF < MAX_POINTS_MF) {
  2585.                     return bSuccess;
  2586.                 }
  2587.             } else {
  2588.                 //
  2589.                 // Caller don't want to increment counter, so must be doing
  2590.                 // recording, so we just set xform and play it again...
  2591.                 //
  2592.                 // But, if the xform data is no good, bail out...
  2593.                 //
  2594.                 if (!bXformReady) {
  2595.                     return bSuccess;
  2596.                 }
  2597.  
  2598.                 GetEnhMetaFileHeader(ghMetaf, sizeof(ENHMETAHEADER), &EnhMetaHdr);
  2599.                 SetWorldTransform(hDC, &xform);
  2600.                 GetClientRect(ghwndDrawSurf, &rcClientDS);
  2601.  
  2602.                 iEntries = GetEnhMetaFilePaletteEntries(ghMetaf, 0, NULL);
  2603.  
  2604.                 if (iEntries) {
  2605.                     if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  2606.                             sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) {
  2607.                         MessageBox(ghwndMain, "Failed in Creating Palette!", "Error", MB_OK);
  2608.                     }
  2609.  
  2610.                     plogPal->palVersion = 0x300;
  2611.                     plogPal->palNumEntries = (WORD) iEntries;
  2612.                     pjTmp = (PBYTE) plogPal;
  2613.                     pjTmp += 8;
  2614.  
  2615.                     GetEnhMetaFilePaletteEntries(ghMetaf, iEntries, (PPALETTEENTRY)pjTmp);
  2616.                     hPal = CreatePalette(plogPal);
  2617.                     GlobalFree(plogPal);
  2618.  
  2619.                     SelectPalette(hDC, hPal, FALSE);
  2620.                     RealizePalette(hDC);
  2621.                 }
  2622.  
  2623.                 //PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &rcClientDS);
  2624.                 {
  2625.                 RECT rc;
  2626.  
  2627.                 rc.top = rc.left = 0;
  2628.                 rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left;
  2629.                 rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top;
  2630.                 if (!PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &rc)) {
  2631.                     char    text[128];
  2632.  
  2633.                     wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError());
  2634.                     OutputDebugString(text);
  2635.                 }
  2636.  
  2637.                 }
  2638.                 ModifyWorldTransform(hDC, NULL, MWT_IDENTITY);
  2639.                 return bSuccess;
  2640.             }
  2641.  
  2642.             GetEnhMetaFileHeader(ghMetaf, sizeof(ENHMETAHEADER), &EnhMetaHdr);
  2643.             //
  2644.             // Based on the three points, top-left, top-right and bottom-left
  2645.             // (in this order), of the destination, solve equations for the
  2646.             // elements of the transformation matrix.
  2647.             //
  2648.             xform.eDx = (float) rgPtsMF[0].x;
  2649.             xform.eDy = (float) rgPtsMF[0].y;
  2650.             xform.eM11 = (rgPtsMF[1].x - xform.eDx)/(EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left);
  2651.             xform.eM12 = (rgPtsMF[1].y - xform.eDy)/(EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left);
  2652.             xform.eM21 = (rgPtsMF[2].x - xform.eDx)/(EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top);
  2653.             xform.eM22 = (rgPtsMF[2].y - xform.eDy)/(EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top);
  2654.  
  2655.             bXformReady = TRUE;
  2656.             SetWorldTransform(hDC, &xform);
  2657.             GetClientRect(ghwndDrawSurf, &rcClientDS);
  2658.  
  2659.             iEntries = GetEnhMetaFilePaletteEntries(ghMetaf, 0, NULL);
  2660.  
  2661.             if (iEntries) {
  2662.                 if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  2663.                         sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) {
  2664.                     MessageBox(ghwndMain, "Failed in Creating Palette!", "Error", MB_OK);
  2665.                 }
  2666.  
  2667.                 plogPal->palVersion = 0x300;
  2668.                 plogPal->palNumEntries = (WORD) iEntries;
  2669.                 pjTmp = (PBYTE) plogPal;
  2670.                 pjTmp += 8;
  2671.  
  2672.                 GetEnhMetaFilePaletteEntries(ghMetaf, iEntries, (PPALETTEENTRY)pjTmp);
  2673.                 hPal = CreatePalette(plogPal);
  2674.                 GlobalFree(plogPal);
  2675.  
  2676.                 SelectPalette(hDC, hPal, FALSE);
  2677.                 RealizePalette(hDC);
  2678.             }
  2679.  
  2680.             //PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &rcClientDS);
  2681.             {
  2682.             RECT rc;
  2683.  
  2684.             rc.top = rc.left = 0;
  2685.             rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left;
  2686.             rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top;
  2687.             if (!PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &rc)) {
  2688.                  char    text[128];
  2689.  
  2690.                  wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError());
  2691.                  OutputDebugString(text);
  2692.             }
  2693.  
  2694.             }
  2695.             ModifyWorldTransform(hDC, NULL, MWT_IDENTITY);
  2696.             iCntMF = 0;                         // reset
  2697.             return bSuccess;
  2698.         }
  2699.         default:
  2700.             break;
  2701.     }
  2702.     //
  2703.     // Reset counter, user has selected other tools.
  2704.     //
  2705.     iCnt = 0;
  2706.     iCntMF = 0;
  2707.     iCntBMP = 0;
  2708.     return bSuccess;
  2709. }
  2710.  
  2711. /******************************Public*Routine******************************\
  2712. *
  2713. * hemfLoadMetafile
  2714. *
  2715. * Effects:   Brings up the Open file common dialog
  2716. *            Get the enhanced metafile spec'd by user
  2717. *            returns the handle to the enhanced metafile if successfull
  2718. *               otherwise, returns 0.
  2719. *
  2720. * Warnings:
  2721. *
  2722. * History:
  2723. *  08-May-1992 -by- Petrus Wong
  2724. * Wrote it.
  2725. *  28-Aug-1992 -by- Petrus Wong     supports aldus placable mf, wmf and emf
  2726. \**************************************************************************/
  2727.  
  2728. HENHMETAFILE hemfLoadMetafile(HWND hwnd) {
  2729.     OPENFILENAME    ofn;
  2730.     char            szFile[256], szFileTitle[256];
  2731.     static char     *szFilter;
  2732.  
  2733.     HMETAFILE       hmf;
  2734.     UINT            uiSize;
  2735.     LPVOID          pvData;
  2736.     HDC             hDCDrawSurf;
  2737.     HENHMETAFILE    hemf;
  2738.  
  2739.     HANDLE                  hFile, hMapFile;
  2740.     LPVOID                  pMapFile;
  2741.     LPENHMETAHEADER         pemh;
  2742.  
  2743.     BOOL        bSuccess;
  2744.     char            text[128];
  2745.  
  2746.  
  2747.     bSuccess = TRUE;
  2748.  
  2749.     szFilter =
  2750.       "EnhMeta files (*.emf)\0*.emf\0Windows Metafiles (*.wmf)\0*.wmf\0\0";
  2751.  
  2752.     strcpy(szFile, "*.emf\0");
  2753.     ofn.lStructSize = sizeof(OPENFILENAME);
  2754.     ofn.hwndOwner = hwnd;
  2755.     ofn.lpstrFilter = szFilter;
  2756.     ofn.lpstrCustomFilter = (LPSTR) NULL;
  2757.     ofn.nMaxCustFilter = 0L;
  2758.     ofn.nFilterIndex = 1;
  2759.     ofn.lpstrFile = szFile;
  2760.     ofn.nMaxFile = sizeof(szFile);
  2761.     ofn.lpstrFileTitle = szFileTitle;
  2762.     ofn.nMaxFileTitle = sizeof(szFileTitle);
  2763.     ofn.lpstrInitialDir = NULL;
  2764.     ofn.lpstrTitle = "Load Metafile";
  2765.     ofn.Flags = 0L;
  2766.     ofn.nFileOffset = 0;
  2767.     ofn.nFileExtension = 0;
  2768.     ofn.lpstrDefExt = "EMF";
  2769.  
  2770.     if (!GetOpenFileName(&ofn))
  2771.         return 0L;
  2772.  
  2773.     if ((hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL,
  2774.             OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL)) == (HANDLE)-1) {
  2775.         wsprintf(text, "Fail in file open! Error %ld\n", GetLastError());
  2776.         MessageBox(ghwndMain, text, "Error", MB_OK);
  2777.         return 0L;
  2778.     }
  2779.  
  2780.     //
  2781.     // Create a map file of the opened file
  2782.     //
  2783.     if ((hMapFile = CreateFileMapping(hFile, NULL,
  2784.                              PAGE_READONLY, 0, 0, "MapF")) == NULL) {
  2785.         wsprintf(text, "Fail in creating map file! Error %ld\n", GetLastError());
  2786.         MessageBox(ghwndMain, text, "Error", MB_OK);
  2787.         bSuccess = FALSE;
  2788.         goto ErrorExit1;
  2789.     }
  2790.  
  2791.     //
  2792.     // Map a view of the whole file
  2793.     //
  2794.     if ((pMapFile = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0)) == NULL) {
  2795.         wsprintf(text, "Fail in mapping view of the Map File object! Error %ld\n", GetLastError());
  2796.         MessageBox(ghwndMain, text, "Error", MB_OK);
  2797.         bSuccess = FALSE;
  2798.         goto ErrorExit2;
  2799.     }
  2800.  
  2801.     //
  2802.     // First check that if it is an enhanced metafile
  2803.     //
  2804.     pemh = (LPENHMETAHEADER) pMapFile;
  2805.     if (pemh->dSignature == META32_SIGNATURE) {
  2806.         hemf = GetEnhMetaFile(szFile);
  2807.         goto HLM_EXIT;
  2808.     }
  2809.  
  2810.     //
  2811.     // If it has an ALDUS header skip it
  2812.     // Notice: APMSIZE is used because the HANDLE and RECT of the structure
  2813.     //         depends on the environment
  2814.     //
  2815.     if (*((LPDWORD)pemh) == ALDUS_ID) {
  2816.         //METAFILEPICT    mfp;
  2817.  
  2818.         MessageBox(ghwndMain, "This is an ALDUS metafile!", "Hey!", MB_OK);
  2819.         uiSize = *((LPDWORD) ((PBYTE)pMapFile + APMSIZE + 6));
  2820.         hDCDrawSurf = GetDC(ghwndDrawSurf);
  2821.  
  2822.         // Notice: mtSize is size of the file in word.
  2823.         // if LPMETAFILEPICT is NULL
  2824.         //    MM_ANISOTROPIC mode and default device size will be used.
  2825.         hemf = SetWinMetaFileBits(uiSize*2L, (PBYTE)pMapFile + APMSIZE, hDCDrawSurf, NULL);
  2826. #if 0
  2827.         switch ( ((PAPMFILEHEADER) pMapFile)->inch ) {
  2828.             // !!! End up in an upside down image
  2829.             //
  2830.             case 1440:
  2831.                 mfp.mm = MM_TWIPS;
  2832.                 OutputDebugString("MM_TWIPS\n");
  2833.                 break;
  2834.             case 2540:
  2835.                 OutputDebugString("MM_HIMETRIC\n");
  2836.                 mfp.mm = MM_HIMETRIC;
  2837.                 break;
  2838.             case 254:
  2839.                 OutputDebugString("MM_LOMETRIC\n");
  2840.                 mfp.mm = MM_LOMETRIC;
  2841.                 break;
  2842.             case 1000:
  2843.                 OutputDebugString("MM_HIENGLISH\n");
  2844.                 mfp.mm = MM_HIENGLISH;
  2845.                 break;
  2846.             case 100:
  2847.                 OutputDebugString("MM_LOENGLISH\n");
  2848.                 mfp.mm = MM_LOENGLISH;
  2849.                 break;
  2850.             default:
  2851.                 // !!! In addition, text is too small
  2852.                 //
  2853.                 OutputDebugString("MM_ANISOTROPIC\n");
  2854.                 mfp.mm = MM_ANISOTROPIC;
  2855.                 mfp.xExt = (((PAPMFILEHEADER) pMapFile)->bbox.Right - ((PAPMFILEHEADER) pMapFile)->bbox.Left)
  2856.                            * ((PAPMFILEHEADER) pMapFile)->inch * 2560;
  2857.                 mfp.yExt = (((PAPMFILEHEADER) pMapFile)->bbox.Bottom - ((PAPMFILEHEADER) pMapFile)->bbox.Top)
  2858.                            * ((PAPMFILEHEADER) pMapFile)->inch * 2560;
  2859.                 break;
  2860.         }
  2861.         mfp.hMF = 0;
  2862.         hemf = SetWinMetaFileBits(uiSize*2L, (PBYTE)pMapFile + APMSIZE, hDCDrawSurf, &mfp);
  2863. #endif
  2864.  
  2865.         if (!hemf) {
  2866.             char text[256];
  2867.  
  2868.             wsprintf(text, "SetWinMetaFileBits failed, %x", GetLastError());
  2869.             MessageBox(ghwndMain, text, "Error!", MB_OK);
  2870.         }
  2871.  
  2872.         ghmf = SetMetaFileBitsEx(uiSize*2L, (PBYTE)pMapFile + APMSIZE);
  2873.         if (!ghmf) {
  2874.             char text[256];
  2875.  
  2876.             wsprintf(text, "SetMetaFileBitsEx failed, %x", GetLastError());
  2877.             MessageBox(ghwndMain, text, "Error!", MB_OK);
  2878.         }
  2879.  
  2880. // !!! Displaying the Windows format metafile
  2881. //if (!PlayMetaFile(hDCDrawSurf, ghmf)) {
  2882. //    wsprintf(text, "PlayMetaFile failed, %x", GetLastError());
  2883. //    MessageBox(ghwndMain, text, "Error!", MB_OK);
  2884. //}
  2885.         ReleaseDC(ghwndDrawSurf, hDCDrawSurf);
  2886.         goto HLM_EXIT;
  2887.     }
  2888.  
  2889.  
  2890.     //
  2891.     // It is a Windows 3x format metafile (hopefully)
  2892.     //
  2893.     if (!(hmf = GetMetaFile((LPCSTR)szFile))) {
  2894.         char text[256];
  2895.  
  2896.         wsprintf(text, "GetMetaFile failed, %x", GetLastError());
  2897.         MessageBox(ghwndMain, text, "Error!", MB_OK);
  2898.         bSuccess = FALSE;
  2899.         goto ErrorExit3;
  2900.     }
  2901.  
  2902.     if (!(uiSize = GetMetaFileBitsEx(hmf, 0, NULL))) {
  2903.         MessageBox(ghwndMain, "Fail in 1st GetMetaFileBitsEx!", "Error", MB_OK);
  2904.         return NULL;
  2905.     }
  2906.  
  2907.     if ((pvData = (LPVOID) LocalAlloc(LMEM_FIXED, uiSize)) == NULL) {
  2908.         MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK);
  2909.         bSuccess = FALSE;
  2910.         goto ErrorExit3;
  2911.     }
  2912.  
  2913.     if (!(uiSize = GetMetaFileBitsEx(hmf, uiSize, pvData))) {
  2914.         MessageBox(ghwndMain, "Fail in 2nd GetMetaFileBitsEx!", "Error", MB_OK);
  2915.         bSuccess = FALSE;
  2916.         goto ErrorExit3;
  2917.     }
  2918.  
  2919.     DeleteMetaFile(hmf);
  2920.  
  2921.     hDCDrawSurf = GetDC(ghwndDrawSurf);
  2922.     hemf = SetWinMetaFileBits(uiSize, (LPBYTE)pvData, hDCDrawSurf, NULL);
  2923.     ghmf = SetMetaFileBitsEx(uiSize, (LPBYTE) pvData);
  2924.  
  2925.     LocalFree(pvData);
  2926.  
  2927.     ReleaseDC(ghwndDrawSurf ,hDCDrawSurf);
  2928.  
  2929. HLM_EXIT:
  2930. ErrorExit3:
  2931.     UnmapViewOfFile(pMapFile);
  2932.  
  2933. ErrorExit2:
  2934.     CloseHandle(hMapFile);
  2935. ErrorExit1:
  2936.     CloseHandle(hFile);
  2937.  
  2938.     if (bSuccess)
  2939.         return hemf;
  2940.     else
  2941.         return 0L;
  2942. }
  2943.  
  2944. /******************************Public*Routine******************************\
  2945. *
  2946. * hDCRecordMetafileAs
  2947. *
  2948. * Effects:   Brings up the SaveAs common dialog
  2949. *            Creates the enhanced metafile with the filename spec'd by user
  2950. *            Modifies the second arg to reflect the new default filename
  2951. *            less extension
  2952. *            returns the created metafile DC if successful, otherwise, 0
  2953. *
  2954. * Warnings:
  2955. *
  2956. * History:
  2957. *  08-May-1992 -by- Petrus Wong
  2958. * Wrote it.
  2959. \**************************************************************************/
  2960.  
  2961. HDC hDCRecordMetafileAs(HWND hwnd, LPSTR szFilename) {
  2962.     OPENFILENAME ofn;
  2963.     char szFile[256], szFileTitle[256];
  2964.     static char *szFilter;
  2965.     char *szTmp, szTmp2[256];
  2966.     HDC  hDCMeta;
  2967.  
  2968.     int iWidthMM, iHeightMM, iWidthPels, iHeightPels, iMMPerPelX, iMMPerPelY;
  2969.     RECT rc;
  2970.     HDC hDC;
  2971.  
  2972.  
  2973.     szFilter = "EnhMeta files (*.emf)\0\0";
  2974.     strcpy(szFile, "*.emf\0");
  2975.     ofn.lStructSize = sizeof(OPENFILENAME);
  2976.     ofn.hwndOwner = hwnd;
  2977.     ofn.lpstrFilter = szFilter;
  2978.     ofn.lpstrCustomFilter = (LPSTR) NULL;
  2979.     ofn.nMaxCustFilter = 0L;
  2980.     ofn.nFilterIndex = 0L;
  2981.     ofn.lpstrFile = szFile;
  2982.     ofn.nMaxFile = sizeof(szFile);
  2983.     ofn.lpstrFileTitle = szFileTitle;
  2984.     ofn.nMaxFileTitle = sizeof(szFileTitle);
  2985.     ofn.lpstrInitialDir = NULL;
  2986.     ofn.lpstrTitle = "Save Metafile As";
  2987.     ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
  2988.     ofn.nFileOffset = 0;
  2989.     ofn.nFileExtension = 0;
  2990.     ofn.lpstrDefExt = (LPSTR)NULL;
  2991.  
  2992.     if (!GetSaveFileName(&ofn)) {
  2993.         return 0L;
  2994.     }
  2995.  
  2996.  
  2997.     hDC = GetDC(hwnd);
  2998.     iWidthMM = GetDeviceCaps(hDC, HORZSIZE);
  2999.     iHeightMM = GetDeviceCaps(hDC, VERTSIZE);
  3000.     iWidthPels = GetDeviceCaps(hDC, HORZRES);
  3001.     iHeightPels = GetDeviceCaps(hDC, VERTRES);
  3002.     ReleaseDC(hwnd, hDC);
  3003.     iMMPerPelX = (iWidthMM * 100)/iWidthPels;
  3004.     iMMPerPelY = (iHeightMM * 100)/iHeightPels;
  3005.     GetClientRect(ghwndDrawSurf, &rc);
  3006.     rc.left = rc.left * iMMPerPelX;
  3007.     rc.top = rc.top * iMMPerPelY;
  3008.     rc.right = rc.right * iMMPerPelX;
  3009.     rc.bottom = rc.bottom * iMMPerPelY;
  3010.  
  3011.  
  3012.     //hDCMeta = CreateEnhMetaFile((HDC)NULL, szFile, (LPRECT)NULL, (LPSTR)NULL);
  3013.     {
  3014.         CHAR    szDesc[256];
  3015.  
  3016.         wsprintf(szDesc, "SDK Enhanced Metafile Editor\\0%s\\0\\0", szFileTitle);
  3017.         hDCMeta = CreateEnhMetaFile((HDC)NULL, szFile, (LPRECT)&rc, (LPSTR)szDesc);
  3018.         if ((SetGraphicsMode(hDCMeta, GM_ADVANCED)) == 0) {
  3019.            MessageBox(ghwndMain, "Fail in setting Advanced Graphics Mode!", "Error", MB_OK);
  3020.         }
  3021.     }
  3022.  
  3023.     //
  3024.     // parses the new filename, removes the extension and copy it into
  3025.     // szFilename
  3026.     //
  3027.     strcpy(szFilename, "");
  3028.     szTmp = (char *)strtok(szFile, "\\");
  3029.     strcpy(szTmp2, szTmp);
  3030.     while (szTmp != NULL) {
  3031.         szTmp = (char *)strtok(NULL, "\\");
  3032.         if (szTmp != NULL) {
  3033.             strcat(szFilename, szTmp2);
  3034.             strcpy(szTmp2, szTmp);
  3035.             strcat(szFilename, "\\");
  3036.         }
  3037.     }
  3038.     szTmp = (char *)strtok(szTmp2, ".");
  3039.     strcat(szFilename, szTmp);
  3040.  
  3041.     return hDCMeta;
  3042. }
  3043.  
  3044.  
  3045. /******************************Public*Routine******************************\
  3046. *
  3047. * bPlayRecord
  3048. *
  3049. * Effects:  Play metafile
  3050. *           if PlayInfo.bPlayContinuous is TRUE
  3051. *               play metafile from 1st record up to the PlayInfo.iRecord th
  3052. *                   record
  3053. *           else only play the PlayInfo.iRecord th record and those preceding
  3054. *               records that are relevant like MoveTo, etc.
  3055. *           Terminates enumeration after playing up to the
  3056. *               PlayInfo.iRecord th record
  3057. *
  3058. * Warnings:
  3059. *
  3060. * History:
  3061. *  08-May-1992 -by- Petrus Wong
  3062. * Wrote it.
  3063. \**************************************************************************/
  3064.  
  3065. BOOL APIENTRY bPlayRecord(HDC hDC, LPHANDLETABLE lpHandleTable,
  3066.                                    LPENHMETARECORD lpEnhMetaRecord,
  3067.                                    UINT nHandles,
  3068.                                    LPVOID lpData) {
  3069.     BOOL bSuccess;
  3070.     static int  iCnt=0;
  3071.     int         i;
  3072.     char        ach[128];
  3073.     char        achTmp[128];
  3074.     LONG        lNumDword;
  3075.  
  3076.     bSuccess = TRUE;
  3077.  
  3078.     lNumDword = (lpEnhMetaRecord->nSize-8) / 4;
  3079.  
  3080.     iCnt++;
  3081.     if (((PLAYINFO *) lpData)->bPlayContinuous) {
  3082.         bSuccess = PlayEnhMetaFileRecord(hDC, lpHandleTable,
  3083.                                              lpEnhMetaRecord, nHandles);
  3084.         if (iCnt == ((PLAYINFO *) lpData)->iRecord) {
  3085.             wsprintf((LPSTR) ach, "%s", rgMetaName[lpEnhMetaRecord->iType]);
  3086.             for (i=0; i < lNumDword; i++) {
  3087.                 wsprintf((LPSTR) achTmp, "%ld ", lpEnhMetaRecord->dParm[i]);
  3088.                 if ((strlen(ach)+strlen(achTmp))/sizeof(char) >= 128)
  3089.                     break;
  3090.                 strcat(ach, achTmp);
  3091.             }
  3092.         SetWindowText(ghTextWnd, ach);
  3093.         }
  3094.     } else {
  3095.  
  3096.         switch (lpEnhMetaRecord->iType) {
  3097.             case MR_SETWINDOWEXTEX:
  3098.             case MR_SETWINDOWORGEX:
  3099.             case MR_SETVIEWPORTEXTEX:
  3100.             case MR_SETVIEWPORTORGEX:
  3101.             case MR_SETBRUSHORGEX:
  3102.             case MR_SETMAPMODE:
  3103.             case MR_SETBKMODE:
  3104.             case MR_SETPOLYFILLMODE:
  3105.             case MR_SETROP2:
  3106.             case MR_SETSTRETCHBLTMODE:
  3107.             case MR_SETTEXTALIGN:
  3108.             case MR_SETTEXTCOLOR:
  3109.             case MR_SETBKCOLOR:
  3110.             case MR_OFFSETCLIPRGN:
  3111.             case MR_MOVETOEX:
  3112.             case MR_SETMETARGN:
  3113.             case MR_EXCLUDECLIPRECT:
  3114.             case MR_INTERSECTCLIPRECT:
  3115.             case MR_SCALEVIEWPORTEXTEX:
  3116.             case MR_SCALEWINDOWEXTEX:
  3117.             case MR_SAVEDC:
  3118.             case MR_RESTOREDC:
  3119.             case MR_SETWORLDTRANSFORM:
  3120.             case MR_MODIFYWORLDTRANSFORM:
  3121.             case MR_SELECTOBJECT:
  3122.             case MR_CREATEPEN:
  3123.             case MR_CREATEBRUSHINDIRECT:
  3124.             case MR_DELETEOBJECT:
  3125.             case MR_SELECTPALETTE:
  3126.             case MR_CREATEPALETTE:
  3127.             case MR_SETPALETTEENTRIES:
  3128.             case MR_RESIZEPALETTE:
  3129.             case MR_REALIZEPALETTE:
  3130.             case MR_SETARCDIRECTION:
  3131.             case MR_SETMITERLIMIT:
  3132.             case MR_BEGINPATH:
  3133.             case MR_ENDPATH:
  3134.             case MR_CLOSEFIGURE:
  3135.             case MR_SELECTCLIPPATH:
  3136.             case MR_ABORTPATH:
  3137.             case MR_EXTCREATEFONTINDIRECTW:
  3138.             case MR_CREATEMONOBRUSH:
  3139.             case MR_CREATEDIBPATTERNBRUSHPT:
  3140.             case MR_EXTCREATEPEN:
  3141.                 goto PlayRec;
  3142.             default:
  3143.                 break;
  3144.         } //switch
  3145.  
  3146.         if (iCnt == ((PLAYINFO *) lpData)->iRecord) {
  3147. PlayRec:
  3148.             bSuccess = PlayEnhMetaFileRecord(hDC, lpHandleTable,
  3149.                                              lpEnhMetaRecord, nHandles);
  3150.             wsprintf((LPSTR) ach, "%s", rgMetaName[lpEnhMetaRecord->iType]);
  3151.             for (i=0; i < lNumDword; i++) {
  3152.                 wsprintf((LPSTR) achTmp, "%ld ", lpEnhMetaRecord->dParm[i]);
  3153.                 if ((strlen(ach)+strlen(achTmp))/sizeof(char) >= 128)
  3154.                     break;
  3155.                 strcat(ach, achTmp);
  3156.             }
  3157.             SetWindowText(ghTextWnd, ach);
  3158.         }
  3159.     }
  3160.  
  3161.     if (iCnt == ((PLAYINFO *) lpData)->iRecord) {
  3162.         iCnt = 0;
  3163.         return FALSE;
  3164.     }
  3165.     return bSuccess;
  3166. }
  3167.  
  3168. /******************************Public*Routine******************************\
  3169. *
  3170. * LoadBitmapFile
  3171. *
  3172. * Effects:  Loads the bitmap from file and return the bitmap
  3173. *
  3174. * Warnings: pszFileName contains the full path
  3175. *
  3176. * History:
  3177. *  18-Feb-1993 Petrus Wong           fix metaf bnp color problem
  3178. *  21-Oct-1992 Petrus Wong           fix data-misalignment
  3179. *  13-May-1992 Petrus Wong           return bitmap handle
  3180. *  09-Jan-1992 -by- Petrus Wong
  3181. * Wrote it.
  3182. \**************************************************************************/
  3183.  
  3184. HBITMAP hBmpLoadBitmapFile(HDC hDC, PSTR pszFileName)
  3185. {
  3186.     HANDLE              hFile, hMapFile;
  3187.     LPVOID              pMapFile, pMapFileTmp;
  3188.     LPBITMAPINFOHEADER  pbmh;
  3189.     LPBITMAPINFO        pbmi;
  3190.     PBYTE               pjTmp;
  3191.     ULONG               sizBMI;
  3192.     HBITMAP             hBitmap;
  3193.     INT                 iNumClr;
  3194.     BOOL                bCoreHdr;
  3195.     WORD                wBitCount;
  3196.     PFILEINFO           pFileInfo;
  3197.  
  3198.     hBitmap = NULL;
  3199.  
  3200.     if ((hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
  3201.             OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL)) == (HANDLE)-1) {
  3202.         SetWindowText(ghTextWnd, "Fail in file open");
  3203.         goto ErrExit1;
  3204.     }
  3205.  
  3206.     //
  3207.     // Create a map file of the opened file
  3208.     //
  3209.     if ((hMapFile = CreateFileMapping(hFile, NULL,
  3210.                              PAGE_READONLY, 0, 0, NULL)) == (HANDLE)-1) {
  3211.         SetWindowText(ghTextWnd, "Fail in creating map file");
  3212.         goto ErrExit2;
  3213.  
  3214.     }
  3215.  
  3216.     //
  3217.     // Map a view of the whole file
  3218.     //
  3219.     if ((pMapFile = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0)) == NULL) {
  3220.         SetWindowText(ghTextWnd, "Fail in mapping view of the Map File object");
  3221.         goto ErrExit3;
  3222.     }
  3223.  
  3224.     pMapFileTmp = pMapFile;
  3225.  
  3226.     //
  3227.     // First check that it is a bitmap file
  3228.     //
  3229.     if (*((PWORD)pMapFile) != 0x4d42) {              // 'BM'
  3230.         MessageBox(ghwndMain, "This is not a DIB bitmap file!", "Error", MB_OK);
  3231.         goto ErrExit3;
  3232.     }
  3233.  
  3234.     //
  3235.     // The file header doesn't end on DWORD boundary...
  3236.     //
  3237.     pbmh = (LPBITMAPINFOHEADER)((PBYTE)pMapFile + sizeof(BITMAPFILEHEADER));
  3238.  
  3239.     {
  3240.         BITMAPCOREHEADER bmch, *pbmch;
  3241.         BITMAPINFOHEADER bmih, *pbmih;
  3242.         PBYTE            pjTmp;
  3243.         ULONG            ulSiz;
  3244.  
  3245.         pbmch = &bmch;
  3246.         pbmih = &bmih;
  3247.  
  3248.         pjTmp = (PBYTE)pbmh;
  3249.         ulSiz = sizeof(BITMAPCOREHEADER);
  3250.         while (ulSiz--) {
  3251.             *(((PBYTE)pbmch)++) = *(((PBYTE)pjTmp)++);
  3252.         }
  3253.  
  3254.         pjTmp = (PBYTE)pbmh;
  3255.         ulSiz = sizeof(BITMAPINFOHEADER);
  3256.         while (ulSiz--) {
  3257.             *(((PBYTE)pbmih)++) = *(((PBYTE)pjTmp)++);
  3258.         }
  3259.  
  3260.         //
  3261.         // Use the size to determine if it is a BitmapCoreHeader or
  3262.         // BitmapInfoHeader
  3263.         //
  3264.         // Does PM supports 16 and 32 bpp? How?
  3265.         //
  3266.         if (bmch.bcSize == sizeof(BITMAPCOREHEADER))
  3267.         {
  3268.             wBitCount = bmch.bcBitCount;
  3269.             iNumClr = ((wBitCount == 24) ? 0 : (1 << wBitCount));
  3270.             sizBMI = sizeof(BITMAPCOREHEADER)+sizeof(RGBTRIPLE)*iNumClr;
  3271.             bCoreHdr = TRUE;
  3272.         }
  3273.         else            // BITMAPINFOHEADER
  3274.         {
  3275.             wBitCount = bmih.biBitCount;
  3276.             switch (wBitCount) {
  3277.                 case 16:
  3278.                 case 32:
  3279.                     sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3;
  3280.                     break;
  3281.                 case 24:
  3282.                     sizBMI = sizeof(BITMAPINFOHEADER);
  3283.                     break;
  3284.                 default:
  3285.                     iNumClr = (1 << wBitCount);
  3286.                     sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*iNumClr;
  3287.                     break;
  3288.             }
  3289.             bCoreHdr = FALSE;
  3290.         }
  3291.     }
  3292.  
  3293.     if ((pbmi = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED,sizBMI)) == NULL) {
  3294.         MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK);
  3295.         goto ErrExit3;
  3296.     }
  3297.  
  3298.     //
  3299.     // Make sure we pass in a DWORD aligned BitmapInfo to CreateDIBitmap
  3300.     // Otherwise, exception on the MIPS platform
  3301.     // CR!!!  Equivalent to memcpy
  3302.     //
  3303.     pjTmp = (PBYTE)pbmi;
  3304.  
  3305.     while(sizBMI--)
  3306.     {
  3307.         *(((PBYTE)pjTmp)++) = *(((PBYTE)pbmh)++);
  3308.     }
  3309.  
  3310.     pMapFile = (PBYTE)pMapFile + ((BITMAPFILEHEADER *)pMapFile)->bfOffBits;
  3311.  
  3312. // !!! Use CreateBitmap for monochrome bitmap?
  3313.  
  3314.     //
  3315.     // Select the palette into the DC first before CreateDIBitmap()
  3316.     //
  3317.     bSelectDIBPal(hDC, pbmi, bCoreHdr);
  3318.  
  3319. // !!! We always pass a screen DC to this routine.
  3320. // !!! Maybe we should pass a metafile DC to this routine too.
  3321. // !!! The bitmap handle created for the screen DC won't give correct
  3322. // !!! color for the metafile DC.  So now, we always use the original
  3323. // !!! DIB info.
  3324.     if ((hBitmap = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)pbmi,
  3325.                         CBM_INIT, pMapFile, pbmi, DIB_RGB_COLORS)) == NULL) {
  3326.         SetWindowText(ghTextWnd, "Fail in creating DIB bitmap from file!");
  3327.         goto ErrExit4;
  3328.     }
  3329.  
  3330.     // reset gbUseDIB flag, now that we have opened up a new DIB
  3331.     gbUseDIB = FALSE;
  3332.  
  3333. // !!! Always use the DIB info o.w. metafile DC don't get the right color.
  3334. #if 0
  3335.     if (GetDeviceCaps(hDC, BITSPIXEL) < wBitCount) {
  3336. #endif
  3337.         gbUseDIB = TRUE;
  3338.         bFreeDibFile(&gDib);
  3339.         pFileInfo = &(gDib.rgFileInfo[0]);
  3340.         pFileInfo->hFile        = hFile;
  3341.         pFileInfo->hMapFile     = hMapFile;
  3342.         pFileInfo->lpvMapView   = pMapFileTmp;
  3343.  
  3344.         gDib.rgpjFrame[0]       = pMapFile;
  3345.         gDib.rgpbmi[0]          = pbmi;
  3346.         gDib.rgbCoreHdr[0]      = bCoreHdr;
  3347.         gDib.ulFrames           =
  3348.         gDib.ulFiles            = 1;
  3349.         return (hBitmap);
  3350. #if 0
  3351.     }
  3352. #endif
  3353.  
  3354. ErrExit4:
  3355.     LocalFree(pbmi);
  3356. ErrExit3:
  3357.     CloseHandle(hMapFile);
  3358. ErrExit2:
  3359.     CloseHandle(hFile);
  3360. ErrExit1:
  3361.  
  3362.     return (hBitmap);
  3363.  
  3364. }
  3365.  
  3366.  
  3367. /******************************Public*Routine******************************\
  3368. *
  3369. * bFreeDibFile
  3370. *
  3371. * Effects:
  3372. *
  3373. * Warnings:
  3374. *
  3375. * History:
  3376. *  09-Feb-1993 -by- Petrus Wong
  3377. * Wrote it.
  3378. \**************************************************************************/
  3379.  
  3380. BOOL bFreeDibFile(PDIBDATA pDibData)
  3381. {
  3382.     ULONG               ulFiles;
  3383.     ULONG               ulFrames;
  3384.     ULONG               i;
  3385.     PFILEINFO           pFileInfo;
  3386.  
  3387.     ulFiles = pDibData->ulFiles;
  3388.     ulFrames = pDibData->ulFrames;
  3389.  
  3390.     for (i = 0; i < ulFrames; i++) {
  3391.         LocalFree(pDibData->rgpjFrame[i]);
  3392.         LocalFree(pDibData->rgpbmi[i]);
  3393.     }
  3394.  
  3395.     for (i = 0; i < ulFiles; i++) {
  3396.         pFileInfo = &(pDibData->rgFileInfo[i]);
  3397.         CloseHandle(pFileInfo->hFile);
  3398.         CloseHandle(pFileInfo->hMapFile);
  3399.         UnmapViewOfFile(pFileInfo->lpvMapView);
  3400.     }
  3401.  
  3402.     pDibData->ulFiles = 0;
  3403.     pDibData->ulFrames = 0;
  3404.     return TRUE;
  3405. }
  3406.  
  3407.  
  3408.  
  3409.  
  3410. /******************************Public*Routine******************************\
  3411. *
  3412. * bGetBMP
  3413. *
  3414. * Effects: call common dialog and pass the filename to hBmpLoadBitmapFile
  3415. *          return TRUE if successful, FALSE otherwise
  3416. *
  3417. * Warnings:
  3418. *
  3419. * History:
  3420. *  13-May-1992 -by- Petrus Wong
  3421. * Wrote it.
  3422. \**************************************************************************/
  3423.  
  3424. BOOL bGetBMP(HWND hwnd, BOOL bMask) {
  3425.     OPENFILENAME    ofn;
  3426.     char            szFile[256], szFileTitle[256];
  3427.     static char     *szFilter;
  3428.     BOOL            bSuccess;
  3429.     HDC             hDC;
  3430.  
  3431.     bSuccess = FALSE;
  3432.  
  3433.     szFilter =
  3434.       "DIB files (*.bmp)\0*.bmp\0RLE files (*.rle)\0*.rle\0\0";
  3435.  
  3436.     strcpy(szFile, "*.bmp\0");
  3437.     ofn.lStructSize = sizeof(OPENFILENAME);
  3438.     ofn.hwndOwner = hwnd;
  3439.     ofn.lpstrFilter = szFilter;
  3440.     ofn.lpstrCustomFilter = (LPSTR) NULL;
  3441.     ofn.nMaxCustFilter = 0L;
  3442.     ofn.nFilterIndex = 1;
  3443.     ofn.lpstrFile = szFile;
  3444.     ofn.nMaxFile = sizeof(szFile);
  3445.     ofn.lpstrFileTitle = szFileTitle;
  3446.     ofn.nMaxFileTitle = sizeof(szFileTitle);
  3447.     ofn.lpstrInitialDir = NULL;
  3448.     ofn.lpstrTitle = (bMask ? "Load Mask" : "Load Bitmap");
  3449.     ofn.Flags = 0L;
  3450.     ofn.nFileOffset = 0;
  3451.     ofn.nFileExtension = 0;
  3452.     ofn.lpstrDefExt = "BMP";
  3453.  
  3454.     if (!GetOpenFileName(&ofn))
  3455.         return 0L;
  3456.  
  3457.     hDC = GetDC(ghwndDrawSurf);
  3458.     if (bMask) {
  3459.         ghBmpMask = hBmpLoadBitmapFile(hDC, szFile);
  3460.         if (ghBmpMask != NULL)
  3461.             bSuccess = TRUE;
  3462.     } else {
  3463.         ghBmp = hBmpLoadBitmapFile(hDC, szFile);
  3464.         if (ghBmp != NULL)
  3465.             bSuccess = TRUE;
  3466.     }
  3467.     ReleaseDC(ghwndDrawSurf, hDC);
  3468.  
  3469.     return bSuccess;
  3470. }
  3471.  
  3472. /******************************Public*Routine******************************\
  3473. *
  3474. * bHitTest
  3475. *
  3476. * Effects:  Enumerates metafile records
  3477. *           Calling bDoHitTest to process each record found.
  3478. *               The mouse position is passed to the bDoHitTest
  3479. *
  3480. * Warnings:
  3481. *
  3482. * History:
  3483. *  20-May-1992 -by- Petrus Wong
  3484. * Wrote it.
  3485. \**************************************************************************/
  3486.  
  3487. BOOL bHitTest(HDC hDC, INT x, INT y) {
  3488.     BOOL          bSuccess;
  3489.     ENHMETAHEADER EnhMetaHdr;
  3490.     RECT          rcClientDS;
  3491.     HTDATA        htData;
  3492.     static        HCURSOR hCurHT, hCurWait;
  3493.  
  3494.     bSuccess = TRUE;
  3495.  
  3496.     if (ghMetaf == 0)
  3497.         return 0L;
  3498.  
  3499.     hCurHT = LoadCursor(NULL, IDC_CROSS);
  3500.     hCurWait = LoadCursor(NULL, IDC_WAIT);
  3501.  
  3502.     GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr);
  3503.  
  3504.     htData.point.x = x;
  3505.     htData.point.y = y;
  3506.     htData.iRecord = EnhMetaHdr.nRecords;
  3507.  
  3508.     SetCursor(hCurWait);
  3509.     if (gbFit2Wnd) {
  3510.         GetClientRect(ghwndDrawSurf, &rcClientDS);
  3511.         EnumEnhMetaFile(hDC, ghMetaf, (ENHMFENUMPROC)bDoHitTest, (LPVOID) &htData, (LPRECT)&rcClientDS);
  3512.     } else {
  3513.         RECT rc;
  3514.  
  3515.         rc.top = rc.left = 0;
  3516.         rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left;
  3517.         rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top;
  3518.         EnumEnhMetaFile(hDC, ghMetaf, (ENHMFENUMPROC)bDoHitTest, (LPVOID) &htData, (LPRECT)&rc);
  3519.     }
  3520.     SetCursor(hCurHT);
  3521.  
  3522.     return bSuccess;
  3523. }
  3524.  
  3525. /******************************Public*Routine******************************\
  3526. *
  3527. * bDoHitTest
  3528. *
  3529. * Effects:      Play all records related to transformation
  3530. *               Remember new mouse position if the record is a MoveTo
  3531. *               Convert rectangle, ellipse, lineto and bezier to path
  3532. *               Widen the path and convert it to region.
  3533. *               Test if the mouse position is inside the region.
  3534. *
  3535. * Warnings:     Only handle rectangle, ellipse, line and polybezier
  3536. *
  3537. * History:
  3538. *  20-May-1992 -by- Petrus Wong
  3539. * Wrote it.
  3540. \**************************************************************************/
  3541.  
  3542. BOOL APIENTRY bDoHitTest(HDC hDC, LPHANDLETABLE lpHandleTable,
  3543.                                   LPENHMETARECORD lpEnhMetaRecord,
  3544.                                   UINT nHandles,
  3545.                                   LPVOID lpData) {
  3546.     BOOL            bSuccess;
  3547.     char            ach[128];
  3548.     char            achTmp[128];
  3549.     POINT           PtOrg;
  3550.     LONG            lNumDword;
  3551.     XFORM           xfSave;
  3552.     SIZE            SizeWndEx, SizeViewEx;
  3553.     POINT           ptWndOrgin, ptViewOrgin;
  3554.     int             i, iMode;
  3555.     HRGN            hRgn;
  3556.     PPOINT          pPt, pPtTmp;
  3557.     static HGDIOBJ  hObjOld=NULL;
  3558.     static LONG     lCurX=0;
  3559.     static LONG     lCurY=0;
  3560.     static BOOL     bXform=FALSE;
  3561.     static int      iCnt=0;
  3562.  
  3563.     iCnt++;
  3564.  
  3565.     //
  3566.     // select a wide pen for widen path later on
  3567.     //
  3568.     hObjOld = SelectObject(hDC, ghpnWide);
  3569.  
  3570.     //
  3571.     // save the mouse hit position, this was passed in as a POINT structure
  3572.     //
  3573.     PtOrg.x = (((HTDATA *)lpData)->point).x;
  3574.     PtOrg.y = (((HTDATA *)lpData)->point).y;
  3575.  
  3576.     //
  3577.     // save the number of parameters for the GDI fcn concerned in DWORD.
  3578.     // This is the total size of metafile record in question less the
  3579.     // size of the GDI function
  3580.     //
  3581.     lNumDword = (lpEnhMetaRecord->nSize-8) / 4;
  3582.  
  3583.     switch (lpEnhMetaRecord->iType) {
  3584.     case MR_SETWINDOWEXTEX:
  3585.     case MR_SETWINDOWORGEX:
  3586.     case MR_SETVIEWPORTEXTEX:
  3587.     case MR_SETVIEWPORTORGEX:
  3588.     case MR_SETMAPMODE:
  3589.     case MR_SCALEVIEWPORTEXTEX:
  3590.     case MR_SCALEWINDOWEXTEX:
  3591.     case MR_SETMETARGN:
  3592.     case MR_SAVEDC:
  3593.     case MR_RESTOREDC:
  3594.     case MR_SETWORLDTRANSFORM:
  3595.     case MR_MODIFYWORLDTRANSFORM: {
  3596.         //
  3597.         // play all records related to transformation & font
  3598.         //
  3599.         PlayEnhMetaFileRecord(hDC, lpHandleTable,
  3600.                                    lpEnhMetaRecord, nHandles);
  3601.         bXform = TRUE;
  3602.         return TRUE;
  3603.     }
  3604.     //
  3605.     // convert the following GDI calls to path for hit testing
  3606.     //
  3607.     case MR_RECTANGLE: {
  3608.         BeginPath(hDC);
  3609.         Rectangle(hDC, lpEnhMetaRecord->dParm[0], lpEnhMetaRecord->dParm[1],
  3610.                        lpEnhMetaRecord->dParm[2], lpEnhMetaRecord->dParm[3]);
  3611.         EndPath(hDC);
  3612.         break;
  3613.     }
  3614.     case MR_ELLIPSE: {
  3615.         BeginPath(hDC);
  3616.         Ellipse(hDC, lpEnhMetaRecord->dParm[0], lpEnhMetaRecord->dParm[1],
  3617.                      lpEnhMetaRecord->dParm[2], lpEnhMetaRecord->dParm[3]);
  3618.         EndPath(hDC);
  3619.         break;
  3620.     }
  3621.     case MR_MOVETOEX: {
  3622.         //
  3623.         // Remember our current position
  3624.         //
  3625.         lCurX = lpEnhMetaRecord->dParm[0];
  3626.         lCurY = lpEnhMetaRecord->dParm[1];
  3627.         return TRUE;
  3628.     }
  3629.     case MR_LINETO: {
  3630.         BeginPath(hDC);
  3631.         MoveToEx(hDC, lCurX, lCurY, NULL);
  3632.         LineTo(hDC, lpEnhMetaRecord->dParm[0], lpEnhMetaRecord->dParm[1]);
  3633.         EndPath(hDC);
  3634.         break;
  3635.     }
  3636.     case MR_POLYBEZIER16: {
  3637.         int         i;
  3638.         LONG        lSize;
  3639.         LONG        lPtCnt;
  3640.  
  3641.         lPtCnt = lpEnhMetaRecord->dParm[4];
  3642.         lSize = lPtCnt * sizeof(POINTL);
  3643.  
  3644.         if ((pPt = (PPOINT) LocalAlloc(LMEM_FIXED, lSize)) == NULL) {
  3645.             SetWindowText(ghTextWnd, "ERROR: Failed in Memory Allocation: NO HIT");
  3646.             return TRUE;
  3647.         }
  3648.  
  3649.         pPtTmp = pPt;
  3650.  
  3651.         for (i=0; i < (INT) lPtCnt; i++, pPtTmp++) {
  3652.             pPtTmp->x = (LONG)(LOWORD(lpEnhMetaRecord->dParm[i+5]));
  3653.             pPtTmp->y = (LONG)(HIWORD(lpEnhMetaRecord->dParm[i+5]));
  3654.         }
  3655.  
  3656.         BeginPath(hDC);
  3657.         PolyBezier(hDC, (LPPOINT)pPt, (DWORD) lPtCnt);
  3658.         EndPath(hDC);
  3659.         LocalFree(pPt);
  3660.         break;
  3661.     }
  3662.     default:
  3663.         wsprintf((LPSTR) ach, "NO HIT: I don't Hit-Test %s", rgMetaName[lpEnhMetaRecord->iType]);
  3664.         SetWindowText(ghTextWnd, ach);
  3665.         return TRUE;
  3666.     }   //switch
  3667.  
  3668.     if (bXform) {
  3669.         //
  3670.         // Set World transform to identity temporarily so that pen width
  3671.         // is not affected by world to page transformation
  3672.         //
  3673.         GetWorldTransform(hDC, &xfSave);
  3674.         ModifyWorldTransform(hDC, NULL, MWT_IDENTITY);
  3675.  
  3676.         //
  3677.         // Set Page transform to identity temporarily so that pen width
  3678.         // is not affected by page to device transformation
  3679.         //
  3680.         iMode = GetMapMode(hDC);
  3681.  
  3682.         if ((iMode == MM_ISOTROPIC) || (iMode == MM_ANISOTROPIC)) {
  3683.             GetWindowOrgEx(hDC, &ptWndOrgin);
  3684.             GetWindowExtEx(hDC, &SizeWndEx);
  3685.             GetViewportExtEx(hDC, &SizeViewEx);
  3686.             GetViewportOrgEx(hDC, &ptViewOrgin);
  3687.         }
  3688.  
  3689.         SetMapMode(hDC, MM_TEXT);
  3690.     }
  3691.  
  3692.     WidenPath(hDC);
  3693.  
  3694.     hRgn = PathToRegion(hDC);
  3695.  
  3696.     if (hRgn == 0) {
  3697.         SetWindowText(ghTextWnd, "ERROR: Null Region: NO HIT");
  3698.         DeleteObject(hRgn);
  3699.         return TRUE;
  3700.     }
  3701.     //DPtoLP(hDC, &PtOrg, 1);
  3702.     //SetPixel(hDC, PtOrg.x, PtOrg.y, RGB(0, 255, 0));
  3703.     //
  3704.     // test if mouse hit position is in region
  3705.     //
  3706.     bSuccess = PtInRegion(hRgn, PtOrg.x, PtOrg.y);
  3707.     //Temporily comment this out
  3708.     FillRgn(hDC, hRgn, ghbrRed);
  3709.     DeleteObject(hRgn);
  3710.     //
  3711.     // Set transform back.
  3712.     //
  3713.     if (bXform) {
  3714.         SetWorldTransform(hDC, &xfSave);
  3715.         SetMapMode(hDC, iMode);
  3716.  
  3717.         if ((iMode == MM_ISOTROPIC) || (iMode == MM_ANISOTROPIC)) {
  3718.             SetWindowOrgEx(hDC, ptWndOrgin.x, ptWndOrgin.y, NULL);
  3719.             SetWindowExtEx(hDC, SizeWndEx.cx, SizeWndEx.cy, NULL);
  3720.             SetViewportExtEx(hDC, SizeViewEx.cx, SizeViewEx.cy, NULL);
  3721.             SetViewportOrgEx(hDC, ptViewOrgin.x, ptViewOrgin.y, NULL);
  3722.         }
  3723.     }
  3724.  
  3725.     if (bSuccess) {
  3726.         Beep(440, 500);
  3727.         //
  3728.         // Reporting the metafile record number.  Then reset counter.
  3729.         //
  3730.         SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, iCnt, FALSE);
  3731.         iCnt=0;
  3732.         wsprintf((LPSTR) ach, "HIT %s", rgMetaName[lpEnhMetaRecord->iType]);
  3733.  
  3734.         for (i=0; i < lNumDword; i++) {
  3735.             wsprintf((LPSTR) achTmp, "%ld ", lpEnhMetaRecord->dParm[i]);
  3736.             if ((strlen(ach)+strlen(achTmp))/sizeof(char) >= 128)
  3737.                 break;
  3738.             strcat(ach, achTmp);
  3739.         }
  3740.  
  3741.         SetWindowText(ghTextWnd, ach);
  3742.         SelectObject(hDC, hObjOld);
  3743.         bXform = FALSE;
  3744.         return FALSE;
  3745.     }
  3746.     SetWindowText(ghTextWnd, "NO HIT");
  3747.     if (iCnt >= ((HTDATA *)lpData)->iRecord)
  3748.         iCnt = 0;
  3749.     return TRUE;
  3750.  
  3751.     UNREFERENCED_PARAMETER(lpHandleTable);
  3752.     UNREFERENCED_PARAMETER(nHandles);
  3753.  
  3754. }
  3755.  
  3756. /******************************Public*Routine******************************\
  3757. *
  3758. * bChooseNewFont
  3759. *
  3760. * Effects:
  3761. *
  3762. * Warnings:
  3763. *
  3764. * History:
  3765. *  20-May-1992 -by- Petrus Wong
  3766. * Wrote it.
  3767. \**************************************************************************/
  3768.  
  3769. BOOL bChooseNewFont(HWND hwnd, PLOGFONT plf, COLORREF *pClrRef) {
  3770.    HDC                  hDC;
  3771.    static CHOOSEFONT    chf;
  3772.    static BOOL          bInit=TRUE;
  3773.  
  3774.  
  3775.    if (bInit) {
  3776.         bInit = FALSE;
  3777.  
  3778.         hDC = GetDC( hwnd );
  3779.         chf.hDC = CreateCompatibleDC( hDC );
  3780.         ReleaseDC( hwnd, hDC );
  3781.  
  3782.         chf.lStructSize = sizeof(CHOOSEFONT);
  3783.         chf.hwndOwner = hwnd;
  3784.         chf.lpLogFont = plf;
  3785.         chf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT;
  3786.         chf.rgbColors = *pClrRef;
  3787.         chf.lCustData = 0;
  3788.         chf.hInstance = (HANDLE)NULL;
  3789.         chf.lpszStyle = (LPSTR)NULL;
  3790.         chf.nFontType = SCREEN_FONTTYPE;
  3791.         chf.nSizeMin = 0;
  3792.         chf.nSizeMax = 0;
  3793.         chf.lpfnHook = (LPCFHOOKPROC)NULL;
  3794.         chf.lpTemplateName = (LPSTR)NULL;
  3795.    }
  3796.  
  3797.    if (ChooseFont( &chf ) == FALSE ) {
  3798.         DeleteDC( hDC );
  3799.     return FALSE;
  3800.    }
  3801.  
  3802.    *pClrRef = chf.rgbColors;
  3803.  
  3804.    DeleteDC( hDC );
  3805.    return (TRUE);
  3806. }
  3807.  
  3808. /******************************Public*Routine******************************\
  3809. *
  3810. * bChooseNewColor
  3811. *
  3812. * Effects:  Returns TRUE if successful; lpdwRGB points the color selected.
  3813. *           Otherwise, FALSE.
  3814. *
  3815. * Warnings:
  3816. *
  3817. * History:
  3818. *  21-May-1992 -by- Petrus Wong
  3819. * Wrote it.
  3820. \**************************************************************************/
  3821.  
  3822. BOOL bChooseNewColor(HWND hwnd, LPDWORD lpdwRGB) {
  3823.     static DWORD argbCust[16] = {
  3824.         RGB(255, 255, 255), RGB(255, 255, 255),
  3825.         RGB(255, 255, 255), RGB(255, 255, 255),
  3826.         RGB(255, 255, 255), RGB(255, 255, 255),
  3827.         RGB(255, 255, 255), RGB(255, 255, 255),
  3828.         RGB(255, 255, 255), RGB(255, 255, 255),
  3829.         RGB(255, 255, 255), RGB(255, 255, 255),
  3830.         RGB(255, 255, 255), RGB(255, 255, 255),
  3831.         RGB(255, 255, 255), RGB(255, 255, 255)
  3832.     };
  3833.     CHOOSECOLOR cc;
  3834.     BOOL bResult;
  3835.  
  3836.     cc.lStructSize = sizeof(CHOOSECOLOR);
  3837.     cc.hwndOwner = hwnd;
  3838.     cc.hInstance = ghModule;
  3839.     cc.rgbResult = *lpdwRGB;
  3840.     cc.lpCustColors = argbCust;
  3841.     cc.Flags = CC_RGBINIT | CC_SHOWHELP;
  3842.     cc.lCustData = 0;
  3843.     cc.lpfnHook = NULL;
  3844.     cc.lpTemplateName = NULL;
  3845.  
  3846.     bResult = ChooseColor(&cc);
  3847.  
  3848.     if (bResult) {
  3849.         *lpdwRGB = cc.rgbResult;
  3850.         return TRUE;
  3851.     }
  3852.  
  3853.     return FALSE;
  3854. }
  3855.  
  3856.  
  3857. /******************************Public*Routine******************************\
  3858. *
  3859. * hBrCreateBrush
  3860. *
  3861. * Effects: Creates a brush with the specified RGB
  3862. *
  3863. * Warnings:
  3864. *
  3865. * History:
  3866. *  04-Mar-1992 -by- Petrus Wong
  3867. * Wrote it.
  3868. \**************************************************************************/
  3869.  
  3870. HBRUSH hBrCreateBrush(HDC hDC, DWORD dwRGB)
  3871. {
  3872.     HDC hdcMem;
  3873.     HBRUSH hbr;
  3874.     HBRUSH hbrOld;
  3875.     HBITMAP hbmPat;
  3876.     HBITMAP hbmOld;
  3877.  
  3878.     hbr = CreateSolidBrush(dwRGB);
  3879.     hdcMem = CreateCompatibleDC(hDC);
  3880.  
  3881.     //
  3882.     // Minimum size for a bitmap to be used in a fill pattern is 8x8
  3883.     //
  3884.     hbmPat = CreateCompatibleBitmap(hDC, 8, 8);
  3885.  
  3886.     hbmOld = SelectObject(hdcMem, hbmPat);
  3887.     hbrOld = SelectObject(hdcMem, hbr);
  3888.     PatBlt(hdcMem, 0, 0, 8, 8, PATCOPY);
  3889.  
  3890.     //
  3891.     // Deselect hbmPat and hbr
  3892.     //
  3893.     SelectObject(hdcMem, hbmOld);
  3894.     SelectObject(hdcMem, hbrOld);
  3895.  
  3896.     DeleteDC(hdcMem);
  3897.     DeleteObject(hbr);
  3898.  
  3899.     hbr = CreatePatternBrush(hbmPat);
  3900.  
  3901.     DeleteObject(hbmPat);
  3902.  
  3903.     return hbr;
  3904. }
  3905.  
  3906.  
  3907. /******************************Public*Routine******************************\
  3908. *
  3909. * bPrintMf  Brings up the print dialog for printer setup and then
  3910. *           starts printing the enhanced metafile.
  3911. *
  3912. *           pPD     Points to a PRTDATA structure that contains the
  3913. *                   the handle for the Enh. Metafile for printing.
  3914. *
  3915. * Effects:  Returns TRUE if sucessful.  Otherwise, it is FALSE.
  3916. *           GlobalFree pPD when exits.
  3917. *
  3918. * Warnings:
  3919. *
  3920. * History:
  3921. *  22-Oct-1992 -by- Petrus Wong
  3922. * Wrote it.
  3923. \**************************************************************************/
  3924.  
  3925. BOOL bPrintMf(PPRTDATA pPD) {
  3926.     DOCINFO         DocInfo;
  3927.     HDC             hDCPrinter;
  3928.     ENHMETAHEADER   EnhMetaHdr;
  3929.     HENHMETAFILE    hEnhMf;
  3930.     TCHAR           buf[128];
  3931.     PRINTDLG        pd;
  3932.     BOOL            bSuccess;
  3933.     int             iEntries;
  3934.     PLOGPALETTE     plogPal;
  3935.     PBYTE           pjTmp;
  3936.     HPALETTE        hPal;
  3937.  
  3938.  
  3939.     bSuccess = TRUE;
  3940.  
  3941.     if (pPD->hMetaf == 0) {
  3942.         SetWindowText(ghTextWnd, "NO Metafile to print");
  3943.         goto PMF_EXIT;
  3944.         bSuccess = FALSE;
  3945.     }
  3946.  
  3947.     hEnhMf = CopyEnhMetaFile(pPD->hMetaf, NULL);
  3948.     pd.lStructSize = sizeof(PRINTDLG);
  3949.     pd.hwndOwner   = ghwndMain;
  3950.     pd.Flags       = PD_RETURNDC;
  3951.     pd.hInstance   = ghModule;
  3952.  
  3953.     if (!PrintDlg(&pd)) {
  3954.         SetWindowText(ghTextWnd, "Cancel Printing");
  3955.         goto PMF_EXIT;
  3956.         bSuccess = FALSE;
  3957.     }
  3958.  
  3959.  
  3960.     if (pd.hDC == NULL) {
  3961.         SetWindowText(ghTextWnd, "Failed in creating printer DC");
  3962.         goto PMF_EXIT;
  3963.         bSuccess = FALSE;
  3964.     }
  3965.  
  3966.     hDCPrinter = pd.hDC;
  3967.     GetEnhMetaFileDescription(hEnhMf, 128, (LPTSTR)buf);
  3968.  
  3969.     DocInfo.cbSize      = sizeof(DOCINFO);
  3970.     DocInfo.lpszDocName = (LPTSTR) buf;
  3971.     DocInfo.lpszOutput  = NULL;
  3972.     StartDoc(hDCPrinter, &DocInfo);
  3973.     StartPage(hDCPrinter);
  3974.  
  3975.     SetWindowText(ghTextWnd, "Printing...");
  3976.  
  3977.     iEntries = GetEnhMetaFilePaletteEntries(hEnhMf, 0, NULL);
  3978.  
  3979.     if (iEntries) {
  3980.         if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  3981.                 sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) {
  3982.             MessageBox(ghwndMain, "Failed in Creating Palette!", "Error", MB_OK);
  3983.         }
  3984.  
  3985.         plogPal->palVersion = 0x300;
  3986.         plogPal->palNumEntries = (WORD) iEntries;
  3987.         pjTmp = (PBYTE) plogPal;
  3988.         pjTmp += 8;
  3989.  
  3990.         GetEnhMetaFilePaletteEntries(hEnhMf, iEntries, (PPALETTEENTRY)pjTmp);
  3991.         hPal = CreatePalette(plogPal);
  3992.         GlobalFree(plogPal);
  3993.  
  3994.         SelectPalette(hDCPrinter, hPal, FALSE);
  3995.         RealizePalette(hDCPrinter);
  3996.     }
  3997.  
  3998.     if (pPD->bFit2Wnd) {
  3999.         int     iWidth, iHeight;
  4000.         RECT    rc;
  4001.  
  4002.         iWidth = GetDeviceCaps(hDCPrinter, HORZRES);
  4003.         iHeight = GetDeviceCaps(hDCPrinter, VERTRES);
  4004.         rc.left = rc.top = 0;
  4005.         rc.right = iWidth;
  4006.         rc.bottom = iHeight;
  4007.         bSuccess = PlayEnhMetaFile(hDCPrinter, hEnhMf, (LPRECT) &rc);
  4008.         if (!bSuccess) {
  4009.             char    text[128];
  4010.  
  4011.             wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError());
  4012.             OutputDebugString(text);
  4013.         }
  4014.  
  4015.  
  4016.     } else {
  4017.         GetEnhMetaFileHeader(hEnhMf, sizeof(ENHMETAHEADER), &EnhMetaHdr);
  4018.         {
  4019.         RECT rc;
  4020.  
  4021.         rc.top = rc.left = 0;
  4022.         rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left;
  4023.         rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top;
  4024.         bSuccess = PlayEnhMetaFile(hDCPrinter, hEnhMf, (LPRECT) &rc);
  4025.         if (!bSuccess) {
  4026.             char    text[128];
  4027.  
  4028.             wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError());
  4029.             OutputDebugString(text);
  4030.         }
  4031.  
  4032.         }
  4033.     }
  4034.  
  4035.     EndPage(hDCPrinter);
  4036.     EndDoc(hDCPrinter);
  4037.     SetWindowText(ghTextWnd, "Printing Thread Done...");
  4038.  
  4039. PMF_EXIT:
  4040.  
  4041.     ExitThread(0);
  4042.     GlobalFree(pPD);
  4043.     return bSuccess;
  4044.  
  4045. }
  4046.  
  4047. /******************************Public*Routine******************************\
  4048. *
  4049. * bSelectDIBPal
  4050. *
  4051. * Effects: Creates a logical palette from the DIB and select it into the DC
  4052. *          and realize the palette. Saving the hPal in the ghPal
  4053. *
  4054. * Warnings: Based on Windows NT DIB support.  If PM support 16,24,32 bpp
  4055. *           we need to modify this routine.
  4056. *           Global alert! ghPal is changed here...
  4057. *
  4058. * History:
  4059. *  22-Jan-1993      Petrus Wong         PM support
  4060. *  31-Dec-1992 -by- Petrus Wong
  4061. * Wrote it.
  4062. \**************************************************************************/
  4063.  
  4064. BOOL bSelectDIBPal(HDC hDC, LPBITMAPINFO pbmi, BOOL bCoreHdr)
  4065. {
  4066.   LOGPALETTE    *plogPal;
  4067.   UINT          uiSizPal;
  4068.   INT           i, iNumClr;
  4069.   WORD          wBitCount;
  4070.  
  4071.   if (bCoreHdr) {
  4072.     wBitCount = ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcBitCount;
  4073.   } else {
  4074.     wBitCount = pbmi->bmiHeader.biBitCount;
  4075.   }
  4076.  
  4077.   switch (wBitCount) {
  4078.     case 16:
  4079.     case 24:
  4080.     case 32:                            // Does PM supports these?
  4081.         return FALSE;
  4082.     default:
  4083.         iNumClr = (1 << wBitCount);
  4084.         break;
  4085.   }
  4086.  
  4087.   uiSizPal = sizeof(WORD)*2 + sizeof(PALETTEENTRY)*iNumClr;
  4088.   if ((plogPal = (LOGPALETTE *) LocalAlloc(LMEM_FIXED,uiSizPal)) == NULL) {
  4089.       MessageBox(ghwndMain, "Fail in Allocating palette!", "Error", MB_OK);
  4090.       ghPal = NULL;
  4091.       return FALSE;
  4092.   }
  4093.  
  4094.   plogPal->palVersion = 0x300;
  4095.   plogPal->palNumEntries = (WORD) iNumClr;
  4096.  
  4097.   if (bCoreHdr) {
  4098.     for (i=0; i<iNumClr; i++) {
  4099.         plogPal->palPalEntry[i].peRed   = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtRed;
  4100.         plogPal->palPalEntry[i].peGreen = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtGreen;
  4101.         plogPal->palPalEntry[i].peBlue  = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtBlue;
  4102.         plogPal->palPalEntry[i].peFlags = PC_RESERVED;
  4103.     }
  4104.   } else {
  4105.     for (i=0; i<iNumClr; i++) {
  4106.         plogPal->palPalEntry[i].peRed   = pbmi->bmiColors[i].rgbRed;
  4107.         plogPal->palPalEntry[i].peGreen = pbmi->bmiColors[i].rgbGreen;
  4108.         plogPal->palPalEntry[i].peBlue  = pbmi->bmiColors[i].rgbBlue;
  4109.         plogPal->palPalEntry[i].peFlags = PC_RESERVED;
  4110.     }
  4111.   }
  4112.  
  4113.   DeleteObject(ghPal);
  4114.   ghPal = CreatePalette((LPLOGPALETTE)plogPal);
  4115.   if ((ghPal) == NULL) {
  4116.       MessageBox(ghwndMain, "Fail in creating palette!", "Error", MB_OK);
  4117.       return FALSE;
  4118.   }
  4119.  
  4120.   if ((GetDeviceCaps(hDC, RASTERCAPS)) & RC_PALETTE) {
  4121.     SelectPalette(hDC, ghPal, FALSE);
  4122.     RealizePalette(hDC);
  4123.   }
  4124.  
  4125.   GlobalFree(plogPal);
  4126.  
  4127.   return TRUE;
  4128. }
  4129.  
  4130.  
  4131. /******************************Public*Routine******************************\
  4132. *
  4133. * bPlgBlt
  4134. *
  4135. * Effects:  If Source DIB bpp > Destination DC's
  4136. *           use Halftone for PlgBlt.
  4137. *
  4138. * Warnings: Global Alert!
  4139. *           gbUseDIB is always TRUE now.
  4140. *
  4141. * History:
  4142. *  12-Mar-1993      Petrus Wong     fixed clr problem on playback (non-HT)
  4143. *  18-Feb-1993      Petrus Wong     fixed clr problem on playback (HT)
  4144. *  10-Feb-1993 -by- Petrus Wong
  4145. * Wrote it.
  4146. \**************************************************************************/
  4147.  
  4148. BOOL bPlgBlt(HDC hDC, LPPOINT rgPtsBMP)
  4149. {
  4150.     HDC                  hDCRef;
  4151.     HDC                  hDCSrn;                // hDC can be metaf DC
  4152.     HGDIOBJ              hObjOld, hBmpMem;
  4153.     BITMAP               bm;
  4154.     INT                  iBpp;
  4155.     WORD                 wBitCnt;
  4156.  
  4157.  
  4158.     hDCSrn = GetDC(ghwndDrawSurf);
  4159.     hDCRef = CreateCompatibleDC(hDC);
  4160.  
  4161.     if (gbUseDIB) {
  4162.         int         cx, cy, dx, dy;
  4163.         PBITMAPINFO pbmi;
  4164.  
  4165.         pbmi = (gDib.rgpbmi[0]);
  4166.         dx = rgPtsBMP[0].x - rgPtsBMP[1].x;
  4167.         dy = rgPtsBMP[0].y - rgPtsBMP[1].y;
  4168.         cx = (INT) sqrt( dx * dx + dy * dy );
  4169.  
  4170.         dx = rgPtsBMP[0].x - rgPtsBMP[2].x;
  4171.         dy = rgPtsBMP[0].y - rgPtsBMP[2].y;
  4172.         cy = (INT) sqrt( dx * dx + dy * dy );
  4173.  
  4174.         iBpp = GetDeviceCaps(hDC, BITSPIXEL);
  4175.  
  4176.         if (gDib.rgbCoreHdr[0]) {
  4177.             wBitCnt = ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcBitCount;
  4178.         } else {
  4179.             wBitCnt = pbmi->bmiHeader.biBitCount;
  4180.         }
  4181.  
  4182.         if (iBpp < wBitCnt) {   // Do Halftone
  4183.             SetStretchBltMode(hDCRef, HALFTONE);
  4184.             if (ghHT) {
  4185.                 SelectPalette(hDCRef, ghHT, FALSE);
  4186.                 SelectPalette(hDC, ghHT, FALSE);
  4187.                 SelectPalette(hDCSrn, ghHT, FALSE); // hDC can be metaf DC
  4188.                 RealizePalette(hDCSrn);             // always realize the srn DC
  4189.  
  4190.                 // Don't have to realize the palette in hDCRef
  4191.                 // RealizePalette(hDCRef);
  4192.  
  4193.                 // has to be compatible with screen DC, cannot be hDCRef
  4194.                 // memory DC has no bitmap by default?
  4195.                 // hDC may be a metafile DC, so use hDCSrn
  4196.                 hBmpMem = CreateCompatibleBitmap(hDCSrn, cx, cy);
  4197.                 SelectObject(hDCRef, hBmpMem);
  4198.             } else {
  4199.                 MessageBox(ghwndMain, "Halftone palette is null!", "Error", MB_OK);
  4200.             }
  4201.         } else {
  4202.             SetStretchBltMode(hDCRef, COLORONCOLOR);
  4203.             if (ghPal) {
  4204.                 if (ghDCMetaf == hDC)
  4205.                     CopyPalette(ghPal);
  4206.                 SelectPalette(hDCRef, ghPal, FALSE);
  4207.                 SelectPalette(hDC, ghPal, FALSE);
  4208.                 SelectPalette(hDCSrn, ghPal, FALSE); // hDC can be metaf DC
  4209.                 RealizePalette(hDCSrn);             // always realize the srn DC
  4210.  
  4211.                 // Don't have to realize the palette in hDCRef
  4212.                 // RealizePalette(hDCRef);
  4213.  
  4214.                 // has to be compatible with screen DC, cannot be hDCRef
  4215.                 // memory DC has no bitmap by default?
  4216.                 // hDC may be a metafile DC, so use hDCSrn
  4217.                 hBmpMem = CreateCompatibleBitmap(hDCSrn, cx, cy);
  4218.                 SelectObject(hDCRef, hBmpMem);
  4219.             } else {
  4220.                 MessageBox(ghwndMain, "Palette is null!", "Error", MB_OK);
  4221.             }
  4222.         }
  4223.  
  4224.         if (gDib.rgbCoreHdr[0]) {
  4225.             StretchDIBits(hDCRef, 0,0, cx, cy,
  4226.                           0,0, ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcWidth, ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcHeight,
  4227.                           gDib.rgpjFrame[0], pbmi, DIB_RGB_COLORS, SRCCOPY);
  4228.         } else {
  4229.             StretchDIBits(hDCRef, 0,0, cx, cy,
  4230.                           0,0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight,
  4231.                           gDib.rgpjFrame[0], pbmi, DIB_RGB_COLORS, SRCCOPY);
  4232.         }
  4233.  
  4234.         PlgBlt(hDC, rgPtsBMP, hDCRef, 0, 0, cx, cy,
  4235.                ghBmpMask, 0, 0);
  4236.  
  4237.         DeleteObject(hBmpMem);
  4238.  
  4239.     } else {
  4240.         hObjOld = SelectObject(hDCRef, ghBmp);
  4241.  
  4242.         GetObject(ghBmpMask, sizeof(BITMAP), (LPSTR)&bm);
  4243.         if (bm.bmBitsPixel != 1) {
  4244.             SetWindowText(ghTextWnd, "ERROR: Mask has to be a Monochrome bitmap!");
  4245.             ghBmpMask = NULL;
  4246.         }
  4247.  
  4248.         GetObject(ghBmp, sizeof(BITMAP), (LPSTR)&bm);
  4249.  
  4250.         if (ghPal) {
  4251.             SelectPalette(hDC, ghPal, FALSE);
  4252.             RealizePalette(hDC);
  4253.             SetStretchBltMode(hDC, COLORONCOLOR);
  4254.         }
  4255.         PlgBlt(hDC, rgPtsBMP, hDCRef, 0, 0, bm.bmWidth, bm.bmHeight,
  4256.                ghBmpMask, 0, 0);
  4257.  
  4258.         SelectObject(hDCRef, hObjOld);
  4259.     }
  4260.  
  4261.     DeleteDC(hDCRef);
  4262.     ReleaseDC(ghwndDrawSurf, hDCSrn);
  4263.     return TRUE;
  4264.  
  4265. }
  4266.  
  4267.  
  4268.  
  4269. /******************************Public*Routine******************************\
  4270. *
  4271. * HPALETTE CopyPalette
  4272. *
  4273. * Effects:
  4274. *
  4275. * Warnings:
  4276. *
  4277. * History:
  4278. *  18-Sep-1992 -by- Petrus Wong
  4279. * Wrote it.
  4280. \**************************************************************************/
  4281.  
  4282. HPALETTE CopyPalette(HPALETTE hPalSrc)
  4283. {
  4284.     PLOGPALETTE     plogPal;
  4285.     PBYTE           pjTmp;
  4286.     int             iNumEntries=0;
  4287.     HPALETTE        hPal;
  4288.  
  4289.     if ((iNumEntries = GetPaletteEntries(hPalSrc, 0, iNumEntries, NULL)) == 0) {
  4290.         MessageBox(ghwndMain, "No entry in palette to copy!", "Error", MB_OK);
  4291.         return (HPALETTE) NULL;
  4292.     }
  4293.  
  4294.     if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
  4295.             sizeof(DWORD) + sizeof(PALETTEENTRY)*iNumEntries )) == NULL) {
  4296.         MessageBox(ghwndMain, "Failed in CopyPalette!", "Error", MB_OK);
  4297.         return (HPALETTE) NULL;
  4298.     }
  4299.  
  4300.     plogPal->palVersion = 0x300;
  4301.     plogPal->palNumEntries = (WORD) iNumEntries;
  4302.     pjTmp = (PBYTE) plogPal;
  4303.     pjTmp += 8;
  4304.     GetPaletteEntries(hPalSrc, 0, iNumEntries, (PPALETTEENTRY)pjTmp);
  4305.     hPal = CreatePalette(plogPal);
  4306.  
  4307.     GlobalFree(plogPal);
  4308.  
  4309.     return hPal;
  4310. }
  4311.  
  4312.  
  4313.  
  4314.  
  4315. /******************************Public*Routine******************************\
  4316. *
  4317. * iTT
  4318. *
  4319. * Effects: set the global variable gbTT if the family is true type
  4320. *
  4321. * Warnings:
  4322. *
  4323. * History:
  4324. *  29-Apr-1993 -by- Petrus Wong
  4325. * Wrote it.
  4326. \**************************************************************************/
  4327.  
  4328. int CALLBACK iTT(
  4329.     LPLOGFONT    lpLF,
  4330.     LPTEXTMETRIC lpTM,
  4331.     DWORD        dwFontType,
  4332.     LPARAM       lpData)
  4333. {
  4334.  
  4335.     if (lpTM->tmPitchAndFamily & TMPF_TRUETYPE) {
  4336.         //OutputDebugString("TRUETYPE\n");
  4337.         *((BOOL *)lpData) = TRUE;
  4338.     } else {
  4339.         //OutputDebugString("NON-TRUETYPE\n");
  4340.         *((BOOL *)lpData) = FALSE;
  4341.     }
  4342.  
  4343. #if 0
  4344.     //
  4345.     // that's equivalent
  4346.     //
  4347.     if (dwFontType & TRUETYPE_FONTTYPE) {
  4348.         //OutputDebugString("TRUETYPE\n");
  4349.         *((BOOL *)lpData) = TRUE;
  4350.     } else {
  4351.         //OutputDebugString("NON-TRUETYPE\n");
  4352.         *((BOOL *)lpData) = FALSE;
  4353.     }
  4354. #endif
  4355.     return 0;
  4356.  
  4357.     UNREFERENCED_PARAMETER (lpLF);
  4358.     //UNREFERENCED_PARAMETER (lpTM);
  4359.     UNREFERENCED_PARAMETER (dwFontType);
  4360.  
  4361. }
  4362.  
  4363.  
  4364.  
  4365. /******************************Public*Routine******************************\
  4366. *
  4367. * CMTMLTFMT *pLoadMltFmtFile(VOID)
  4368. *
  4369. * Effects:  Load either EPS or enh mf
  4370. *
  4371. * Warnings: CR! change this to load multiple def of picture
  4372. *
  4373. * History:
  4374. *  16-Aug-1993 -by- Petrus Wong
  4375. * Wrote it.
  4376. \**************************************************************************/
  4377.  
  4378. CMTMLTFMT *pLoadMltFmtFile(VOID)
  4379. {
  4380.     OPENFILENAME    ofn;
  4381.     char            szDirName[256];
  4382.     char            szFile[256], szFileTitle[256];
  4383.     static char     *szFilter;
  4384.     HANDLE          hFile, hMapFile;
  4385.     LPVOID          pMapFile;
  4386.     DWORD           dwFileSizeLow, dwFileSizeHigh;
  4387.     CMTMLTFMT       *pMfmt;
  4388.  
  4389.     pMfmt = (CMTMLTFMT*)NULL;
  4390.  
  4391.     szFilter =
  4392.       "EPS files (*.eps)\0*.eps\0Enhanced Metafiles (*.emf)\0*.emf\0\0";
  4393.  
  4394.     GetSystemDirectory((LPSTR) szDirName, 256);
  4395.     strcpy(szFile, "*.eps\0");
  4396.     ofn.lStructSize = sizeof(OPENFILENAME);
  4397.     ofn.hwndOwner = GetFocus();
  4398.     ofn.lpstrFilter = szFilter;
  4399.     ofn.lpstrCustomFilter = (LPSTR) NULL;
  4400.     ofn.nMaxCustFilter = 0L;
  4401.     ofn.nFilterIndex = 1;
  4402.     ofn.lpstrFile = szFile;
  4403.     ofn.nMaxFile = sizeof(szFile);
  4404.     ofn.lpstrFileTitle = szFileTitle;
  4405.     ofn.nMaxFileTitle = sizeof(szFileTitle);
  4406.     ofn.lpstrInitialDir = szDirName;
  4407.     ofn.lpstrTitle = (LPSTR) NULL;
  4408.     ofn.Flags = 0L;
  4409.     ofn.nFileOffset = 0;
  4410.     ofn.nFileExtension = 0;
  4411.     ofn.lpstrDefExt = "EPS";
  4412.  
  4413.     if (!GetOpenFileName(&ofn)) {
  4414.         goto EXIT;
  4415.     }
  4416.  
  4417.     if ((hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL,
  4418.             OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL)) == (HANDLE)-1) {
  4419.         goto EXIT;
  4420.     }
  4421.  
  4422.     dwFileSizeLow = GetFileSize(hFile, &dwFileSizeHigh);
  4423.     if ((dwFileSizeLow == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) {
  4424.         goto EXIT;
  4425.     }
  4426.  
  4427.     //
  4428.     // Create a map file of the opened file
  4429.     //
  4430.     if ((hMapFile = CreateFileMapping(hFile, NULL,
  4431.                              PAGE_READONLY, 0, 0, NULL)) == (HANDLE)-1) {
  4432.         goto EXIT2;
  4433.     }
  4434.  
  4435.     //
  4436.     // Map a view of the whole file
  4437.     //
  4438.     if ((pMapFile = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0)) == NULL) {
  4439.         goto EXIT3;
  4440.     }
  4441.  
  4442. //
  4443. // CR!! In future, change this to load different def of the picture...
  4444. //
  4445.   {
  4446.     ULONG       ulSize;
  4447.     PBYTE       pjTmp;
  4448.     RECTL       rectl;
  4449.  
  4450.     ulSize = dwFileSizeLow+sizeof(CMTMLTFMT);
  4451.     if ((pMfmt = (CMTMLTFMT *) LocalAlloc(LMEM_FIXED, ulSize)) == NULL) {
  4452.         MessageBox(GetFocus(), "Fail in Memory Allocation!", "Error", MB_OK);
  4453.         goto EXIT3;
  4454.     }
  4455.  
  4456.     pMfmt->ident = GDICOMMENT_IDENTIFIER;
  4457.     pMfmt->iComment = GDICOMMENT_MULTIFORMATS;
  4458.     pMfmt->nFormats = 1;
  4459.     pMfmt->aemrformat[0].cbData = dwFileSizeLow;
  4460.     pMfmt->aemrformat[0].offData = 11*sizeof(DWORD);
  4461.  
  4462.     // parse for %!PS-Adobe-3.0 EPSF keyword
  4463.     //           Enhanced Metafile signature
  4464.     // set EMRFORMAT.dSignature appropiately
  4465.  
  4466.     if (((ENHMETAHEADER *) pMapFile)->dSignature == ENHMETA_SIGNATURE) {
  4467.  
  4468.         pMfmt->aemrformat[0].dSignature = ENHMETA_SIGNATURE;
  4469.         pMfmt->aemrformat[0].nVersion = 0;                    // not for emf
  4470.         pMfmt->rclOutput.left   = ((ENHMETAHEADER *) pMapFile)->rclBounds.left;
  4471.         pMfmt->rclOutput.top    = ((ENHMETAHEADER *) pMapFile)->rclBounds.top;
  4472.         pMfmt->rclOutput.right  = ((ENHMETAHEADER *) pMapFile)->rclBounds.right;
  4473.         pMfmt->rclOutput.bottom = ((ENHMETAHEADER *) pMapFile)->rclBounds.bottom;
  4474.     }
  4475.     else    //assume it is Adobe EPS
  4476.     if (bGetEPSBounds(pMapFile, &rectl)) {
  4477.  
  4478.         char text[128];
  4479.  
  4480.  
  4481.         pMfmt->aemrformat[0].dSignature = 0x46535045;
  4482.         pMfmt->aemrformat[0].nVersion = 1;
  4483.         pMfmt->rclOutput.left   = rectl.left;
  4484.         pMfmt->rclOutput.top    = rectl.top;
  4485.         pMfmt->rclOutput.right  = rectl.right;
  4486.         pMfmt->rclOutput.bottom = rectl.bottom;
  4487.  
  4488.         wsprintf(text, "Bounds = %d %d %d %d",
  4489.                  rectl.left, rectl.top, rectl.right, rectl.bottom);
  4490.         MessageBox(GetFocus(), text, "Bounds", MB_OK);
  4491.  
  4492.     }
  4493.     else {
  4494.         // unknown file type
  4495.         Free(pMfmt);
  4496.         pMfmt = NULL;
  4497.         goto EXIT3;
  4498.     }
  4499.  
  4500.     pjTmp = (PBYTE)(((DWORD *)pMfmt->aemrformat)+4);
  4501.     while (dwFileSizeLow--) {
  4502.         *(((PBYTE)pjTmp)++) = *(((PBYTE)pMapFile)++);
  4503.     }
  4504.  
  4505.   }
  4506.  
  4507.  
  4508. EXIT3:
  4509.     CloseHandle(hMapFile);
  4510. EXIT2:
  4511.     CloseHandle(hFile);
  4512. EXIT:
  4513.  
  4514.     return pMfmt;
  4515. }
  4516.  
  4517.  
  4518. HLOCAL Free(CMTMLTFMT *pMfmt) {
  4519.     return LocalFree(pMfmt);
  4520. }
  4521.  
  4522. #define DBG 0
  4523.  
  4524. BOOL bIsAdobe(char *szStr)
  4525. {
  4526.     if (strcmp(szStr, "%!PS-Adobe-3.0") == 0)
  4527.         return TRUE;
  4528.     else
  4529.         return FALSE;
  4530. }
  4531.  
  4532. BOOL bIsEPS(char *szStr)
  4533. {
  4534.     if ((strcmp(szStr, "EPSF-3.0") == 0) ||
  4535.         (strcmp(szStr, "EPSF-2.0") == 0))
  4536.         return TRUE;
  4537.     else
  4538.         return FALSE;
  4539. }
  4540.  
  4541. BOOL bIsBndBox(char *szStr)
  4542. {
  4543.     if (strcmp(szStr, "%%BoundingBox:") == 0)
  4544.         return TRUE;
  4545.     else
  4546.         return FALSE;
  4547. }
  4548.  
  4549. BOOL bIsEOF(char *szStr)
  4550. {
  4551.     if (strcmp(szStr, "%%EOF") == 0)
  4552.         return TRUE;
  4553.     else
  4554.         return FALSE;
  4555. }
  4556.  
  4557.  
  4558. BOOL bGetEPSBounds(LPVOID lpData, RECTL *prctl)
  4559. {
  4560.     char szKeyWord[128], szValue[128];
  4561.     int  index;
  4562.  
  4563.  
  4564.     if (lpData == NULL) {
  4565. #if DBG
  4566.         MessageBox(GetFocus(), "Null Pointer!", "Error", MB_OK);
  4567. #endif
  4568.         return FALSE;
  4569.     }
  4570.  
  4571.     index = 0;
  4572.  
  4573.     if (!bGetWord(lpData, szKeyWord, &index))
  4574.         return FALSE;
  4575.  
  4576.     if (!bIsAdobe(szKeyWord)) {
  4577.         MessageBox(GetFocus(), "Not Adobe!", "Error", MB_OK);
  4578.         return FALSE;
  4579.     }
  4580.  
  4581.     if (!bGetWord(lpData, szValue, &index))
  4582.         return FALSE;
  4583.  
  4584.     if (!bIsEPS(szValue)) {
  4585.         MessageBox(GetFocus(), "Not EPS!", "Error", MB_OK);
  4586.         return FALSE;
  4587.     }
  4588.  
  4589.     if (!bGoNextLine(lpData, &index))
  4590.         return FALSE;
  4591.  
  4592.     while ((bGetWord(lpData, szKeyWord, &index)) &&
  4593.            (!bIsBndBox(szKeyWord))) {
  4594. #if DBG
  4595.         MessageBox(GetFocus(), "Skip to EOL", "Error", MB_OK);
  4596. #endif
  4597.         if (!bGoNextLine(lpData, &index)) {
  4598.             MessageBox(GetFocus(), "EOF unexpectedly!", "Error", MB_OK);
  4599.             return FALSE;
  4600.         }
  4601.     }
  4602.  
  4603.     if (bIsBndBox(szKeyWord)) {
  4604.         if (bGetWord(lpData, szValue, &index))
  4605.             prctl->left    = atol(szValue);
  4606.         else {
  4607.             MessageBox(GetFocus(), "Fail to get bnd: left!", "Error", MB_OK);
  4608.             return FALSE;
  4609.         }
  4610.  
  4611.         if (bGetWord(lpData, szValue, &index))
  4612.             prctl->top     = atol(szValue);
  4613.         else {
  4614.             MessageBox(GetFocus(), "Fail to get bnd: top!", "Error", MB_OK);
  4615.             return FALSE;
  4616.         }
  4617.  
  4618.         if (bGetWord(lpData, szValue, &index))
  4619.             prctl->right   = atol(szValue);
  4620.         else {
  4621.             MessageBox(GetFocus(), "Fail to get bnd: right!", "Error", MB_OK);
  4622.             return FALSE;
  4623.         }
  4624.  
  4625.         if (bGetWord(lpData, szValue, &index))
  4626.             prctl->bottom  = atol(szValue);
  4627.         else {
  4628.             MessageBox(GetFocus(), "Fail to get bnd: bottom", "Error", MB_OK);
  4629.             return FALSE;
  4630.         }
  4631.     }
  4632.  
  4633.     return TRUE;
  4634.  
  4635. }
  4636.  
  4637.  
  4638. BOOL bGetWord(LPVOID lpData, char *str, int* pi)
  4639. {
  4640.     char *pstr;
  4641.  
  4642.     pstr = str;
  4643.  
  4644.     while (((char *)lpData)[*pi] == ' ')
  4645.         (*pi)++;
  4646.  
  4647.     while ((((char *)lpData)[*pi] != ' ') &&
  4648.            (((char *)lpData)[*pi] != '\n') &&
  4649.            (((char *)lpData)[*pi] != '\r')) {
  4650.         *str++ = ((char *)lpData)[(*pi)++];
  4651.     }
  4652.     *str++ = '\0';
  4653.  
  4654. #if DBG
  4655.     {
  4656.     char text[128];
  4657.  
  4658.     wsprintf(text, "bGetWord gets %s", pstr);
  4659.     MessageBox(GetFocus(), text, "Info", MB_OK);
  4660.     }
  4661. #endif
  4662.  
  4663.     return TRUE;
  4664. }
  4665.  
  4666.  
  4667. BOOL bGoNextLine(LPVOID lpData, int* pi)
  4668. {
  4669.     char tmp[128];
  4670.     int  q;
  4671.  
  4672.     while ((((char *)lpData)[*pi] != '\n') &&
  4673.            (((char *)lpData)[*pi] != '\r'))
  4674.         (*pi)++;
  4675.  
  4676.     //
  4677.     // skip them
  4678.     //
  4679.     *pi += 2;
  4680.  
  4681.     q = *pi;
  4682.  
  4683.     if ((bGetWord(lpData, tmp, &q)) && (bIsEOF(tmp)) )
  4684.         return FALSE;
  4685.  
  4686.     return TRUE;
  4687. }
  4688.