Annotation of mstools/samples/mfedit/mfedit.c, revision 1.1

1.1     ! root        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) 1990 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: 
        !            39: //
        !            40: // Forward declarations.
        !            41: //
        !            42: BOOL InitializeApp   (void);
        !            43: LONG MainWndProc     (HWND, UINT, DWORD, LONG);
        !            44: LONG DrawSurfWndProc (HWND, UINT, DWORD, LONG);
        !            45: LONG MDIWndProc      (HWND, UINT, DWORD, LONG);
        !            46: LONG About          (HWND, UINT, DWORD, LONG);
        !            47: LONG TextWndProc     (HWND, UINT, DWORD, LONG);
        !            48: LONG CtrlPanelDlgProc(HWND, UINT, DWORD, LONG);
        !            49: BOOL bDrawStuff      (HDC, INT, INT, INT, INT, BOOL, BOOL, BOOL, LPSTR);
        !            50: HENHMETAFILE hemfLoadMetafile(HWND);
        !            51: HDC  hDCRecordMetafileAs(HWND, LPSTR);
        !            52: BOOL APIENTRY bPlayRecord(HDC, LPHANDLETABLE, LPENHMETARECORD, UINT, LPVOID);
        !            53: BOOL APIENTRY bDoHitTest(HDC, LPHANDLETABLE, LPENHMETARECORD, UINT, LPVOID);
        !            54: BOOL bHitTest(HDC, INT, INT);
        !            55: HBITMAP hBmpLoadBitmapFile(HDC, PSTR);
        !            56: BOOL bGetBMP(HWND, BOOL);
        !            57: BOOL bChooseNewFont(HWND, PLOGFONT, COLORREF * );
        !            58: BOOL bChooseNewColor(HWND, LPDWORD);
        !            59: HBRUSH hBrCreateBrush(HDC, DWORD);
        !            60: 
        !            61: /***************************************************************************\
        !            62: * WinMain
        !            63: *
        !            64: * History:
        !            65: * 11-Feb-1992   Petrus Wong
        !            66: \***************************************************************************/
        !            67: int WinMain(
        !            68:     HANDLE hInstance,
        !            69:     HANDLE hPrevInstance,
        !            70:     LPSTR lpCmdLine,
        !            71:     int nShowCmd)
        !            72: {
        !            73:     MSG    msg;
        !            74:     HANDLE hAccel;
        !            75: 
        !            76:     ghModule = GetModuleHandle(NULL);
        !            77:     if (!InitializeApp()) {
        !            78:        MessageBox(ghwndMain, "MfEdit: InitializeApp failure!", "Error", MB_OK);
        !            79:         return 0;
        !            80:     }
        !            81: 
        !            82:     if (!(hAccel = LoadAccelerators (ghModule, MAKEINTRESOURCE(ACCEL_ID))))
        !            83:        MessageBox(ghwndMain, "MfEdit: Load Accel failure!", "Error", MB_OK);
        !            84: 
        !            85: 
        !            86:     while (GetMessage(&msg, NULL, 0, 0)) {
        !            87:         if (!TranslateAccelerator( ghwndMain, hAccel, &msg) ) {
        !            88:             TranslateMessage(&msg);
        !            89:             DispatchMessage(&msg);
        !            90:         }
        !            91:     }
        !            92: 
        !            93:     return 1;
        !            94: 
        !            95:     UNREFERENCED_PARAMETER(lpCmdLine);
        !            96:     UNREFERENCED_PARAMETER(nShowCmd);
        !            97:     UNREFERENCED_PARAMETER(hInstance);
        !            98:     UNREFERENCED_PARAMETER(hPrevInstance);
        !            99: }
        !           100: 
        !           101: 
        !           102: /***************************************************************************\
        !           103: * InitializeApp
        !           104: *
        !           105: * History:
        !           106: * 11-Feb-1992   Petrus Wong
        !           107: *   Name changes.
        !           108: * 09-09-91      Petrus Wong    Created.
        !           109: \***************************************************************************/
        !           110: 
        !           111: BOOL InitializeApp(void)
        !           112: {
        !           113:     WNDCLASS wc;
        !           114:     int index;
        !           115: 
        !           116:     wc.style            = CS_DBLCLKS;
        !           117:     wc.lpfnWndProc      = (WNDPROC)MainWndProc;
        !           118:     wc.cbClsExtra       = 0;
        !           119:     wc.cbWndExtra      = sizeof(DWORD);
        !           120:     wc.hInstance        = ghModule;
        !           121:     wc.hIcon            = LoadIcon(ghModule, MAKEINTRESOURCE(APPICON));
        !           122:     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
        !           123:     wc.hbrBackground   = (HBRUSH)(COLOR_APPWORKSPACE + 1);
        !           124:     wc.lpszMenuName     = "MainMenu";
        !           125:     wc.lpszClassName   = "MetafDemoClass";
        !           126: 
        !           127:     if (!RegisterClass(&wc))
        !           128:        return FALSE;
        !           129: 
        !           130:     wc.style            = CS_OWNDC | CS_SAVEBITS;
        !           131:     wc.lpfnWndProc      = (WNDPROC)DrawSurfWndProc;
        !           132:     wc.hIcon            = NULL;
        !           133:     wc.hCursor          = NULL;
        !           134:     wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW + 1);
        !           135:     wc.lpszMenuName     = NULL;
        !           136:     wc.lpszClassName    = "DrawSurfClass";
        !           137: 
        !           138:     if (!RegisterClass(&wc))
        !           139:        return FALSE;
        !           140: 
        !           141:     wc.style           = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
        !           142:     wc.lpfnWndProc     = (WNDPROC)TextWndProc;
        !           143:     wc.hIcon           = NULL;
        !           144:     wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
        !           145:     wc.hbrBackground   = (HBRUSH)(COLOR_BTNFACE + 1);
        !           146:     wc.lpszMenuName    = NULL;
        !           147:     wc.lpszClassName   = "Text";
        !           148: 
        !           149:     if (!RegisterClass(&wc))
        !           150:             return FALSE;
        !           151: 
        !           152: 
        !           153: 
        !           154:     hMenu      = LoadMenu(ghModule, "MainMenu");
        !           155: 
        !           156:     for (index = 0; index < OD_BTN_CNT; index++) {
        !           157:         ghBmpDn[index] = (PVOID)LoadBitmap(ghModule, (LPCSTR)MAKEINTRESOURCE(BMID_BASED+index));
        !           158:         ghBmpUp[index] = (PVOID)LoadBitmap(ghModule, (LPCSTR)MAKEINTRESOURCE(BMID_BASEU+index));
        !           159:     }
        !           160:     for (index = 0; index < OD_TOOL_CNT; index++) {
        !           161:         ghToolBmpDn[index] = (PVOID)LoadBitmap(ghModule, (LPCSTR)MAKEINTRESOURCE(BMID_TOOLBASED+index));
        !           162:         ghToolBmpUp[index] = (PVOID)LoadBitmap(ghModule, (LPCSTR)MAKEINTRESOURCE(BMID_TOOLBASEU+index));
        !           163: 
        !           164:     }
        !           165: 
        !           166:     ghwndMain = CreateWindowEx(0L, "MetafDemoClass", "Enhanced Metafile Editor",
        !           167:            WS_OVERLAPPED   | WS_CAPTION     | WS_BORDER       |
        !           168:            WS_THICKFRAME   | WS_MAXIMIZEBOX | WS_MINIMIZEBOX  |
        !           169:            WS_CLIPCHILDREN | WS_VISIBLE     | WS_SYSMENU,
        !           170:             80, 70, 600, 300,
        !           171:            NULL, hMenu, ghModule, NULL);
        !           172: 
        !           173:     if (ghwndMain == NULL)
        !           174:        return FALSE;
        !           175: 
        !           176:     SetWindowLong(ghwndMain, GWL_USERDATA, 0L);
        !           177: 
        !           178:     SetFocus(ghwndMain);    /* set initial focus */
        !           179: 
        !           180:     return TRUE;
        !           181: }
        !           182: 
        !           183: 
        !           184: /***************************************************************************\
        !           185: * MainWndProc
        !           186: *
        !           187: * History:
        !           188: * 11-Feb-1992   Petrus Wong
        !           189: *   Name changes.  Added comments.
        !           190: * 09-09-91      Petrus Wong    Created.
        !           191: \***************************************************************************/
        !           192: 
        !           193: long MainWndProc(
        !           194:     HWND hwnd,
        !           195:     UINT message,
        !           196:     DWORD wParam,
        !           197:     LONG lParam)
        !           198: {
        !           199:     static int         iMetafCnt=0;
        !           200:     static char        szFilename[256] = "c:\\metaf";
        !           201:     static BOOL        bReset=FALSE;
        !           202: 
        !           203:     switch (message) {
        !           204: 
        !           205:       case WM_CREATE: {
        !           206: 
        !           207:        SetWindowLong(hwnd, 0, (LONG)NULL);
        !           208:         ghDCMem = CreateCompatibleDC(NULL);
        !           209: 
        !           210:         ghwndCtrlPanel = CreateDialog(ghModule, (LPCSTR)MAKEINTRESOURCE(DID_CTRLPANEL),
        !           211:                      hwnd, (DLGPROC) CtrlPanelDlgProc);
        !           212: 
        !           213:         ghwndDrawSurf = CreateWindow("DrawSurfClass", NULL,
        !           214:                                     WS_BORDER | WS_CHILD | WS_VISIBLE,
        !           215:                                     0, 0, 0, 0,
        !           216:                                     hwnd,
        !           217:                                     NULL,
        !           218:                                     ghModule,
        !           219:                                     NULL);
        !           220: 
        !           221:         ghTextWnd = CreateWindow("Text", NULL,
        !           222:                                 WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
        !           223:                                 0, 0, 0, 0,
        !           224:                                 hwnd,
        !           225:                                 NULL,               //(HMENU) 2,
        !           226:                                 ghModule,
        !           227:                                 NULL);
        !           228: 
        !           229:         ghbrRed = CreateSolidBrush(RGB(255, 0, 0));
        !           230:         ghbrAppBkgd = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));
        !           231:         ghpnWide = CreatePen(PS_SOLID, 5, RGB(0, 0, 0));
        !           232:         return 0L;
        !           233:       }
        !           234: 
        !           235:       case WM_SIZE: {
        !           236:           RECT        rc;
        !           237:           LONG        lcyCtrlPanel, lcyDrawSurf;
        !           238: 
        !           239:           GetWindowRect(ghwndCtrlPanel, &rc);
        !           240:           lcyCtrlPanel = rc.bottom-rc.top;
        !           241:           lcyDrawSurf = HIWORD(lParam) - lcyCtrlPanel - glcyStatus;
        !           242: 
        !           243:           //
        !           244:           // CR!! Alternatively, this window can be created with cy
        !           245:           //      equals to cy of the screen and saving this call
        !           246:           //      altogether.
        !           247:           //
        !           248:           MoveWindow(ghwndCtrlPanel,
        !           249:                      0, 0, LOWORD(lParam), lcyCtrlPanel, TRUE);
        !           250: 
        !           251:           //
        !           252:           // This ordering guarantees the text window paints correctly
        !           253:           //
        !           254:           MoveWindow(ghTextWnd,
        !           255:                      0, lcyCtrlPanel + lcyDrawSurf,
        !           256:                      LOWORD(lParam),                    // cx of hwnd
        !           257:                      glcyStatus, TRUE);
        !           258: 
        !           259:           MoveWindow(ghwndDrawSurf,
        !           260:                      0, lcyCtrlPanel,
        !           261:                      LOWORD(lParam),                    // cx of hwnd
        !           262:                      lcyDrawSurf, TRUE);
        !           263:           break;
        !           264:       }
        !           265: 
        !           266:       case WM_DESTROY: {
        !           267:         DeleteDC(ghDCMem);
        !           268:         DeleteEnhMetaFile(ghMetaf);
        !           269:         DestroyWindow(ghwndCtrlPanel);
        !           270:         DeleteObject(ghbrRed);
        !           271:         DeleteObject(ghbrCur);
        !           272:         DeleteObject(ghpnCur);
        !           273:         DeleteObject(ghbrAppBkgd);
        !           274:         DeleteObject(ghpnWide);
        !           275:        PostQuitMessage(0);
        !           276:        return 0L;
        !           277:       }
        !           278: 
        !           279:       case WM_COMMAND: {
        !           280:         static int     iPlus=0;
        !           281: 
        !           282:        switch (LOWORD(wParam)) {
        !           283:             case DID_ZERO:
        !           284:             case DID_ONE:
        !           285:             case DID_TWO:
        !           286:             case DID_THREE:
        !           287:             case DID_FOUR:
        !           288:             case DID_FIVE:
        !           289:             case DID_SIX:
        !           290:             case DID_SEVEN:
        !           291:             case DID_EIGHT:
        !           292:             case DID_NINE: {
        !           293:                 HDC           hDCDrawSurf;
        !           294:                 ENHMETAHEADER EnhMetaHdr;
        !           295:                 //RECT          rcClientDS;
        !           296:                 int           iRecord;
        !           297:                 PLAYINFO      PlayInfo;
        !           298: 
        !           299:                 if (ghMetaf == 0)
        !           300:                     return 0L;
        !           301: 
        !           302:                 GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr);
        !           303:                 iRecord = LOWORD(wParam) - DID_ZERO + iPlus;
        !           304:                 SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, iRecord, FALSE);
        !           305:                 PlayInfo.iRecord = iRecord;
        !           306:                 PlayInfo.bPlayContinuous = FALSE;
        !           307:                 iPlus = 0;
        !           308: 
        !           309:                 if ((EnhMetaHdr.nRecords > 1) && (iRecord > 0) &&
        !           310:                     (iRecord <= (INT) EnhMetaHdr.nRecords)) {
        !           311:                     //!!!GetClientRect(ghwndDrawSurf, &rcClientDS);
        !           312:                     hDCDrawSurf = GetDC(ghwndDrawSurf);
        !           313:                     //!!!EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, &rcClientDS);
        !           314:                     EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds);
        !           315:                     //
        !           316:                     // Enabling the user to record a metafile record selectively
        !           317:                     //
        !           318:                     if ((gbRecording) && (ghDCMetaf != NULL))
        !           319:                         EnumEnhMetaFile(ghDCMetaf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds);
        !           320:                     ReleaseDC(ghwndDrawSurf, hDCDrawSurf);
        !           321:                 }
        !           322:                 return 0L;
        !           323:             }
        !           324:             case DID_TEN_PLUS: {
        !           325:                 if (ghMetaf == 0)
        !           326:                     return 0L;
        !           327: 
        !           328:                 iPlus += 10;
        !           329:                 SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, iPlus, FALSE);
        !           330:                 return 0L;
        !           331:             }
        !           332:             case MM_PRINT:
        !           333:             case MM_PAGESETUP:
        !           334:             case MM_PRINTSETUP:
        !           335:             case MM_CUT:
        !           336:             case MM_COPY:
        !           337:             case MM_PASTE:
        !           338:             case MM_DEL:
        !           339:                 return 0L;
        !           340:             case MM_PEN: {
        !           341:                 HDC     hDC;
        !           342:                 DWORD   dwRGB;
        !           343: 
        !           344:                 if (bChooseNewColor(hwnd, &dwRGB)) {
        !           345:                     hDC = GetDC(ghwndDrawSurf);
        !           346:                     if (ghpnCur != NULL)
        !           347:                         DeleteObject(ghpnCur);
        !           348:                     ghpnCur = CreatePen(PS_SOLID, 1, dwRGB);
        !           349:                     SelectObject(hDC, ghpnCur);
        !           350:                     if (ghDCMetaf != NULL)
        !           351:                         SelectObject(ghDCMetaf, ghpnCur);
        !           352:                     ReleaseDC(ghwndDrawSurf, hDC);
        !           353:                 }
        !           354:                 return 0L;
        !           355:             }
        !           356:             case MM_BRUSH: {
        !           357:                 HDC     hDC;
        !           358:                 static DWORD   dwRGB=RGB(255, 255, 255);
        !           359: 
        !           360:                 if (bChooseNewColor(hwnd, &dwRGB)) {
        !           361:                     hDC = GetDC(ghwndDrawSurf);
        !           362:                     if (ghbrCur != NULL)
        !           363:                         DeleteObject(ghbrCur);
        !           364:                     ghbrCur = hBrCreateBrush(hDC, dwRGB);
        !           365:                     SelectObject(hDC, ghbrCur);
        !           366:                     if (ghDCMetaf != NULL)
        !           367:                         SelectObject(ghDCMetaf, ghbrCur);
        !           368:                     ReleaseDC(ghwndDrawSurf, hDC);
        !           369:                 }
        !           370:                 return 0L;
        !           371:             }
        !           372:             case MM_FONT: {
        !           373:                 if (bChooseNewFont(ghwndMain, &glf, &gCrText)) {
        !           374:                     ghCurFont = CreateFontIndirect(&glf);
        !           375:                     if (ghDCMetaf != NULL)
        !           376:                         SelectObject(ghDCMetaf, ghCurFont);
        !           377:                 }
        !           378:                 return 0L;
        !           379:             }
        !           380: 
        !           381:             case MM_HITTEST: {
        !           382:                 static BOOL bHitTest=FALSE;
        !           383:                 HWND        hwndRecBtn;
        !           384: 
        !           385:                 bHitTest = (bHitTest ? FALSE : TRUE);
        !           386:                 hwndRecBtn = GetDlgItem(ghwndCtrlPanel, DID_RECORD);
        !           387:                 if (bHitTest) {
        !           388:                     CheckMenuItem(hMenu, MM_HITTEST, MF_CHECKED);
        !           389:                     EnableMenuItem(hMenu, MM_RECORD, MF_GRAYED);
        !           390:                     EnableWindow(hwndRecBtn, FALSE);
        !           391:                     gbHitTest = TRUE;
        !           392:                 } else {
        !           393:                     CheckMenuItem(hMenu, MM_HITTEST, MF_UNCHECKED);
        !           394:                     EnableMenuItem(hMenu, MM_RECORD, MF_ENABLED);
        !           395:                     EnableWindow(hwndRecBtn, TRUE);
        !           396:                     gbHitTest = FALSE;
        !           397:                     return 0L;
        !           398:                 }
        !           399: 
        !           400:                 if (ghMetaf == 0) {
        !           401:                     SetWindowText(ghTextWnd, "No Metafile loaded for hit-testing");
        !           402:                     return 0L;
        !           403:                 }
        !           404:                 return 0L;
        !           405:             }
        !           406:            case MM_ABOUT:
        !           407:                if (DialogBox(ghModule, (LPCSTR)"AboutBox", ghwndMain, (DLGPROC)About) == -1)
        !           408:                        MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK);
        !           409:                return 0L;
        !           410: 
        !           411:             case MM_LOAD_MASKBMP:
        !           412:                 SetWindowText(ghTextWnd, "Load Mask Bitmap");
        !           413:                 bGetBMP(hwnd, TRUE);
        !           414:                 return 0L;
        !           415: 
        !           416:             case MM_LOAD_BMP:
        !           417:                 SetWindowText(ghTextWnd, "Load Bitmap");
        !           418:                 bGetBMP(hwnd, FALSE);
        !           419:                 return 0L;
        !           420: 
        !           421:             case MM_SAVE_BMP:
        !           422:                 SetWindowText(ghTextWnd, "Save Drawing Surface as Bitmap");
        !           423:                 return 0L;
        !           424: 
        !           425:             case MM_LOAD:
        !           426:            case DID_OPEN: {
        !           427:                 ENHMETAHEADER EnhMetaHdr;
        !           428: 
        !           429:                 SetWindowText(ghTextWnd, "Load Metafile");
        !           430:                 DeleteEnhMetaFile(ghMetaf);
        !           431:                 ghMetaf = hemfLoadMetafile(hwnd);
        !           432:                 if (ghMetaf != 0) {
        !           433:                     GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr);
        !           434:                     SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, EnhMetaHdr.nRecords, FALSE);
        !           435:                 } else {
        !           436:                     SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, 0, FALSE);
        !           437:                 }
        !           438:                 bReset = TRUE;
        !           439:                 return 0L;
        !           440:             }
        !           441:             case MM_RECORD:
        !           442:                 if (gbHitTest) {
        !           443:                     SetWindowText(ghTextWnd, "Please CANCEL Hit Testing Mode First!");
        !           444:                     return 0L;
        !           445:                 }
        !           446: 
        !           447:                 SetWindowText(ghTextWnd, "Recording...");
        !           448:                 if (!gbRecording) {
        !           449:                     ghDCMetaf = hDCRecordMetafileAs(hwnd, szFilename);
        !           450:                 }
        !           451: 
        !           452:                 if (ghDCMetaf == NULL) {
        !           453:                    SetWindowText(ghTextWnd, "ERROR: Failed in creating the metafile DC!");
        !           454:                    return 0L;
        !           455:                 }
        !           456:                 gbRecording = TRUE;
        !           457: 
        !           458:                 if (ghpnCur != NULL)
        !           459:                     SelectObject(ghDCMetaf, ghpnCur);
        !           460: 
        !           461:                 if (ghbrCur != NULL)
        !           462:                     SelectObject(ghDCMetaf, ghbrCur);
        !           463: 
        !           464:                 if (ghCurFont != NULL)
        !           465:                     SelectObject(ghDCMetaf, ghCurFont);
        !           466:                 return 0L;
        !           467: 
        !           468:            case DID_RECORD: {
        !           469:                 char tmp[256];
        !           470:                 char suffix[20];
        !           471: 
        !           472:                 if (gbHitTest) {
        !           473:                     SetWindowText(ghTextWnd, "Please CANCEL Hit Testing Mode First!");
        !           474:                     return 0L;
        !           475:                 }
        !           476: 
        !           477:                 SetWindowText(ghTextWnd, "Recording...");
        !           478:                 if (!gbRecording) {
        !           479:                    wsprintf((LPSTR) suffix, "%d.emf", iMetafCnt);
        !           480:                     iMetafCnt++;
        !           481:                     strcpy(tmp, szFilename);
        !           482:                     strcat(tmp, suffix);
        !           483:                     ghDCMetaf = CreateEnhMetaFile((HDC)NULL, tmp, (LPRECT)NULL, (LPSTR)NULL);
        !           484:                 }
        !           485: 
        !           486:                 if (ghDCMetaf == NULL) {
        !           487:                    SetWindowText(ghTextWnd, "ERROR: Failed in creating the metafile DC!");
        !           488:                    return 0L;
        !           489:                 }
        !           490:                 gbRecording = TRUE;
        !           491: 
        !           492:                 if (ghpnCur != NULL)
        !           493:                     SelectObject(ghDCMetaf, ghpnCur);
        !           494: 
        !           495:                 if (ghbrCur != NULL)
        !           496:                     SelectObject(ghDCMetaf, ghbrCur);
        !           497: 
        !           498:                 if (ghCurFont != NULL)
        !           499:                     SelectObject(ghDCMetaf, ghCurFont);
        !           500: 
        !           501:                 return 0L;
        !           502:             }
        !           503:            case DID_STOP:
        !           504:                 SetWindowText(ghTextWnd, "Stop");
        !           505:                 if (gbRecording) {
        !           506:                     ghMetaf = CloseEnhMetaFile(ghDCMetaf);
        !           507:                     gbRecording = FALSE;
        !           508:                 }
        !           509:                 return 0L;
        !           510:            case DID_PLAY: {
        !           511:                 HDC hDCDrawSurf;
        !           512:                 ENHMETAHEADER EnhMetaHdr;
        !           513:                 //!!!RECT          rcClientDS;
        !           514: 
        !           515:                 SetWindowText(ghTextWnd, "Playing Metafile");
        !           516:                 if (ghMetaf != NULL) {
        !           517:                     hDCDrawSurf = GetDC(ghwndDrawSurf);
        !           518:                     //!!!GetClientRect(ghwndDrawSurf, &rcClientDS);
        !           519:                     GetEnhMetaFileHeader(ghMetaf, sizeof(ENHMETAHEADER), &EnhMetaHdr);
        !           520:                     //!!!PlayEnhMetaFile( hDCDrawSurf, ghMetaf, (LPRECT) &rcClientDS);
        !           521:                     PlayEnhMetaFile( hDCDrawSurf, ghMetaf, (LPRECT) &EnhMetaHdr.rclBounds);
        !           522: 
        !           523:                     //
        !           524:                     // Enabling the user to embed another metafile
        !           525:                     //
        !           526:                     if ((gbRecording) && (ghDCMetaf != NULL))
        !           527:                         PlayEnhMetaFile( ghDCMetaf, ghMetaf, (LPRECT) &EnhMetaHdr.rclBounds);
        !           528: 
        !           529:                     ReleaseDC(ghwndDrawSurf, hDCDrawSurf);
        !           530:                 }
        !           531:                 return 0L;
        !           532:             }
        !           533:            case DID_FF: {
        !           534:                 HDC           hDCDrawSurf;
        !           535:                 ENHMETAHEADER EnhMetaHdr;
        !           536:                 //!!!RECT          rcClientDS;
        !           537:                 static int    iRecord = 0;
        !           538:                 PLAYINFO      PlayInfo;
        !           539: 
        !           540:                 if (ghMetaf == 0)
        !           541:                     return 0L;
        !           542: 
        !           543:                 PlayInfo.iRecord = ++iRecord;
        !           544:                 PlayInfo.bPlayContinuous = TRUE;
        !           545: 
        !           546:                 GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr);
        !           547:                 SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, iRecord, FALSE);
        !           548:                 if ((EnhMetaHdr.nRecords > 1) && (iRecord <= (INT)EnhMetaHdr.nRecords)) {
        !           549:                     //!!!GetClientRect(ghwndDrawSurf, &rcClientDS);
        !           550:                     hDCDrawSurf = GetDC(ghwndDrawSurf);
        !           551:                     //!!!EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT) &rcClientDS);
        !           552:                     EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT) &EnhMetaHdr.rclBounds);
        !           553: 
        !           554:                     //
        !           555:                     // Enabling the user to record a metafile records selectively
        !           556:                     //
        !           557:                     if ((gbRecording) && (ghDCMetaf != NULL))
        !           558:                         EnumEnhMetaFile(ghDCMetaf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds);
        !           559: 
        !           560:                     ReleaseDC(ghwndDrawSurf, hDCDrawSurf);
        !           561:                 }
        !           562: 
        !           563:                 if ((iRecord == (INT) EnhMetaHdr.nRecords) || bReset) {
        !           564:                     iRecord = 0;
        !           565:                     if (bReset)
        !           566:                         SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, 0, FALSE);
        !           567:                     bReset = FALSE;
        !           568:                 }
        !           569: 
        !           570:                 return 0L;
        !           571:             }
        !           572:            case DID_CLEAR: {
        !           573:                 HDC     hDCDrawSurf;
        !           574:                 HGDIOBJ hObjOld;
        !           575:                 RECT    rcDrawSurf;
        !           576: 
        !           577:                 SetWindowText(ghTextWnd, "Drawing Surface cleared");
        !           578:                 hDCDrawSurf = GetDC(ghwndDrawSurf);
        !           579:                 ghbrAppBkgd = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
        !           580:                 hObjOld = SelectObject(hDCDrawSurf, ghbrAppBkgd);
        !           581:                 GetClientRect(ghwndDrawSurf, &rcDrawSurf);
        !           582:                 PatBlt(hDCDrawSurf, 0, 0, rcDrawSurf.right, rcDrawSurf.bottom, PATCOPY);
        !           583:                 ReleaseDC(ghwndDrawSurf, hDCDrawSurf);
        !           584:                 SelectObject(hDCDrawSurf, hObjOld);
        !           585:                 return 0L;
        !           586:             }
        !           587: 
        !           588:             case DID_PEN:
        !           589:                 SetWindowText(ghTextWnd, "Pen");
        !           590:                 return 0L;
        !           591:             case DID_TEXT:
        !           592:                 SetWindowText(ghTextWnd, "Text");
        !           593:                 return 0L;
        !           594:             case DID_RECT:
        !           595:                 SetWindowText(ghTextWnd, "Rectangle");
        !           596:                 return 0L;
        !           597:             case DID_FILLRECT:
        !           598:                 SetWindowText(ghTextWnd, "Filled Rectangle");
        !           599:                 return 0L;
        !           600:             case DID_ELLIPSE:
        !           601:                 SetWindowText(ghTextWnd, "Ellipse");
        !           602:                 return 0L;
        !           603:             case DID_FILLELLIPSE:
        !           604:                 SetWindowText(ghTextWnd, "Filled Ellipse");
        !           605:                 return 0L;
        !           606:             case DID_LINE:
        !           607:                 SetWindowText(ghTextWnd, "Line");
        !           608:                 return 0L;
        !           609:             case DID_BEZIER:
        !           610:                 SetWindowText(ghTextWnd,
        !           611:                     "Bezier: Click with Left button for placing control points");
        !           612:                 return 0L;
        !           613:             case DID_BMPOBJ:
        !           614:                 SetWindowText(ghTextWnd,
        !           615:                     "Bitmap: Click three points for the destination of the bitmap");
        !           616:                 return 0L;
        !           617:             case DID_METAF:
        !           618:                 SetWindowText(ghTextWnd,
        !           619:                     "External Metafile: Click three points for the destination of the Metafile");
        !           620:                 return 0L;
        !           621:            default:
        !           622:                 return DefWindowProc(hwnd, message, wParam, lParam);
        !           623:         }
        !           624:       }     // WM_COMMAND
        !           625:       default:
        !           626:         return DefWindowProc(hwnd, message, wParam, lParam);
        !           627:     }
        !           628: }
        !           629: 
        !           630: /******************************Public*Routine******************************\
        !           631: *
        !           632: * DrawSurfWndProc
        !           633: *       Drawing surface window procedure
        !           634: *
        !           635: * Effects:  Trapping all mouse messages and call the DrawStuff appropriately
        !           636: *           for drawing to the drawing surface DC and metafile DC as needed.
        !           637: *
        !           638: * Warnings:
        !           639: *
        !           640: * History:
        !           641: *  30-Apr-1992 -by- Petrus Wong
        !           642: * Wrote it.
        !           643: \**************************************************************************/
        !           644: 
        !           645: long DrawSurfWndProc(
        !           646:     HWND hwnd,
        !           647:     UINT message,
        !           648:     DWORD wParam,
        !           649:     LONG lParam)
        !           650: {
        !           651:     static BOOL    bTrack = FALSE;
        !           652:     static int     OrgX, OrgY;
        !           653:     static int     PrevX, PrevY;
        !           654:     static HDC     hDC;
        !           655:     static HCURSOR hCurArrow, hCurHT;
        !           656: 
        !           657:     switch (message) {
        !           658:       case WM_CREATE:
        !           659:           {
        !           660:               RECT       rect;
        !           661: 
        !           662:               GetClientRect(GetParent(hwnd), &rect);
        !           663: 
        !           664:               SetWindowPos(hwnd, NULL,
        !           665:                       0,
        !           666:                       30,
        !           667:                       rect.right-rect.left,
        !           668:                       rect.bottom-rect.top-30,
        !           669:                       SWP_NOZORDER | SWP_NOMOVE);
        !           670: 
        !           671:               CreateCaret(hwnd, NULL, 1, 12);
        !           672:               ghCurFont = GetStockObject(SYSTEM_FONT);
        !           673:               GetObject(ghCurFont, sizeof(LOGFONT), &glf);
        !           674:               hCurArrow = LoadCursor(NULL, IDC_ARROW);
        !           675:               hCurHT = LoadCursor(NULL, IDC_CROSS);
        !           676:               break;
        !           677:           }
        !           678: 
        !           679:       case WM_LBUTTONDOWN: {
        !           680:         int    x, y;
        !           681: 
        !           682:         x = (int) LOWORD(lParam);
        !           683:         y = (int) HIWORD(lParam);
        !           684: 
        !           685:         if (gbHitTest) {
        !           686:             hDC = GetDC(hwnd);
        !           687:             bHitTest(hDC, x, y);
        !           688:             ReleaseDC(hwnd, hDC);
        !           689:             break;
        !           690:         }
        !           691: 
        !           692:         bTrack = TRUE;
        !           693:         OrgX = PrevX = x;
        !           694:         OrgY = PrevY = y;
        !           695: 
        !           696:         hDC = GetDC(hwnd);
        !           697:         SetCapture(hwnd);
        !           698:         break;
        !           699:       }
        !           700: 
        !           701:       case WM_MOUSEMOVE: {
        !           702:         RECT rectClient;
        !           703:         int NextX;
        !           704:         int NextY;
        !           705: 
        !           706:         if (gbHitTest) {
        !           707:             SetCursor(hCurHT);
        !           708:         } else {
        !           709:             SetCursor(hCurArrow);
        !           710:         }
        !           711: 
        !           712:         // Update the selection region
        !           713:         if (bTrack) {
        !           714:             NextX = (SHORT) LOWORD(lParam);
        !           715:             NextY = (SHORT) HIWORD(lParam);
        !           716: 
        !           717:             // Do not draw outside the window's client area
        !           718: 
        !           719:             GetClientRect (hwnd, &rectClient);
        !           720:             if (NextX < rectClient.left) {
        !           721:                 NextX = rectClient.left;
        !           722:             } else if (NextX >= rectClient.right) {
        !           723:                 NextX = rectClient.right - 1;
        !           724:             }
        !           725:             if (NextY < rectClient.top) {
        !           726:                 NextY = rectClient.top;
        !           727:             } else if (NextY >= rectClient.bottom) {
        !           728:                 NextY = rectClient.bottom - 1;
        !           729:             }
        !           730:             if ((NextX != PrevX) || (NextY != PrevY)) {
        !           731:                SetROP2(hDC, R2_NOT);           // Erases the previous box
        !           732:                bDrawStuff(hDC, OrgX, OrgY, PrevX, PrevY, TRUE, TRUE, FALSE, NULL);
        !           733: 
        !           734:                //
        !           735:                // Optimization.  Do not record in metafile DC if it is going
        !           736:                // to be erased.  So only call bDrawStuff with the PEN tool.
        !           737:                //
        !           738:                if (gbRecording && (ghDCMetaf != NULL) && (gdwCurTool == DID_PEN)) {
        !           739:                    bDrawStuff(ghDCMetaf, OrgX, OrgY, PrevX, PrevY, TRUE, TRUE, FALSE, NULL);
        !           740:                }
        !           741: 
        !           742: 
        !           743:             // Get the current mouse position
        !           744:                PrevX = NextX;
        !           745:                PrevY = NextY;
        !           746: 
        !           747:                //
        !           748:                // SetROP2(hDC, R2_COPYPEN);
        !           749:                //   This is commented out because we don't want to erase
        !           750:                //   the background as it sweeps.
        !           751:                //
        !           752:                bDrawStuff(hDC, OrgX, OrgY, PrevX, PrevY, FALSE, TRUE, FALSE, NULL);
        !           753: 
        !           754:                if (gbRecording && (ghDCMetaf != NULL) && (gdwCurTool == DID_PEN)) {
        !           755:                    bDrawStuff(ghDCMetaf, OrgX, OrgY, PrevX, PrevY, FALSE, TRUE, FALSE, NULL);
        !           756:                }
        !           757: 
        !           758:             }
        !           759:         }
        !           760:         break;
        !           761: 
        !           762:       }
        !           763: 
        !           764:       case WM_LBUTTONUP: {
        !           765:         int NextX;
        !           766:         int NextY;
        !           767: 
        !           768:         if (!bTrack)
        !           769:            break;
        !           770: 
        !           771:         // End the selection
        !           772:            ReleaseCapture();
        !           773:            bTrack = FALSE;
        !           774: 
        !           775:         // Erases the box
        !           776:            //
        !           777:            // SetROP2(hDC, R2_NOT);
        !           778:            //   This is assumed to be R2_NOT, thus unnecessary
        !           779:            //
        !           780:            bDrawStuff(hDC, OrgX, OrgY, PrevX, PrevY, TRUE, FALSE, FALSE, NULL);
        !           781: 
        !           782:            if (gbRecording && (ghDCMetaf != NULL) && (gdwCurTool == DID_PEN)) {
        !           783:                bDrawStuff(ghDCMetaf, OrgX, OrgY, PrevX, PrevY, TRUE, FALSE, FALSE, NULL);
        !           784:            }
        !           785: 
        !           786:            NextX = LOWORD(lParam);
        !           787:            NextY = HIWORD(lParam);
        !           788: 
        !           789:         // Draws the new box
        !           790:            SetROP2(hDC, R2_COPYPEN);
        !           791:            bDrawStuff(hDC, OrgX, OrgY, NextX, NextY, FALSE, FALSE, TRUE, NULL);
        !           792: 
        !           793:            ReleaseDC(hwnd, hDC);
        !           794: 
        !           795:            if (gbRecording && (ghDCMetaf != NULL)) {
        !           796:                 bDrawStuff(ghDCMetaf, OrgX, OrgY, NextX, NextY, FALSE, FALSE, FALSE, NULL);
        !           797:            }
        !           798: 
        !           799:         break;
        !           800:       } // case WM_LBUTTONUP
        !           801: 
        !           802:       case WM_CHAR: {
        !           803: 
        !           804:         if (gdwCurTool != DID_TEXT)
        !           805:             break;
        !           806: 
        !           807:         hDC = GetDC(hwnd);
        !           808:         bDrawStuff(hDC, 0, 0, 0, 0, TRUE, FALSE, FALSE, (LPSTR)&wParam);
        !           809:         ReleaseDC(hwnd, hDC);
        !           810: 
        !           811:         if (gbRecording && (ghDCMetaf != NULL)) {
        !           812:             bDrawStuff(ghDCMetaf, 0, 0, 0, 0, TRUE, FALSE, FALSE, (LPSTR)&wParam);
        !           813:         }
        !           814: 
        !           815:         break;
        !           816:       }
        !           817: 
        !           818:       case WM_DESTROY: {
        !           819:         DestroyCaret();
        !           820:         DeleteObject(ghCurFont);
        !           821:        PostQuitMessage(0);
        !           822:        return 0L;
        !           823:       }
        !           824: 
        !           825:       default:
        !           826:        return DefWindowProc(hwnd, message, wParam, lParam);
        !           827:     }
        !           828: }
        !           829: 
        !           830: 
        !           831: /***************************************************************************\
        !           832: * About
        !           833: *
        !           834: * About dialog proc.
        !           835: *
        !           836: * History:
        !           837: * 09-09-91 Petrus Wong Rewrote.
        !           838: * 04-13-91 ????         Created.
        !           839: \***************************************************************************/
        !           840: 
        !           841: long About(
        !           842:     HWND hDlg,
        !           843:     UINT message,
        !           844:     DWORD wParam,
        !           845:     LONG lParam)
        !           846: {
        !           847:     switch (message) {
        !           848:     case WM_INITDIALOG:
        !           849:         return TRUE;
        !           850: 
        !           851:     case WM_COMMAND:
        !           852:         if (wParam == IDOK)
        !           853:             EndDialog(hDlg, wParam);
        !           854:         break;
        !           855:     }
        !           856: 
        !           857:     return FALSE;
        !           858: 
        !           859:     UNREFERENCED_PARAMETER(lParam);
        !           860:     UNREFERENCED_PARAMETER(hDlg);
        !           861: }
        !           862: 
        !           863: /***************************************************************************\
        !           864: *
        !           865: * TextWndProc
        !           866: *
        !           867: * Text Window procedure for displaying miscellaneous messages to user.
        !           868: *
        !           869: * History:
        !           870: * 10-07-91  Petrus Wong
        !           871: *   3D text output
        !           872: *
        !           873: \***************************************************************************/
        !           874: 
        !           875: LONG TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam)
        !           876: {
        !           877:     static HFONT hFont = (HFONT) NULL;
        !           878: 
        !           879:     switch (message)
        !           880:     {
        !           881:     case WM_CREATE:
        !           882:         {
        !           883:            LOGFONT    lf;
        !           884:            HDC        hDC;
        !           885:            HFONT      hOldFont;
        !           886:             TEXTMETRIC tm;
        !           887:            //RECT       rect;
        !           888: 
        !           889:             SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), (PVOID) &lf, (UINT)FALSE);
        !           890: 
        !           891:            hDC = GetDC(hwnd);
        !           892:            // this is the height for 8 point size font in pixels
        !           893:            lf.lfHeight = 8 * GetDeviceCaps(hDC, LOGPIXELSY) / 72;
        !           894: 
        !           895:            hFont = CreateFontIndirect(&lf);
        !           896:            hOldFont = SelectObject(hDC, hFont);
        !           897:            GetTextMetrics(hDC, &tm);
        !           898: 
        !           899:            // base the height of the window on size of text
        !           900:            glcyStatus = tm.tmHeight+6*GetSystemMetrics(SM_CYBORDER)+2;
        !           901:             ReleaseDC(hwnd, hDC);
        !           902:             break;
        !           903:         }
        !           904: 
        !           905:     case WM_DESTROY:
        !           906:            if (hFont)
        !           907:                DeleteObject(hFont);
        !           908:            break;
        !           909: 
        !           910:     case WM_SETTEXT:
        !           911:             DefWindowProc(hwnd, message, wParam, lParam);
        !           912:             InvalidateRect(hwnd,NULL,FALSE);
        !           913:             UpdateWindow(hwnd);
        !           914:             return 0L;
        !           915: 
        !           916:     case WM_PAINT:
        !           917:         {
        !           918:             PAINTSTRUCT ps;
        !           919:             RECT   rc;
        !           920:             char   ach[128];
        !           921:             int    len, nxBorder, nyBorder;
        !           922:             HFONT  hOldFont = NULL;
        !           923: 
        !           924:             BeginPaint(hwnd, &ps);
        !           925: 
        !           926:             GetClientRect(hwnd,&rc);
        !           927: 
        !           928:             nxBorder = GetSystemMetrics(SM_CXBORDER);
        !           929:            rc.left  += 9*nxBorder;
        !           930:             rc.right -= 9*nxBorder;
        !           931: 
        !           932:             nyBorder = GetSystemMetrics(SM_CYBORDER);
        !           933:            rc.top    += 3*nyBorder;
        !           934:            rc.bottom -= 3*nyBorder;
        !           935: 
        !           936:            // 3D Text
        !           937:             len = GetWindowText(hwnd, ach, sizeof(ach));
        !           938:            SetBkColor(ps.hdc, GetSysColor(COLOR_BTNFACE));
        !           939: 
        !           940:            SetBkMode(ps.hdc, TRANSPARENT);
        !           941:            SetTextColor(ps.hdc, RGB(64,96,96));
        !           942:            if (hFont)
        !           943:                hOldFont = SelectObject(ps.hdc, hFont);
        !           944:            ExtTextOut(ps.hdc, rc.left+2*nxBorder+2, rc.top+2, ETO_OPAQUE | ETO_CLIPPED,
        !           945:                        &rc, ach, len, NULL);
        !           946: 
        !           947:            SetTextColor(ps.hdc, RGB(128,128,128));
        !           948:            if (hFont)
        !           949:                hOldFont = SelectObject(ps.hdc, hFont);
        !           950:            ExtTextOut(ps.hdc, rc.left+2*nxBorder+1, rc.top+1, ETO_CLIPPED,
        !           951:                        &rc, ach, len, NULL);
        !           952: 
        !           953:            SetTextColor(ps.hdc, RGB(255,255,255));
        !           954:            if (hFont)
        !           955:                hOldFont = SelectObject(ps.hdc, hFont);
        !           956:            ExtTextOut(ps.hdc, rc.left+2*nxBorder, rc.top, ETO_CLIPPED,
        !           957:                        &rc, ach, len, NULL);
        !           958: 
        !           959:            SetBkMode(ps.hdc, OPAQUE);
        !           960: 
        !           961:            if (hOldFont)
        !           962:                SelectObject(ps.hdc, hOldFont);
        !           963: 
        !           964:             EndPaint(hwnd, &ps);
        !           965:             return 0L;
        !           966:         }
        !           967:     }
        !           968:     return DefWindowProc(hwnd, message, wParam, lParam);
        !           969: }
        !           970: 
        !           971: /******************************Public*Routine******************************\
        !           972: *
        !           973: * CtrlPanelDlgProc
        !           974: *       The Control Panel dialog procedure
        !           975: *
        !           976: * Effects:  Responsible for drawing the owner draw buttons.  Notifying
        !           977: *           parent of user's action.
        !           978: *
        !           979: * Warnings:
        !           980: *
        !           981: * History:
        !           982: *  27-May-1992 -by- Petrus Wong
        !           983: * Wrote it.
        !           984: \**************************************************************************/
        !           985: 
        !           986: LONG CtrlPanelDlgProc(HWND hwnd, UINT msg, DWORD dwParam, LONG lParam)
        !           987: {
        !           988:     switch (msg) {
        !           989:         case WM_INITDIALOG: {
        !           990:             int index;
        !           991: 
        !           992:             for (index = 0; index < OD_BTN_CNT; index++) {
        !           993:                 grHwndCtrlBtn[index] = (PVOID)GetDlgItem(hwnd, (INT)(ID_OD_BTN_BASE+index));
        !           994:             }
        !           995:             for (index = 0; index < OD_TOOL_CNT; index++) {
        !           996:                 grHwndToolBtn[index] = (PVOID)GetDlgItem(hwnd, (INT)(ID_OD_TOOL_BASE+index));
        !           997:             }
        !           998:             return TRUE;
        !           999:         }
        !          1000: 
        !          1001:         case WM_DRAWITEM: {
        !          1002:             PDRAWITEMSTRUCT pDIS = (PDRAWITEMSTRUCT) lParam;
        !          1003:             HBITMAP hBmpOld;
        !          1004:             BITMAP  bm;
        !          1005:             HANDLE  hCtl;
        !          1006:             HDC     hDCCtl;
        !          1007: 
        !          1008:             if (pDIS->CtlID == gdwCurCtrl) {
        !          1009:                 GetObject((HBITMAP) ghBmpDn[pDIS->CtlID - ID_OD_BTN_BASE], sizeof(BITMAP), (LPSTR)&bm);
        !          1010:                 hBmpOld = SelectObject(ghDCMem, (HBITMAP) ghBmpDn[pDIS->CtlID - ID_OD_BTN_BASE]);
        !          1011:             }
        !          1012: 
        !          1013:             if (pDIS->CtlID == gdwCurTool) {
        !          1014:                 GetObject((HBITMAP)ghToolBmpDn[pDIS->CtlID - ID_OD_TOOL_BASE], sizeof(BITMAP), (LPSTR)&bm);
        !          1015:                 hBmpOld = SelectObject(ghDCMem, (HBITMAP)ghToolBmpDn[pDIS->CtlID - ID_OD_TOOL_BASE]);
        !          1016:             }
        !          1017: 
        !          1018:             if ((pDIS->CtlID < ID_OD_TOOL_BASE) && (pDIS->CtlID != gdwCurCtrl)) {
        !          1019:                 GetObject((HBITMAP)ghBmpUp[pDIS->CtlID - ID_OD_BTN_BASE], sizeof(BITMAP), (LPSTR)&bm);
        !          1020:                 hBmpOld = SelectObject(ghDCMem, (HBITMAP)ghBmpUp[pDIS->CtlID - ID_OD_BTN_BASE]);
        !          1021:             }
        !          1022: 
        !          1023:             if ((pDIS->CtlID >= ID_OD_TOOL_BASE) && (pDIS->CtlID != gdwCurTool)) {
        !          1024:                 GetObject((HBITMAP)ghToolBmpUp[pDIS->CtlID - ID_OD_TOOL_BASE], sizeof(BITMAP), (LPSTR)&bm);
        !          1025:                 hBmpOld = SelectObject(ghDCMem, (HBITMAP)ghToolBmpUp[pDIS->CtlID - ID_OD_TOOL_BASE]);
        !          1026:             }
        !          1027: 
        !          1028:             //
        !          1029:             // pDIS->hDC is clipped to the update region but unfortunately
        !          1030:             // that doesn't work well with StretchBlt.  StretchBlt is used
        !          1031:             // because I don't have to make sure that the bitmap size is
        !          1032:             // exactly the same as the size of the button.
        !          1033:             //
        !          1034:             hCtl   = GetDlgItem(hwnd, pDIS->CtlID);
        !          1035:             hDCCtl = GetDC(hCtl);
        !          1036:             StretchBlt(hDCCtl,                                //pDIS->hDC,
        !          1037:                    pDIS->rcItem.left, pDIS->rcItem.top,
        !          1038:                    pDIS->rcItem.right - pDIS->rcItem.left,
        !          1039:                    pDIS->rcItem.bottom - pDIS->rcItem.top,
        !          1040:                    ghDCMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
        !          1041:             ReleaseDC(hCtl, hDCCtl);
        !          1042:             SelectObject(ghDCMem, hBmpOld);
        !          1043:             break;
        !          1044:         }
        !          1045: 
        !          1046:         case WM_COMMAND: {
        !          1047:             DWORD dwOldCtrl = gdwCurCtrl;
        !          1048:             DWORD dwOldTool = gdwCurTool;
        !          1049: 
        !          1050:             switch (dwParam) {
        !          1051:                 case DID_ONE:
        !          1052:                 case DID_TWO:
        !          1053:                 case DID_THREE:
        !          1054:                 case DID_FOUR:
        !          1055:                 case DID_FIVE:
        !          1056:                 case DID_SIX:
        !          1057:                 case DID_SEVEN:
        !          1058:                 case DID_EIGHT:
        !          1059:                 case DID_NINE:
        !          1060:                 case DID_ZERO:
        !          1061:                 case DID_TEN_PLUS:
        !          1062:                     //SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, dwParam - DID_ZERO, FALSE);
        !          1063:                     SendMessage(ghwndMain, WM_COMMAND, dwParam, lParam);
        !          1064:                     break;
        !          1065:                 case DID_OPEN:
        !          1066:                 case DID_RECORD:
        !          1067:                 case DID_STOP:
        !          1068:                 case DID_PLAY:
        !          1069:                 case DID_FF:
        !          1070:                     SendMessage(ghwndMain, WM_COMMAND, dwParam, lParam);
        !          1071:                     gdwCurCtrl = dwParam;
        !          1072:                     InvalidateRect((HWND)grHwndCtrlBtn[dwOldCtrl - ID_OD_BTN_BASE], NULL, FALSE);
        !          1073:                     InvalidateRect((HWND)grHwndCtrlBtn[gdwCurCtrl - ID_OD_BTN_BASE], NULL, FALSE);
        !          1074:                     break;
        !          1075:                 case DID_CLEAR:
        !          1076:                     SendMessage(ghwndMain, WM_COMMAND, dwParam, lParam);
        !          1077:                     break;
        !          1078:                 case DID_TEXT:
        !          1079:                 case DID_PEN:
        !          1080:                 case DID_RECT:
        !          1081:                 case DID_FILLRECT:
        !          1082:                 case DID_ELLIPSE:
        !          1083:                 case DID_FILLELLIPSE:
        !          1084:                 case DID_LINE:
        !          1085:                 case DID_BEZIER:
        !          1086:                 case DID_BMPOBJ:
        !          1087:                 case DID_METAF:
        !          1088:                     SendMessage(ghwndMain, WM_COMMAND, dwParam, lParam);
        !          1089:                     gdwCurTool = dwParam;
        !          1090:                     InvalidateRect((HWND)grHwndToolBtn[dwOldTool - ID_OD_TOOL_BASE], NULL, FALSE);
        !          1091:                     InvalidateRect((HWND)grHwndToolBtn[gdwCurTool - ID_OD_TOOL_BASE], NULL, FALSE);
        !          1092:                     break;
        !          1093:             }
        !          1094:             break;
        !          1095:         }
        !          1096: 
        !          1097: 
        !          1098:         case WM_PAINT:
        !          1099:             {
        !          1100:                 HDC hdc;
        !          1101:                 RECT rc, rcDlg;
        !          1102:                 PAINTSTRUCT ps;
        !          1103:                 HPEN hpenWindowFrame, hpenDarkGray;
        !          1104:                 int  icyDlg;
        !          1105:                 int  icyBorder;
        !          1106: 
        !          1107:                 icyBorder = GetSystemMetrics(SM_CYBORDER);
        !          1108: 
        !          1109:                 GetWindowRect(hwnd, &rcDlg);
        !          1110:                 icyDlg = rcDlg.right - rcDlg.left;
        !          1111: 
        !          1112:                 /*
        !          1113:                  * Draw our border lines.
        !          1114:                  */
        !          1115:                 GetClientRect(hwnd, &rc);
        !          1116:                 hdc = BeginPaint(hwnd, &ps);
        !          1117: 
        !          1118:                 SelectObject(hdc, GetStockObject(WHITE_PEN));
        !          1119:                 MoveToEx(hdc, rc.left, rc.top, NULL);
        !          1120:                 LineTo(hdc, rc.right, rc.top);
        !          1121: 
        !          1122:                 hpenDarkGray = CreatePen(PS_SOLID, 1, DARKGRAY);
        !          1123:                 SelectObject(hdc, hpenDarkGray);
        !          1124:                 MoveToEx(hdc, rc.left, (rc.top + icyDlg) - icyBorder - 1, NULL);
        !          1125:                 LineTo(hdc, rc.right, (rc.top + icyDlg) - icyBorder - 1);
        !          1126: 
        !          1127:                 hpenWindowFrame = CreatePen(PS_SOLID, icyBorder,
        !          1128:                         GetSysColor(COLOR_WINDOWFRAME));
        !          1129:                 SelectObject(hdc, hpenWindowFrame);
        !          1130:                 MoveToEx(hdc, rc.left, (rc.top + icyDlg) - icyBorder, NULL);
        !          1131:                 LineTo(hdc, rc.right, (rc.top + icyDlg) - icyBorder);
        !          1132: 
        !          1133:                 EndPaint(hwnd, &ps);
        !          1134:                 DeleteObject(hpenWindowFrame);
        !          1135:                 DeleteObject(hpenDarkGray);
        !          1136:             }
        !          1137: 
        !          1138:             break;
        !          1139: 
        !          1140: 
        !          1141:         //case WM_CTLCOLOR:
        !          1142:         case WM_CTLCOLORDLG:
        !          1143:         //case WM_CTLCOLORLISTBOX:
        !          1144:         //case WM_CTLCOLORSTATIC:
        !          1145:             switch (GET_WM_CTLCOLOR_TYPE(dwParam, lParam, msg)) {
        !          1146:                 case CTLCOLOR_DLG:
        !          1147:                 //case CTLCOLOR_LISTBOX:
        !          1148:                     return (BOOL)GetStockObject(LTGRAY_BRUSH);
        !          1149: 
        !          1150:                 //case CTLCOLOR_STATIC:
        !          1151:                 //    SetBkColor(GET_WM_CTLCOLOR_HDC(dwParam, lParam, msg),
        !          1152:                 //            LIGHTGRAY);
        !          1153:                 //    return (BOOL)GetStockObject(LTGRAY_BRUSH);
        !          1154:             }
        !          1155:             return (BOOL)NULL;
        !          1156: 
        !          1157:         default:
        !          1158:             return FALSE;
        !          1159:     }
        !          1160: 
        !          1161:     return FALSE;
        !          1162: }
        !          1163: 
        !          1164: 
        !          1165: 
        !          1166: /******************************Public*Routine******************************\
        !          1167: *
        !          1168: * bDrawStuff
        !          1169: *
        !          1170: * Effects:  The drawing routines are localized here.
        !          1171: *           bErase is TRUE if this fcn is called for erasing previous object.
        !          1172: *           (as in tracking objects.)  It is FALSE, otherwise.
        !          1173: *
        !          1174: *           bMove is TRUE if this fcn is called inside the WM_MOUSEMOVE (as
        !          1175: *           in tracking objects.)  It is FALSE, otherwise.
        !          1176: *
        !          1177: *           bCntPt is TRUE if this fcn is to increment either the iCnt or
        !          1178: *           iCntMF counter (used only in processing metafile or bezier.)
        !          1179: *           It is FALSE, otherwise.
        !          1180: *
        !          1181: *           lpstr contains the character to be drawn by TextOut when it is
        !          1182: *           not NULL.
        !          1183: *
        !          1184: * Warnings: Metafile and Bezier assume that the caller is calling this fcn
        !          1185: *           to draw in the screen DC first. Then draw it to the metafile DC.
        !          1186: *           Thus, when it is called to draw on the metafile DC, the points
        !          1187: *           would have been set already.
        !          1188: *
        !          1189: * History:
        !          1190: *  10-May-1992 -by- Petrus Wong
        !          1191: * Wrote it.
        !          1192: \**************************************************************************/
        !          1193: 
        !          1194: BOOL bDrawStuff(HDC hDC, INT OrgX, INT OrgY,
        !          1195:                          INT NextX, INT NextY,
        !          1196:                          BOOL bErase,
        !          1197:                          BOOL bMove,
        !          1198:                          BOOL bCntPt,
        !          1199:                          LPSTR lpstr) {
        !          1200:     BOOL bSuccess;
        !          1201:     HGDIOBJ hObjOld;
        !          1202:     static POINT rgPts[MAX_POINTS], rgPtsMF[MAX_POINTS_MF], rgPtsBMP[MAX_POINTS_BMP];
        !          1203:     static int   iCnt=0, iCntMF=0, iCntBMP=0;
        !          1204:     static BOOL  bCaretShown=FALSE;
        !          1205: 
        !          1206:     bSuccess = TRUE;
        !          1207:     if (bCaretShown) {
        !          1208:         HideCaret(ghwndDrawSurf);
        !          1209:         bCaretShown = FALSE;
        !          1210:     }
        !          1211: 
        !          1212:     switch (gdwCurTool) {
        !          1213:         case DID_PEN:
        !          1214:             if (bErase) {
        !          1215:                 MoveToEx(hDC, NextX, NextY, NULL);
        !          1216:             } else {
        !          1217:                 //
        !          1218:                 // Override the ROP2 st. the pen won't erase its track
        !          1219:                 //
        !          1220:                 SetROP2(hDC, R2_COPYPEN);
        !          1221:                 LineTo(hDC, NextX, NextY);
        !          1222:             }
        !          1223:             break;
        !          1224:         case DID_TEXT: {
        !          1225:             POINT   Pt;
        !          1226: 
        !          1227:             if (lpstr == NULL) {
        !          1228:                 ShowCaret(ghwndDrawSurf);
        !          1229:                 bCaretShown = TRUE;
        !          1230:                 SetCaretPos(NextX, NextY);
        !          1231:                 MoveToEx(hDC, NextX, NextY, NULL);
        !          1232:                 SetFocus(ghwndDrawSurf);
        !          1233:                 break;
        !          1234:             }
        !          1235: 
        !          1236:             SetTextAlign(hDC, TA_UPDATECP);
        !          1237:             hObjOld = SelectObject(hDC, ghCurFont);
        !          1238:             SetTextColor(hDC, gCrText);
        !          1239:             SetBkMode(hDC, TRANSPARENT);
        !          1240:             TextOut(hDC, 0, 0, lpstr, 1);
        !          1241:             SelectObject(hDC, hObjOld);
        !          1242:             GetCurrentPositionEx(hDC, (LPPOINT) &Pt);
        !          1243:             SetCaretPos(Pt.x, Pt.y+2);
        !          1244:             ShowCaret(ghwndDrawSurf);
        !          1245:             bCaretShown = TRUE;
        !          1246: 
        !          1247:             break;
        !          1248:         }
        !          1249:         case DID_RECT:
        !          1250:             hObjOld = SelectObject(hDC, GetStockObject(NULL_BRUSH));
        !          1251:             Rectangle(hDC, OrgX, OrgY, NextX, NextY);
        !          1252:             SelectObject(hDC, hObjOld);
        !          1253:             break;
        !          1254:         case DID_FILLRECT:
        !          1255:             Rectangle(hDC, OrgX, OrgY, NextX, NextY);
        !          1256:             break;
        !          1257:         case DID_ELLIPSE:
        !          1258:             hObjOld = SelectObject(hDC, GetStockObject(NULL_BRUSH));
        !          1259:             Ellipse(hDC, OrgX, OrgY, NextX, NextY);
        !          1260:             SelectObject(hDC, hObjOld);
        !          1261:             break;
        !          1262:         case DID_FILLELLIPSE:
        !          1263:             Ellipse(hDC, OrgX, OrgY, NextX, NextY);
        !          1264:             break;
        !          1265:         case DID_LINE:
        !          1266:             MoveToEx(hDC, OrgX, OrgY, NULL);
        !          1267:             LineTo(hDC, NextX, NextY);
        !          1268:             break;
        !          1269:         case DID_BEZIER:
        !          1270:             if (bErase || bMove)
        !          1271:                 return bSuccess;
        !          1272: 
        !          1273:             if (bCntPt) {
        !          1274:                 rgPts[iCnt].x = NextX;
        !          1275:                 rgPts[iCnt].y = NextY;
        !          1276:                 iCnt++;
        !          1277: 
        !          1278:                 if (iCnt == MAX_POINTS - 1)
        !          1279:                     iCnt = 0;
        !          1280:             }
        !          1281: 
        !          1282:             if ((iCnt % 3) == 1) {              // (iCnt + 1) % 3 == 1
        !          1283:                 //
        !          1284:                 // Override the ROP2 st. the pen won't erase its track
        !          1285:                 //
        !          1286:                 SetROP2(hDC, R2_COPYPEN);
        !          1287:                 PolyBezier(hDC, (LPPOINT)&rgPts, (DWORD) iCnt);
        !          1288:             }
        !          1289:             return bSuccess;
        !          1290: 
        !          1291:         case DID_BMPOBJ: {
        !          1292:             static BOOL          bBltReady = FALSE;
        !          1293:             HDC                  hDCRef;
        !          1294:             HGDIOBJ              hObjOld;
        !          1295:             BITMAP               bm;
        !          1296: 
        !          1297:             if (bErase || bMove)
        !          1298:                 return bSuccess;
        !          1299: 
        !          1300:             if (ghBmp == NULL) {
        !          1301:                 SetWindowText(ghTextWnd, "ERROR: No bitmap to embed!");
        !          1302:                 return bSuccess;
        !          1303:             }
        !          1304: 
        !          1305:             if (bCntPt) {
        !          1306:                 bBltReady = FALSE;
        !          1307:                 rgPtsBMP[iCntBMP].x = NextX;
        !          1308:                 rgPtsBMP[iCntBMP].y = NextY;
        !          1309:                 iCntBMP++;
        !          1310: 
        !          1311:                 if (iCntBMP < MAX_POINTS_BMP) {
        !          1312:                     return bSuccess;
        !          1313:                 }
        !          1314:             } else {
        !          1315:                 //
        !          1316:                 // Caller don't want to increment counter, so must be doing
        !          1317:                 // recording, so we just Blt again...
        !          1318:                 //
        !          1319:                 // But, if the Blt data is no good, bail out...
        !          1320:                 //
        !          1321:                 if (!bBltReady) {
        !          1322:                     return bSuccess;
        !          1323:                 }
        !          1324:                 hDCRef = CreateCompatibleDC(NULL);
        !          1325:                 hObjOld = SelectObject(hDCRef, ghBmp);
        !          1326:                 GetObject(ghBmp, sizeof(BITMAP), (LPSTR)&bm);
        !          1327:                 PlgBlt(hDC, rgPtsBMP, hDCRef, 0, 0, bm.bmWidth, bm.bmHeight,
        !          1328:                        ghBmpMask, 0, 0);
        !          1329:                 SelectObject(hDCRef, hObjOld);
        !          1330:                 DeleteDC(hDCRef);
        !          1331:                 return bSuccess;
        !          1332:             }
        !          1333:             bBltReady = TRUE;
        !          1334:             hDCRef = CreateCompatibleDC(NULL);
        !          1335:             hObjOld = SelectObject(hDCRef, ghBmp);
        !          1336: 
        !          1337:             GetObject(ghBmpMask, sizeof(BITMAP), (LPSTR)&bm);
        !          1338:             if (bm.bmBitsPixel != 1) {
        !          1339:                 SetWindowText(ghTextWnd, "ERROR: Mask has to be a Monochrome bitmap!");
        !          1340:                 ghBmpMask = NULL;
        !          1341:             }
        !          1342: 
        !          1343:             //
        !          1344:             // Avoiding a HT bug
        !          1345:             //
        !          1346:             //ghBmpMask = NULL;
        !          1347:             GetObject(ghBmp, sizeof(BITMAP), (LPSTR)&bm);
        !          1348:             //SetStretchBltMode(hDC, HALFTONE);
        !          1349:             PlgBlt(hDC, rgPtsBMP, hDCRef, 0, 0, bm.bmWidth, bm.bmHeight,
        !          1350:                    ghBmpMask, 0, 0);
        !          1351:             SelectObject(hDCRef, hObjOld);
        !          1352:             DeleteDC(hDCRef);
        !          1353:             iCntBMP = 0;                         // reset
        !          1354:             return bSuccess;
        !          1355:         }
        !          1356: 
        !          1357:         case DID_METAF: {
        !          1358:             ENHMETAHEADER EnhMetaHdr;
        !          1359:             RECT          rcClientDS;
        !          1360:             static XFORM         xform;
        !          1361:             static BOOL          bXformReady = FALSE;
        !          1362: 
        !          1363:             if (bErase || bMove)
        !          1364:                 return bSuccess;
        !          1365: 
        !          1366:             if (ghMetaf == NULL) {
        !          1367:                 SetWindowText(ghTextWnd, "ERROR: No metafile to embed!");
        !          1368:                 return bSuccess;
        !          1369:             }
        !          1370: 
        !          1371:             if (bCntPt) {
        !          1372:                 bXformReady = FALSE;
        !          1373:                 rgPtsMF[iCntMF].x = NextX;
        !          1374:                 rgPtsMF[iCntMF].y = NextY;
        !          1375:                 iCntMF++;
        !          1376: 
        !          1377:                 if (iCntMF < MAX_POINTS_MF) {
        !          1378:                     return bSuccess;
        !          1379:                 }
        !          1380:             } else {
        !          1381:                 //
        !          1382:                 // Caller don't want to increment counter, so must be doing
        !          1383:                 // recording, so we just set xform and play it again...
        !          1384:                 //
        !          1385:                 // But, if the xform data is no good, bail out...
        !          1386:                 //
        !          1387:                 if (!bXformReady) {
        !          1388:                     return bSuccess;
        !          1389:                 }
        !          1390: 
        !          1391:                 GetEnhMetaFileHeader(ghMetaf, sizeof(ENHMETAHEADER), &EnhMetaHdr);
        !          1392:                 SetWorldTransform(hDC, &xform);
        !          1393:                 GetClientRect(ghwndDrawSurf, &rcClientDS);
        !          1394:                 //PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &rcClientDS);
        !          1395:                 PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &EnhMetaHdr.rclBounds);
        !          1396:                 ModifyWorldTransform(hDC, NULL, MWT_IDENTITY);
        !          1397:                 return bSuccess;
        !          1398:             }
        !          1399: 
        !          1400:             GetEnhMetaFileHeader(ghMetaf, sizeof(ENHMETAHEADER), &EnhMetaHdr);
        !          1401:             //
        !          1402:             // Based on the three points, top-left, top-right and bottom-left
        !          1403:             // (in this order), of the destination, solve equations for the
        !          1404:             // elements of the transformation matrix.
        !          1405:             //
        !          1406:             xform.eDx = (float) rgPtsMF[0].x;
        !          1407:             xform.eDy = (float) rgPtsMF[0].y;
        !          1408:             xform.eM11 = (rgPtsMF[1].x - xform.eDx)/(EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left);
        !          1409:             xform.eM12 = (rgPtsMF[1].y - xform.eDy)/(EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left);
        !          1410:             xform.eM21 = (rgPtsMF[2].x - xform.eDx)/(EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top);
        !          1411:             xform.eM22 = (rgPtsMF[2].y - xform.eDy)/(EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top);
        !          1412: 
        !          1413:             bXformReady = TRUE;
        !          1414:             SetWorldTransform(hDC, &xform);
        !          1415:             GetClientRect(ghwndDrawSurf, &rcClientDS);
        !          1416:             //PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &rcClientDS);
        !          1417:             PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &EnhMetaHdr.rclBounds);
        !          1418:             ModifyWorldTransform(hDC, NULL, MWT_IDENTITY);
        !          1419:             iCntMF = 0;                         // reset
        !          1420:             return bSuccess;
        !          1421:         }
        !          1422:         default:
        !          1423:             break;
        !          1424:     }
        !          1425:     //
        !          1426:     // Reset counter, user has selected other tools.
        !          1427:     //
        !          1428:     iCnt = 0;
        !          1429:     iCntMF = 0;
        !          1430:     iCntBMP = 0;
        !          1431:     return bSuccess;
        !          1432: }
        !          1433: 
        !          1434: /******************************Public*Routine******************************\
        !          1435: *
        !          1436: * hemfLoadMetafile
        !          1437: *
        !          1438: * Effects:   Brings up the Open file common dialog
        !          1439: *            Get the enhanced metafile spec'd by user
        !          1440: *            returns the handle to the enhanced metafile if successfull
        !          1441: *               otherwise, returns 0.
        !          1442: *
        !          1443: * Warnings:
        !          1444: *
        !          1445: * History:
        !          1446: *  08-May-1992 -by- Petrus Wong
        !          1447: * Wrote it.
        !          1448: \**************************************************************************/
        !          1449: 
        !          1450: HENHMETAFILE hemfLoadMetafile(HWND hwnd) {
        !          1451:     OPENFILENAME    ofn;
        !          1452:     char            szFile[256], szFileTitle[256];
        !          1453:     static char     *szFilter;
        !          1454: 
        !          1455:     szFilter =
        !          1456:       "EnhMeta files (*.emf)\0*.emf\0\0";
        !          1457: 
        !          1458:     strcpy(szFile, "*.emf\0");
        !          1459:     ofn.lStructSize = sizeof(OPENFILENAME);
        !          1460:     ofn.hwndOwner = hwnd;
        !          1461:     ofn.lpstrFilter = szFilter;
        !          1462:     ofn.lpstrCustomFilter = (LPSTR) NULL;
        !          1463:     ofn.nMaxCustFilter = 0L;
        !          1464:     ofn.nFilterIndex = 1;
        !          1465:     ofn.lpstrFile = szFile;
        !          1466:     ofn.nMaxFile = sizeof(szFile);
        !          1467:     ofn.lpstrFileTitle = szFileTitle;
        !          1468:     ofn.nMaxFileTitle = sizeof(szFileTitle);
        !          1469:     ofn.lpstrInitialDir = NULL;
        !          1470:     ofn.lpstrTitle = "Load Metafile";
        !          1471:     ofn.Flags = 0L;
        !          1472:     ofn.nFileOffset = 0;
        !          1473:     ofn.nFileExtension = 0;
        !          1474:     ofn.lpstrDefExt = "EMF";
        !          1475: 
        !          1476:     if (!GetOpenFileName(&ofn))
        !          1477:         return 0L;
        !          1478: 
        !          1479:     return GetEnhMetaFile(szFile);
        !          1480: }
        !          1481: 
        !          1482: /******************************Public*Routine******************************\
        !          1483: *
        !          1484: * hDCRecordMetafileAs
        !          1485: *
        !          1486: * Effects:   Brings up the SaveAs common dialog
        !          1487: *            Creates the enhanced metafile with the filename spec'd by user
        !          1488: *            Modifies the second arg to reflect the new default filename
        !          1489: *            less extension
        !          1490: *            returns the created metafile DC if successful, otherwise, 0
        !          1491: *
        !          1492: * Warnings:
        !          1493: *
        !          1494: * History:
        !          1495: *  08-May-1992 -by- Petrus Wong
        !          1496: * Wrote it.
        !          1497: \**************************************************************************/
        !          1498: 
        !          1499: HDC hDCRecordMetafileAs(HWND hwnd, LPSTR szFilename) {
        !          1500:     OPENFILENAME ofn;
        !          1501:     char szFile[256], szFileTitle[256];
        !          1502:     static char *szFilter;
        !          1503:     char *szTmp, szTmp2[256];
        !          1504:     HDC  hDCMeta;
        !          1505: 
        !          1506:     szFilter = "EnhMeta files (*.emf)\0\0";
        !          1507:     strcpy(szFile, "*.emf\0");
        !          1508:     ofn.lStructSize = sizeof(OPENFILENAME);
        !          1509:     ofn.hwndOwner = hwnd;
        !          1510:     ofn.lpstrFilter = szFilter;
        !          1511:     ofn.lpstrCustomFilter = (LPSTR) NULL;
        !          1512:     ofn.nMaxCustFilter = 0L;
        !          1513:     ofn.nFilterIndex = 0L;
        !          1514:     ofn.lpstrFile = szFile;
        !          1515:     ofn.nMaxFile = sizeof(szFile);
        !          1516:     ofn.lpstrFileTitle = szFileTitle;
        !          1517:     ofn.nMaxFileTitle = sizeof(szFileTitle);
        !          1518:     ofn.lpstrInitialDir = NULL;
        !          1519:     ofn.lpstrTitle = "Save Metafile As";
        !          1520:     ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;
        !          1521:     ofn.nFileOffset = 0;
        !          1522:     ofn.nFileExtension = 0;
        !          1523:     ofn.lpstrDefExt = (LPSTR)NULL;
        !          1524: 
        !          1525:     if (!GetSaveFileName(&ofn)) {
        !          1526:         return 0L;
        !          1527:     }
        !          1528: 
        !          1529:     hDCMeta = CreateEnhMetaFile((HDC)NULL, szFile, (LPRECT)NULL, (LPSTR)NULL);
        !          1530: 
        !          1531:     //
        !          1532:     // parses the new filename, removes the extension and copy it into
        !          1533:     // szFilename
        !          1534:     //
        !          1535:     strcpy(szFilename, "");
        !          1536:     szTmp = (char *)strtok(szFile, "\\");
        !          1537:     strcpy(szTmp2, szTmp);
        !          1538:     while (szTmp != NULL) {
        !          1539:         szTmp = (char *)strtok(NULL, "\\");
        !          1540:         if (szTmp != NULL) {
        !          1541:             strcat(szFilename, szTmp2);
        !          1542:             strcpy(szTmp2, szTmp);
        !          1543:             strcat(szFilename, "\\");
        !          1544:         }
        !          1545:     }
        !          1546:     szTmp = (char *)strtok(szTmp2, ".");
        !          1547:     strcat(szFilename, szTmp);
        !          1548: 
        !          1549:     return hDCMeta;
        !          1550: }
        !          1551: 
        !          1552: 
        !          1553: /******************************Public*Routine******************************\
        !          1554: *
        !          1555: * bPlayRecord
        !          1556: *
        !          1557: * Effects:  Play metafile
        !          1558: *           if PlayInfo.bPlayContinuous is TRUE
        !          1559: *               play metafile from 1st record up to the PlayInfo.iRecord th
        !          1560: *                   record
        !          1561: *           else only play the PlayInfo.iRecord th record and those preceding
        !          1562: *               records that are relevant like MoveTo, etc.
        !          1563: *           Terminates enumeration after playing up to the
        !          1564: *               PlayInfo.iRecord th record
        !          1565: *
        !          1566: * Warnings:
        !          1567: *
        !          1568: * History:
        !          1569: *  08-May-1992 -by- Petrus Wong
        !          1570: * Wrote it.
        !          1571: \**************************************************************************/
        !          1572: 
        !          1573: BOOL APIENTRY bPlayRecord(HDC hDC, LPHANDLETABLE lpHandleTable,
        !          1574:                                    LPENHMETARECORD lpEnhMetaRecord,
        !          1575:                                    UINT nHandles,
        !          1576:                                    LPVOID lpData) {
        !          1577:     BOOL bSuccess;
        !          1578:     static int  iCnt=0;
        !          1579:     int         i;
        !          1580:     char        ach[128];
        !          1581:     char        achTmp[128];
        !          1582:     LONG        lNumDword;
        !          1583: 
        !          1584:     bSuccess = TRUE;
        !          1585: 
        !          1586:     lNumDword = (lpEnhMetaRecord->nSize-8) / 4;
        !          1587: 
        !          1588:     iCnt++;
        !          1589:     if (((PLAYINFO *) lpData)->bPlayContinuous) {
        !          1590:         bSuccess = PlayEnhMetaFileRecord(hDC, lpHandleTable,
        !          1591:                                              lpEnhMetaRecord, nHandles);
        !          1592:         if (iCnt == ((PLAYINFO *) lpData)->iRecord) {
        !          1593:             wsprintf((LPSTR) ach, "%s", rgMetaName[lpEnhMetaRecord->iType]);
        !          1594:             for (i=0; i < lNumDword; i++) {
        !          1595:                 wsprintf((LPSTR) achTmp, "%ld ", lpEnhMetaRecord->dParm[i]);
        !          1596:                 if ((strlen(ach)+strlen(achTmp))/sizeof(char) >= 128)
        !          1597:                     break;
        !          1598:                 strcat(ach, achTmp);
        !          1599:             }
        !          1600:         SetWindowText(ghTextWnd, ach);
        !          1601:         }
        !          1602:     } else {
        !          1603: 
        !          1604:         switch (lpEnhMetaRecord->iType) {
        !          1605:             case MR_SETWINDOWEXTEX:
        !          1606:             case MR_SETWINDOWORGEX:
        !          1607:             case MR_SETVIEWPORTEXTEX:
        !          1608:             case MR_SETVIEWPORTORGEX:
        !          1609:             case MR_SETBRUSHORGEX:
        !          1610:             case MR_SETMAPMODE:
        !          1611:             case MR_SETBKMODE:
        !          1612:             case MR_SETPOLYFILLMODE:
        !          1613:             case MR_SETROP2:
        !          1614:             case MR_SETSTRETCHBLTMODE:
        !          1615:             case MR_SETTEXTALIGN:
        !          1616:             case MR_SETTEXTCOLOR:
        !          1617:             case MR_SETBKCOLOR:
        !          1618:             case MR_OFFSETCLIPRGN:
        !          1619:             case MR_MOVETOEX:
        !          1620:             case MR_SETMETARGN:
        !          1621:             case MR_EXCLUDECLIPRECT:
        !          1622:             case MR_INTERSECTCLIPRECT:
        !          1623:             case MR_SCALEVIEWPORTEXTEX:
        !          1624:             case MR_SCALEWINDOWEXTEX:
        !          1625:             case MR_SAVEDC:
        !          1626:             case MR_RESTOREDC:
        !          1627:             case MR_SETWORLDTRANSFORM:
        !          1628:             case MR_MODIFYWORLDTRANSFORM:
        !          1629:             case MR_SELECTOBJECT:
        !          1630:             case MR_CREATEPEN:
        !          1631:             case MR_CREATEBRUSHINDIRECT:
        !          1632:             case MR_DELETEOBJECT:
        !          1633:             case MR_SELECTPALETTE:
        !          1634:             case MR_CREATEPALETTE:
        !          1635:             case MR_SETPALETTEENTRIES:
        !          1636:             case MR_RESIZEPALETTE:
        !          1637:             case MR_REALIZEPALETTE:
        !          1638:             case MR_SETARCDIRECTION:
        !          1639:             case MR_SETMITERLIMIT:
        !          1640:             case MR_BEGINPATH:
        !          1641:             case MR_ENDPATH:
        !          1642:             case MR_CLOSEFIGURE:
        !          1643:             case MR_SELECTCLIPPATH:
        !          1644:             case MR_ABORTPATH:
        !          1645:             case MR_EXTCREATEFONTINDIRECTW:
        !          1646:             case MR_CREATEMONOBRUSH:
        !          1647:             case MR_CREATEDIBPATTERNBRUSHPT:
        !          1648:             case MR_EXTCREATEPEN:
        !          1649:                 goto PlayRec;
        !          1650:             default:
        !          1651:                 break;
        !          1652:         } //switch
        !          1653: 
        !          1654:         if (iCnt == ((PLAYINFO *) lpData)->iRecord) {
        !          1655: PlayRec:
        !          1656:             bSuccess = PlayEnhMetaFileRecord(hDC, lpHandleTable,
        !          1657:                                              lpEnhMetaRecord, nHandles);
        !          1658:             wsprintf((LPSTR) ach, "%s", rgMetaName[lpEnhMetaRecord->iType]);
        !          1659:             for (i=0; i < lNumDword; i++) {
        !          1660:                 wsprintf((LPSTR) achTmp, "%ld ", lpEnhMetaRecord->dParm[i]);
        !          1661:                 if ((strlen(ach)+strlen(achTmp))/sizeof(char) >= 128)
        !          1662:                     break;
        !          1663:                 strcat(ach, achTmp);
        !          1664:             }
        !          1665:             SetWindowText(ghTextWnd, ach);
        !          1666:         }
        !          1667:     }
        !          1668: 
        !          1669:     if (iCnt == ((PLAYINFO *) lpData)->iRecord) {
        !          1670:         iCnt = 0;
        !          1671:         return FALSE;
        !          1672:     }
        !          1673:     return bSuccess;
        !          1674: }
        !          1675: 
        !          1676: /******************************Public*Routine******************************\
        !          1677: *
        !          1678: * LoadBitmapFile
        !          1679: *
        !          1680: * Effects:  Loads the bitmap from file and return the bitmap
        !          1681: *
        !          1682: * Warnings: pszFileName contains the full path
        !          1683: *
        !          1684: * History:
        !          1685: *  13-May-1992 Petrus Wong           return bitmap handle
        !          1686: *  09-Jan-1992 -by- Petrus Wong
        !          1687: * Wrote it.
        !          1688: \**************************************************************************/
        !          1689: 
        !          1690: HBITMAP hBmpLoadBitmapFile(HDC hDC, PSTR pszFileName)
        !          1691: {
        !          1692:     HANDLE hFile, hMapFile;
        !          1693:     LPVOID pMapFile;
        !          1694:     LPBITMAPINFOHEADER pbmh;
        !          1695:     LPBITMAPINFO  pbmi;
        !          1696:     PBYTE pjTmp;
        !          1697:     ULONG sizBMI;
        !          1698:     HBITMAP hBitmap;
        !          1699: 
        !          1700:     hBitmap = NULL;
        !          1701: 
        !          1702:     if ((hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
        !          1703:             OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL)) == (HANDLE)-1) {
        !          1704:         SetWindowText(ghTextWnd, "Fail in file open");
        !          1705:         goto ErrExit1;
        !          1706:     }
        !          1707: 
        !          1708:     //
        !          1709:     // Create a map file of the opened file
        !          1710:     //
        !          1711:     if ((hMapFile = CreateFileMapping(hFile, NULL,
        !          1712:                              PAGE_READONLY, 0, 0, "MapF")) == (HANDLE)-1) {
        !          1713:         SetWindowText(ghTextWnd, "Fail in creating map file");
        !          1714:         goto ErrExit2;
        !          1715: 
        !          1716:     }
        !          1717: 
        !          1718:     //
        !          1719:     // Map a view of the whole file
        !          1720:     //
        !          1721:     if ((pMapFile = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0)) == NULL) {
        !          1722:         SetWindowText(ghTextWnd, "Fail in mapping view of the Map File object");
        !          1723:         goto ErrExit3;
        !          1724:     }
        !          1725: 
        !          1726:     //
        !          1727:     // First check that it is a bitmap file
        !          1728:     //
        !          1729:     if (*((PWORD)pMapFile) != 0x4d42) {              // 'BM'
        !          1730:         MessageBox(ghwndMain, "This is not a DIB bitmap file!", "Error", MB_OK);
        !          1731:         goto ErrExit3;
        !          1732:     }
        !          1733: 
        !          1734:     pbmh = (LPBITMAPINFOHEADER)((PBYTE)pMapFile + sizeof(BITMAPFILEHEADER));
        !          1735: 
        !          1736:     //
        !          1737:     // Use the size to determine if it is a BitmapCoreHeader or
        !          1738:     // BitmapInfoHeader
        !          1739:     //
        !          1740:     if (pbmh->biSize == sizeof(BITMAPCOREHEADER))
        !          1741:     {
        !          1742:         sizBMI = sizeof(BITMAPCOREHEADER)+sizeof(RGBTRIPLE)*
        !          1743:             ((((LPBITMAPCOREHEADER)pbmh)->bcBitCount == 24) ? 0 : (1 << ((LPBITMAPCOREHEADER)pbmh)->bcBitCount));
        !          1744:     }
        !          1745:     else            // BITMAPINFOHEADER
        !          1746:     {
        !          1747:         sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*
        !          1748:                  ((pbmh->biBitCount == 24) ? 0 : (1 << pbmh->biBitCount));
        !          1749:     }
        !          1750: 
        !          1751:     if ((pbmi = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED,sizBMI)) == NULL) {
        !          1752:         MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK);
        !          1753:         goto ErrExit3;
        !          1754:     }
        !          1755: 
        !          1756:     //
        !          1757:     // Make sure we pass in a DWORD aligned BitmapInfo to CreateDIBitmap
        !          1758:     // Otherwise, exception on the MIPS platform
        !          1759:     // CR!!!  Equivalent to memcpy
        !          1760:     //
        !          1761:     pjTmp = (PBYTE)pbmi;
        !          1762: 
        !          1763:     while(sizBMI--)
        !          1764:     {
        !          1765:         *(((PBYTE)pjTmp)++) = *(((PBYTE)pbmh)++);
        !          1766:     }
        !          1767: 
        !          1768:     pMapFile = (PBYTE)pMapFile + ((BITMAPFILEHEADER *)pMapFile)->bfOffBits;
        !          1769: 
        !          1770:     if ((hBitmap = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)pbmi,
        !          1771:                         CBM_INIT, pMapFile, pbmi, DIB_RGB_COLORS)) == NULL) {
        !          1772:         SetWindowText(ghTextWnd, "Fail in creating DIB bitmap from file!");
        !          1773:         goto ErrExit4;
        !          1774:     }
        !          1775: 
        !          1776: 
        !          1777: 
        !          1778: ErrExit4:
        !          1779:     LocalFree(pbmi);
        !          1780: ErrExit3:
        !          1781:     CloseHandle(hMapFile);
        !          1782: ErrExit2:
        !          1783:     CloseHandle(hFile);
        !          1784: ErrExit1:
        !          1785: 
        !          1786:     return (hBitmap);
        !          1787: 
        !          1788: }
        !          1789: 
        !          1790: /******************************Public*Routine******************************\
        !          1791: *
        !          1792: * bGetBMP
        !          1793: *
        !          1794: * Effects: call common dialog and pass the filename to hBmpLoadBitmapFile
        !          1795: *          return TRUE if successful, FALSE otherwise
        !          1796: *
        !          1797: * Warnings:
        !          1798: *
        !          1799: * History:
        !          1800: *  13-May-1992 -by- Petrus Wong
        !          1801: * Wrote it.
        !          1802: \**************************************************************************/
        !          1803: 
        !          1804: BOOL bGetBMP(HWND hwnd, BOOL bMask) {
        !          1805:     OPENFILENAME    ofn;
        !          1806:     char            szFile[256], szFileTitle[256];
        !          1807:     static char     *szFilter;
        !          1808:     BOOL            bSuccess;
        !          1809:     HDC             hDC;
        !          1810: 
        !          1811:     bSuccess = FALSE;
        !          1812: 
        !          1813:     szFilter =
        !          1814:       "DIB files (*.bmp)\0*.bmp\0RLE files (*.rle)\0*.rle\0\0";
        !          1815: 
        !          1816:     strcpy(szFile, "*.bmp\0");
        !          1817:     ofn.lStructSize = sizeof(OPENFILENAME);
        !          1818:     ofn.hwndOwner = hwnd;
        !          1819:     ofn.lpstrFilter = szFilter;
        !          1820:     ofn.lpstrCustomFilter = (LPSTR) NULL;
        !          1821:     ofn.nMaxCustFilter = 0L;
        !          1822:     ofn.nFilterIndex = 1;
        !          1823:     ofn.lpstrFile = szFile;
        !          1824:     ofn.nMaxFile = sizeof(szFile);
        !          1825:     ofn.lpstrFileTitle = szFileTitle;
        !          1826:     ofn.nMaxFileTitle = sizeof(szFileTitle);
        !          1827:     ofn.lpstrInitialDir = NULL;
        !          1828:     ofn.lpstrTitle = (bMask ? "Load Mask" : "Load Bitmap");
        !          1829:     ofn.Flags = 0L;
        !          1830:     ofn.nFileOffset = 0;
        !          1831:     ofn.nFileExtension = 0;
        !          1832:     ofn.lpstrDefExt = "BMP";
        !          1833: 
        !          1834:     if (!GetOpenFileName(&ofn))
        !          1835:         return 0L;
        !          1836: 
        !          1837:     hDC = GetDC(ghwndDrawSurf);
        !          1838:     if (bMask) {
        !          1839:         ghBmpMask = hBmpLoadBitmapFile(hDC, szFile);
        !          1840:         if (ghBmpMask != NULL)
        !          1841:             bSuccess = TRUE;
        !          1842:     } else {
        !          1843:         ghBmp = hBmpLoadBitmapFile(hDC, szFile);
        !          1844:         if (ghBmp != NULL)
        !          1845:             bSuccess = TRUE;
        !          1846:     }
        !          1847:     ReleaseDC(ghwndDrawSurf, hDC);
        !          1848: 
        !          1849:     return bSuccess;
        !          1850: }
        !          1851: 
        !          1852: /******************************Public*Routine******************************\
        !          1853: *
        !          1854: * bHitTest
        !          1855: *
        !          1856: * Effects:  Enumerates metafile records
        !          1857: *           Calling bDoHitTest to process each record found.
        !          1858: *               The mouse position is passed to the bDoHitTest
        !          1859: *
        !          1860: * Warnings:
        !          1861: *
        !          1862: * History:
        !          1863: *  20-May-1992 -by- Petrus Wong
        !          1864: * Wrote it.
        !          1865: \**************************************************************************/
        !          1866: 
        !          1867: BOOL bHitTest(HDC hDC, INT x, INT y) {
        !          1868:     BOOL          bSuccess;
        !          1869:     ENHMETAHEADER EnhMetaHdr;
        !          1870:     //POINT         point;
        !          1871:     //!!!RECT          rcClientDS;
        !          1872:     HTDATA        htData;
        !          1873: 
        !          1874:     bSuccess = TRUE;
        !          1875: 
        !          1876:     if (ghMetaf == 0)
        !          1877:         return 0L;
        !          1878: 
        !          1879:     GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr);
        !          1880:     //!!!GetClientRect(ghwndDrawSurf, &rcClientDS);
        !          1881:     htData.point.x = x;
        !          1882:     htData.point.y = y;
        !          1883:     htData.iRecord = EnhMetaHdr.nRecords;
        !          1884:     EnumEnhMetaFile(hDC, ghMetaf, (PROC)bDoHitTest, (LPVOID) &htData, (LPRECT)&EnhMetaHdr.rclBounds);
        !          1885:     //!!!EnumEnhMetaFile(hDC, ghMetaf, (PROC)bDoHitTest, (LPVOID) &point, (LPRECT)&rcClientDS);
        !          1886: 
        !          1887:     return bSuccess;
        !          1888: }
        !          1889: 
        !          1890: /******************************Public*Routine******************************\
        !          1891: *
        !          1892: * bDoHitTest
        !          1893: *
        !          1894: * Effects:      Play all records related to transformation
        !          1895: *               Remember new mouse position if the record is a MoveTo
        !          1896: *               Convert rectangle, ellipse, lineto and bezier to path
        !          1897: *               Widen the path and convert it to region.
        !          1898: *               Test if the mouse position is inside the region.
        !          1899: *
        !          1900: * Warnings:     Only handle rectangle, ellipse, line and polybezier
        !          1901: *
        !          1902: * History:
        !          1903: *  20-May-1992 -by- Petrus Wong
        !          1904: * Wrote it.
        !          1905: \**************************************************************************/
        !          1906: 
        !          1907: BOOL APIENTRY bDoHitTest(HDC hDC, LPHANDLETABLE lpHandleTable,
        !          1908:                                   LPENHMETARECORD lpEnhMetaRecord,
        !          1909:                                   UINT nHandles,
        !          1910:                                   LPVOID lpData) {
        !          1911:     BOOL            bSuccess;
        !          1912:     char            ach[128];
        !          1913:     char            achTmp[128];
        !          1914:     POINT           PtOrg;
        !          1915:     LONG            lNumDword;
        !          1916:     XFORM           xfSave;
        !          1917:     SIZE            SizeWndEx, SizeViewEx;
        !          1918:     POINT           ptWndOrgin, ptViewOrgin;
        !          1919:     int             i, iMode;
        !          1920:     HRGN            hRgn;
        !          1921:     PPOINT          pPt, pPtTmp;
        !          1922:     static HGDIOBJ  hObjOld=NULL;
        !          1923:     static LONG     lCurX=0;
        !          1924:     static LONG     lCurY=0;
        !          1925:     static BOOL     bXform=FALSE;
        !          1926:     static int      iCnt=0;
        !          1927: 
        !          1928:     iCnt++;
        !          1929: 
        !          1930:     //
        !          1931:     // select a wide pen for widen path later on
        !          1932:     //
        !          1933:     hObjOld = SelectObject(hDC, ghpnWide);
        !          1934: 
        !          1935:     //
        !          1936:     // save the mouse hit position, this was passed in as a POINT structure
        !          1937:     //
        !          1938:     PtOrg.x = (((HTDATA *)lpData)->point).x;
        !          1939:     PtOrg.y = (((HTDATA *)lpData)->point).y;
        !          1940: 
        !          1941:     //
        !          1942:     // save the number of parameters for the GDI fcn concerned in DWORD.
        !          1943:     // This is the total size of metafile record in question less the
        !          1944:     // size of the GDI function
        !          1945:     //
        !          1946:     lNumDword = (lpEnhMetaRecord->nSize-8) / 4;
        !          1947: 
        !          1948:     switch (lpEnhMetaRecord->iType) {
        !          1949:     case MR_SETWINDOWEXTEX:
        !          1950:     case MR_SETWINDOWORGEX:
        !          1951:     case MR_SETVIEWPORTEXTEX:
        !          1952:     case MR_SETVIEWPORTORGEX:
        !          1953:     case MR_SETMAPMODE:
        !          1954:     case MR_SCALEVIEWPORTEXTEX:
        !          1955:     case MR_SCALEWINDOWEXTEX:
        !          1956:     case MR_SETMETARGN:
        !          1957:     case MR_SAVEDC:
        !          1958:     case MR_RESTOREDC:
        !          1959:     case MR_SETWORLDTRANSFORM:
        !          1960:     case MR_MODIFYWORLDTRANSFORM: {
        !          1961:         //
        !          1962:         // play all records related to transformation
        !          1963:         //
        !          1964:         PlayEnhMetaFileRecord(hDC, lpHandleTable,
        !          1965:                                    lpEnhMetaRecord, nHandles);
        !          1966:         bXform = TRUE;
        !          1967:         return TRUE;
        !          1968:     }
        !          1969:     //
        !          1970:     // convert the following GDI calls to path for hit testing
        !          1971:     //
        !          1972:     case MR_RECTANGLE: {
        !          1973:         BeginPath(hDC);
        !          1974:         Rectangle(hDC, lpEnhMetaRecord->dParm[0], lpEnhMetaRecord->dParm[1],
        !          1975:                        lpEnhMetaRecord->dParm[2], lpEnhMetaRecord->dParm[3]);
        !          1976:         EndPath(hDC);
        !          1977:         break;
        !          1978:     }
        !          1979:     case MR_ELLIPSE: {
        !          1980:         BeginPath(hDC);
        !          1981:         Ellipse(hDC, lpEnhMetaRecord->dParm[0], lpEnhMetaRecord->dParm[1],
        !          1982:                      lpEnhMetaRecord->dParm[2], lpEnhMetaRecord->dParm[3]);
        !          1983:         EndPath(hDC);
        !          1984:         break;
        !          1985:     }
        !          1986:     case MR_MOVETOEX: {
        !          1987:         //
        !          1988:         // Remember our current position
        !          1989:         //
        !          1990:         lCurX = lpEnhMetaRecord->dParm[0];
        !          1991:         lCurY = lpEnhMetaRecord->dParm[1];
        !          1992:         return TRUE;
        !          1993:     }
        !          1994:     case MR_LINETO: {
        !          1995:         BeginPath(hDC);
        !          1996:         MoveToEx(hDC, lCurX, lCurY, NULL);
        !          1997:         LineTo(hDC, lpEnhMetaRecord->dParm[0], lpEnhMetaRecord->dParm[1]);
        !          1998:         EndPath(hDC);
        !          1999:         break;
        !          2000:     }
        !          2001:     case MR_POLYBEZIER16: {
        !          2002:         int         i;
        !          2003:         LONG        lSize;
        !          2004:         LONG        lPtCnt;
        !          2005: 
        !          2006:         lPtCnt = lpEnhMetaRecord->dParm[4];
        !          2007:         lSize = lPtCnt * sizeof(POINTL);
        !          2008: 
        !          2009:         if ((pPt = (PPOINT) LocalAlloc(LMEM_FIXED, lSize)) == NULL) {
        !          2010:             SetWindowText(ghTextWnd, "ERROR: Failed in Memory Allocation: NO HIT");
        !          2011:             return TRUE;
        !          2012:         }
        !          2013: 
        !          2014:         pPtTmp = pPt;
        !          2015: 
        !          2016:         for (i=0; i < (INT) lPtCnt; i++, pPtTmp++) {
        !          2017:             pPtTmp->x = (LONG)(LOWORD(lpEnhMetaRecord->dParm[i+5]));
        !          2018:             pPtTmp->y = (LONG)(HIWORD(lpEnhMetaRecord->dParm[i+5]));
        !          2019:         }
        !          2020: 
        !          2021:         BeginPath(hDC);
        !          2022:         PolyBezier(hDC, (LPPOINT)pPt, (DWORD) lPtCnt);
        !          2023:         EndPath(hDC);
        !          2024:         LocalFree(pPt);
        !          2025:         break;
        !          2026:     }
        !          2027:     default:
        !          2028:         return TRUE;
        !          2029:     }   //switch
        !          2030: 
        !          2031:     if (bXform) {
        !          2032:         //
        !          2033:         // Set World transform to identity temporarily so that pen width
        !          2034:         // is not affected by world to page transformation
        !          2035:         //
        !          2036:         GetWorldTransform(hDC, &xfSave);
        !          2037:         ModifyWorldTransform(hDC, NULL, MWT_IDENTITY);
        !          2038: 
        !          2039:         //
        !          2040:         // Set Page transform to identity temporarily so that pen width
        !          2041:         // is not affected by page to device transformation
        !          2042:         //
        !          2043:         iMode = GetMapMode(hDC);
        !          2044: 
        !          2045:         if ((iMode == MM_ISOTROPIC) || (iMode == MM_ANISOTROPIC)) {
        !          2046:             GetWindowOrgEx(hDC, &ptWndOrgin);
        !          2047:             GetWindowExtEx(hDC, &SizeWndEx);
        !          2048:             GetViewportExtEx(hDC, &SizeViewEx);
        !          2049:             GetViewportOrgEx(hDC, &ptViewOrgin);
        !          2050:         }
        !          2051: 
        !          2052:         SetMapMode(hDC, MM_TEXT);
        !          2053:     }
        !          2054: 
        !          2055:     WidenPath(hDC);
        !          2056: 
        !          2057:     hRgn = PathToRegion(hDC);
        !          2058: 
        !          2059:     if (hRgn == 0) {
        !          2060:         SetWindowText(ghTextWnd, "ERROR: Null Region: NO HIT");
        !          2061:         DeleteObject(hRgn);
        !          2062:         return TRUE;
        !          2063:     }
        !          2064:     //DPtoLP(hDC, &PtOrg, 1);
        !          2065:     //SetPixel(hDC, PtOrg.x, PtOrg.y, RGB(0, 255, 0));
        !          2066:     //
        !          2067:     // test if mouse hit position is in region
        !          2068:     //
        !          2069:     bSuccess = PtInRegion(hRgn, PtOrg.x, PtOrg.y);
        !          2070:     //Temporily comment this out to avoid a bug in 265
        !          2071:     //FillRgn(hDC, hRgn, ghbrRed);
        !          2072:     DeleteObject(hRgn);
        !          2073:     //
        !          2074:     // Set transform back.
        !          2075:     //
        !          2076:     if (bXform) {
        !          2077:         SetWorldTransform(hDC, &xfSave);
        !          2078:         SetMapMode(hDC, iMode);
        !          2079: 
        !          2080:         if ((iMode == MM_ISOTROPIC) || (iMode == MM_ANISOTROPIC)) {
        !          2081:             SetWindowOrgEx(hDC, ptWndOrgin.x, ptWndOrgin.y, NULL);
        !          2082:             SetWindowExtEx(hDC, SizeWndEx.cx, SizeWndEx.cy, NULL);
        !          2083:             SetViewportExtEx(hDC, SizeViewEx.cx, SizeViewEx.cy, NULL);
        !          2084:             SetViewportOrgEx(hDC, ptViewOrgin.x, ptViewOrgin.y, NULL);
        !          2085:         }
        !          2086:     }
        !          2087: 
        !          2088:     if (bSuccess) {
        !          2089:         Beep(440, 500);
        !          2090:         //
        !          2091:         // Reporting the metafile record number.  Then reset counter.
        !          2092:         //
        !          2093:         SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, iCnt, FALSE);
        !          2094:         iCnt=0;
        !          2095:         wsprintf((LPSTR) ach, "HIT %s", rgMetaName[lpEnhMetaRecord->iType]);
        !          2096: 
        !          2097:         for (i=0; i < lNumDword; i++) {
        !          2098:             wsprintf((LPSTR) achTmp, "%ld ", lpEnhMetaRecord->dParm[i]);
        !          2099:             if ((strlen(ach)+strlen(achTmp))/sizeof(char) >= 128)
        !          2100:                 break;
        !          2101:             strcat(ach, achTmp);
        !          2102:         }
        !          2103: 
        !          2104:         SetWindowText(ghTextWnd, ach);
        !          2105:         SelectObject(hDC, hObjOld);
        !          2106:         bXform = FALSE;
        !          2107:         return FALSE;
        !          2108:     }
        !          2109:     SetWindowText(ghTextWnd, "NO HIT");
        !          2110:     if (iCnt >= ((HTDATA *)lpData)->iRecord)
        !          2111:         iCnt = 0;
        !          2112:     return TRUE;
        !          2113: 
        !          2114:     UNREFERENCED_PARAMETER(lpHandleTable);
        !          2115:     UNREFERENCED_PARAMETER(nHandles);
        !          2116: 
        !          2117: }
        !          2118: 
        !          2119: /******************************Public*Routine******************************\
        !          2120: *
        !          2121: * bChooseNewFont
        !          2122: *
        !          2123: * Effects:
        !          2124: *
        !          2125: * Warnings:
        !          2126: *
        !          2127: * History:
        !          2128: *  20-May-1992 -by- Petrus Wong
        !          2129: * Wrote it.
        !          2130: \**************************************************************************/
        !          2131: 
        !          2132: BOOL bChooseNewFont(HWND hwnd, PLOGFONT plf, COLORREF *pClrRef) {
        !          2133:    HDC          hDC;
        !          2134:    CHOOSEFONT   chf;
        !          2135: 
        !          2136:    hDC = GetDC( hwnd );
        !          2137:    chf.hDC = CreateCompatibleDC( hDC );
        !          2138:    ReleaseDC( hwnd, hDC );
        !          2139:    chf.lStructSize = sizeof(CHOOSEFONT);
        !          2140:    chf.hwndOwner = hwnd;
        !          2141:    chf.lpLogFont = plf;
        !          2142:    chf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT;
        !          2143:    chf.rgbColors = *pClrRef;
        !          2144:    chf.lCustData = 0;
        !          2145:    chf.hInstance = (HANDLE)NULL;
        !          2146:    chf.lpszStyle = (LPSTR)NULL;
        !          2147:    chf.nFontType = SCREEN_FONTTYPE;
        !          2148:    chf.nSizeMin = 0;
        !          2149:    chf.nSizeMax = 0;
        !          2150:    chf.Flags = CF_SCREENFONTS | CF_EFFECTS;
        !          2151:    chf.lpfnHook = (FARPROC)NULL;
        !          2152:    chf.lpTemplateName = (LPSTR)NULL;
        !          2153: 
        !          2154:    if (ChooseFont( &chf ) == FALSE ) {
        !          2155:         DeleteDC( hDC );
        !          2156:        return FALSE;
        !          2157:    }
        !          2158: 
        !          2159:    *pClrRef = chf.rgbColors;
        !          2160: 
        !          2161:    DeleteDC( hDC );
        !          2162:    return (TRUE);
        !          2163: }
        !          2164: 
        !          2165: /******************************Public*Routine******************************\
        !          2166: *
        !          2167: * bChooseNewColor
        !          2168: *
        !          2169: * Effects:  Returns TRUE if successful; lpdwRGB points the color selected.
        !          2170: *           Otherwise, FALSE.
        !          2171: *
        !          2172: * Warnings:
        !          2173: *
        !          2174: * History:
        !          2175: *  21-May-1992 -by- Petrus Wong
        !          2176: * Wrote it.
        !          2177: \**************************************************************************/
        !          2178: 
        !          2179: BOOL bChooseNewColor(HWND hwnd, LPDWORD lpdwRGB) {
        !          2180:     static DWORD argbCust[16] = {
        !          2181:         RGB(255, 255, 255), RGB(255, 255, 255),
        !          2182:         RGB(255, 255, 255), RGB(255, 255, 255),
        !          2183:         RGB(255, 255, 255), RGB(255, 255, 255),
        !          2184:         RGB(255, 255, 255), RGB(255, 255, 255),
        !          2185:         RGB(255, 255, 255), RGB(255, 255, 255),
        !          2186:         RGB(255, 255, 255), RGB(255, 255, 255),
        !          2187:         RGB(255, 255, 255), RGB(255, 255, 255),
        !          2188:         RGB(255, 255, 255), RGB(255, 255, 255)
        !          2189:     };
        !          2190:     CHOOSECOLOR cc;
        !          2191:     BOOL bResult;
        !          2192: 
        !          2193:     cc.lStructSize = sizeof(CHOOSECOLOR);
        !          2194:     cc.hwndOwner = hwnd;
        !          2195:     cc.hInstance = ghModule;
        !          2196:     cc.rgbResult = *lpdwRGB;
        !          2197:     cc.lpCustColors = argbCust;
        !          2198:     cc.Flags = CC_RGBINIT | CC_SHOWHELP;
        !          2199:     cc.lCustData = 0;
        !          2200:     cc.lpfnHook = NULL;
        !          2201:     cc.lpTemplateName = NULL;
        !          2202: 
        !          2203:     bResult = ChooseColor(&cc);
        !          2204: 
        !          2205:     if (bResult) {
        !          2206:         *lpdwRGB = cc.rgbResult;
        !          2207:         return TRUE;
        !          2208:     }
        !          2209: 
        !          2210:     return FALSE;
        !          2211: }
        !          2212: 
        !          2213: 
        !          2214: /******************************Public*Routine******************************\
        !          2215: *
        !          2216: * hBrCreateBrush
        !          2217: *
        !          2218: * Effects: Creates a brush with the specified RGB
        !          2219: *
        !          2220: * Warnings:
        !          2221: *
        !          2222: * History:
        !          2223: *  04-Mar-1992 -by- Petrus Wong
        !          2224: * Wrote it.
        !          2225: \**************************************************************************/
        !          2226: 
        !          2227: HBRUSH hBrCreateBrush(HDC hDC, DWORD dwRGB)
        !          2228: {
        !          2229:     HDC hdcMem;
        !          2230:     HBRUSH hbr;
        !          2231:     HBRUSH hbrOld;
        !          2232:     HBITMAP hbmPat;
        !          2233:     HBITMAP hbmOld;
        !          2234: 
        !          2235:     hbr = CreateSolidBrush(dwRGB);
        !          2236:     hdcMem = CreateCompatibleDC(hDC);
        !          2237: 
        !          2238:     //
        !          2239:     // Minimum size for a bitmap to be used in a fill pattern is 8x8
        !          2240:     //
        !          2241:     hbmPat = CreateCompatibleBitmap(hDC, 8, 8);
        !          2242: 
        !          2243:     hbmOld = SelectObject(hdcMem, hbmPat);
        !          2244:     hbrOld = SelectObject(hdcMem, hbr);
        !          2245:     PatBlt(hdcMem, 0, 0, 8, 8, PATCOPY);
        !          2246: 
        !          2247:     //
        !          2248:     // Deselect hbmPat and hbr
        !          2249:     //
        !          2250:     SelectObject(hdcMem, hbmOld);
        !          2251:     SelectObject(hdcMem, hbrOld);
        !          2252: 
        !          2253:     DeleteDC(hdcMem);
        !          2254:     DeleteObject(hbr);
        !          2255: 
        !          2256:     hbr = CreatePatternBrush(hbmPat);
        !          2257: 
        !          2258:     DeleteObject(hbmPat);
        !          2259: 
        !          2260:     return hbr;
        !          2261: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.