--- mstools/samples/mfedit/mfedit.c 2018/08/09 18:20:54 1.1 +++ mstools/samples/mfedit/mfedit.c 2018/08/09 18:24:08 1.1.1.3 @@ -7,7 +7,7 @@ * Created: 28-May-1992 14:24:00 * Author: Petrus Wong * -* Copyright (c) 1990 Microsoft Corporation +* Copyright (c) 1992 Microsoft Corporation * * The Enhanced Metafile Editor serves to demonstrate the enhanced metafile * APIs in Windows NT. @@ -35,17 +35,18 @@ #include #include #include +#include +#include // // Forward declarations. // BOOL InitializeApp (void); -LONG MainWndProc (HWND, UINT, DWORD, LONG); -LONG DrawSurfWndProc (HWND, UINT, DWORD, LONG); -LONG MDIWndProc (HWND, UINT, DWORD, LONG); -LONG About (HWND, UINT, DWORD, LONG); -LONG TextWndProc (HWND, UINT, DWORD, LONG); -LONG CtrlPanelDlgProc(HWND, UINT, DWORD, LONG); +LONG APIENTRY MainWndProc (HWND, UINT, DWORD, LONG); +LONG APIENTRY DrawSurfWndProc (HWND, UINT, DWORD, LONG); +BOOL CALLBACK About (HWND, UINT, DWORD, LONG); +LONG APIENTRY TextWndProc (HWND, UINT, DWORD, LONG); +LONG APIENTRY CtrlPanelDlgProc(HWND, UINT, DWORD, LONG); BOOL bDrawStuff (HDC, INT, INT, INT, INT, BOOL, BOOL, BOOL, LPSTR); HENHMETAFILE hemfLoadMetafile(HWND); HDC hDCRecordMetafileAs(HWND, LPSTR); @@ -56,7 +57,13 @@ HBITMAP hBmpLoadBitmapFile(HDC, PSTR); BOOL bGetBMP(HWND, BOOL); BOOL bChooseNewFont(HWND, PLOGFONT, COLORREF * ); BOOL bChooseNewColor(HWND, LPDWORD); +BOOL bPrintMf(PPRTDATA); HBRUSH hBrCreateBrush(HDC, DWORD); +BOOL bSelectDIBPal(HDC, LPBITMAPINFO, BOOL); +BOOL bFreeDibFile(PDIBDATA); +BOOL bPlgBlt(HDC, LPPOINT); +HPALETTE CopyPalette(HPALETTE hPalSrc); +int CALLBACK iTT(LPLOGFONT, LPTEXTMETRIC, DWORD, LPARAM); /***************************************************************************\ * WinMain @@ -64,11 +71,15 @@ HBRUSH hBrCreateBrush(HDC, DWORD); * History: * 11-Feb-1992 Petrus Wong \***************************************************************************/ -int WinMain( - HANDLE hInstance, - HANDLE hPrevInstance, - LPSTR lpCmdLine, - int nShowCmd) +int WINAPI WinMain( +#if 0 + HANDLE hInstance, + HANDLE hPrevInstance, +#endif + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nShowCmd) { MSG msg; HANDLE hAccel; @@ -112,13 +123,14 @@ BOOL InitializeApp(void) { WNDCLASS wc; int index; + HDC hDC; wc.style = CS_DBLCLKS; wc.lpfnWndProc = (WNDPROC)MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = sizeof(DWORD); wc.hInstance = ghModule; - wc.hIcon = LoadIcon(ghModule, MAKEINTRESOURCE(APPICON)); + wc.hIcon = LoadIcon(ghModule, MAKEINTRESOURCE(APP_ICON)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); wc.lpszMenuName = "MainMenu"; @@ -174,9 +186,30 @@ BOOL InitializeApp(void) return FALSE; SetWindowLong(ghwndMain, GWL_USERDATA, 0L); + ghwndNext = SetClipboardViewer(ghwndMain); + + if (gbFit2Wnd) + CheckMenuItem(hMenu, MM_FIT2WND, MF_CHECKED); + else + CheckMenuItem(hMenu, MM_FIT2WND, MF_UNCHECKED); + + if (gbImport3X) + CheckMenuItem(hMenu, MM_IMPORT_3X, MF_CHECKED); + else + CheckMenuItem(hMenu, MM_IMPORT_3X, MF_UNCHECKED); + + if (gbExport3X) + CheckMenuItem(hMenu, MM_EXPORT_3X, MF_CHECKED); + else + CheckMenuItem(hMenu, MM_EXPORT_3X, MF_UNCHECKED); SetFocus(ghwndMain); /* set initial focus */ + gDib.ulFiles = gDib.ulFrames = 0; + hDC = GetDC(NULL); + ghHT = CreateHalftonePalette(hDC); + ReleaseDC(NULL, hDC); + return TRUE; } @@ -190,7 +223,7 @@ BOOL InitializeApp(void) * 09-09-91 Petrus Wong Created. \***************************************************************************/ -long MainWndProc( +long APIENTRY MainWndProc( HWND hwnd, UINT message, DWORD wParam, @@ -199,6 +232,7 @@ long MainWndProc( static int iMetafCnt=0; static char szFilename[256] = "c:\\metaf"; static BOOL bReset=FALSE; + static char szLoadedMetaf[256] = " "; switch (message) { @@ -231,6 +265,16 @@ long MainWndProc( ghpnWide = CreatePen(PS_SOLID, 5, RGB(0, 0, 0)); return 0L; } + case WM_DRAWCLIPBOARD: + if ((IsClipboardFormatAvailable(CF_METAFILEPICT)) || + (IsClipboardFormatAvailable(CF_ENHMETAFILE)) ) + EnableMenuItem(hMenu, MM_PASTE, MF_ENABLED); + else + EnableMenuItem(hMenu, MM_PASTE, MF_GRAYED); + + if (ghwndNext) + SendMessage(ghwndNext, message, wParam, lParam); + return 0L; case WM_SIZE: { RECT rc; @@ -260,7 +304,8 @@ long MainWndProc( 0, lcyCtrlPanel, LOWORD(lParam), // cx of hwnd lcyDrawSurf, TRUE); - break; + //break; + return DefWindowProc(hwnd, message, wParam, lParam); } case WM_DESTROY: { @@ -272,6 +317,10 @@ long MainWndProc( DeleteObject(ghpnCur); DeleteObject(ghbrAppBkgd); DeleteObject(ghpnWide); + if (ghHT) + DeleteObject(ghHT); + ChangeClipboardChain(ghwndMain, ghwndNext); + bFreeDibFile(&gDib); PostQuitMessage(0); return 0L; } @@ -279,6 +328,7 @@ long MainWndProc( case WM_COMMAND: { static int iPlus=0; + switch (LOWORD(wParam)) { case DID_ZERO: case DID_ONE: @@ -292,7 +342,7 @@ long MainWndProc( case DID_NINE: { HDC hDCDrawSurf; ENHMETAHEADER EnhMetaHdr; - //RECT rcClientDS; + RECT rcClientDS; int iRecord; PLAYINFO PlayInfo; @@ -308,15 +358,19 @@ long MainWndProc( if ((EnhMetaHdr.nRecords > 1) && (iRecord > 0) && (iRecord <= (INT) EnhMetaHdr.nRecords)) { - //!!!GetClientRect(ghwndDrawSurf, &rcClientDS); hDCDrawSurf = GetDC(ghwndDrawSurf); - //!!!EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, &rcClientDS); - EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds); + if (gbFit2Wnd) { + GetClientRect(ghwndDrawSurf, &rcClientDS); + EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, &rcClientDS); + } else { + EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds); + } // // Enabling the user to record a metafile record selectively // - if ((gbRecording) && (ghDCMetaf != NULL)) - EnumEnhMetaFile(ghDCMetaf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds); + if ((gbRecording) && (ghDCMetaf != NULL)) { + EnumEnhMetaFile(ghDCMetaf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds); + } ReleaseDC(ghwndDrawSurf, hDCDrawSurf); } return 0L; @@ -329,14 +383,444 @@ long MainWndProc( SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, iPlus, FALSE); return 0L; } - case MM_PRINT: case MM_PAGESETUP: - case MM_PRINTSETUP: case MM_CUT: - case MM_COPY: - case MM_PASTE: - case MM_DEL: return 0L; + + case MM_COPY: { + + if ((ghMetaf == 0) && (ghmf == 0)) { + SetWindowText(ghTextWnd, "No Metafile for copying"); + return 0L; + } + + OpenClipboard(ghwndMain); + EmptyClipboard(); + + if (gbExport3X) + { + HGLOBAL hmem; + LPMETAFILEPICT lpmfp; + RECT rcClientDS; + DWORD x, y, mm; + HDC hDCDrawSurf; + LPBYTE pjData; + UINT uiSize; + + hDCDrawSurf = GetDC(ghwndDrawSurf); + + if (ghmf == 0) { + SetWindowText(ghTextWnd, "Converting Enhanced Metafile to 3X format"); + + if (!(uiSize = GetWinMetaFileBits(ghMetaf, 0, NULL, MM_ANISOTROPIC, hDCDrawSurf))) { + MessageBox(ghwndMain, "Fail in 1st GetWinMetaFileBits!", "Error", MB_OK); + goto COPY_3X_EXIT; + } + + if ((pjData = (LPBYTE) LocalAlloc(LMEM_FIXED, uiSize)) == NULL) { + MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK); + goto COPY_3X_EXIT; + } + + if (!(uiSize = GetWinMetaFileBits(ghMetaf, uiSize, pjData, MM_ANISOTROPIC, hDCDrawSurf))) { + MessageBox(ghwndMain, "Fail in 2nd GetWinMetaFileBits!", "Error", MB_OK); + LocalFree(pjData); + goto COPY_3X_EXIT; + } + + ghmf = SetMetaFileBitsEx(uiSize, (LPBYTE) pjData); + LocalFree(pjData); + } + + if ((hmem = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, + sizeof(METAFILEPICT))) == NULL) { + + SetWindowText(ghTextWnd, "Failed in allocating memory"); + goto COPY_3X_EXIT; + + } + + lpmfp = (LPMETAFILEPICT)GlobalLock(hmem); + lpmfp->mm = mm = MM_ANISOTROPIC; + + GetClientRect(ghwndDrawSurf, &rcClientDS); + x = rcClientDS.right - rcClientDS.left; + x *= 2540; + x /= GetDeviceCaps(hDCDrawSurf, LOGPIXELSX); + lpmfp->xExt = x; // ie. in 0.01mm + + y = rcClientDS.bottom - rcClientDS.top; + y *= 2540; + y /= GetDeviceCaps(hDCDrawSurf, LOGPIXELSY); + lpmfp->yExt = y; // ie. in 0.01mm + + lpmfp->hMF = CopyMetaFile(ghmf, NULL); + + GlobalUnlock(hmem); + SetWindowText(ghTextWnd, "Copying 3X Metafile to Clipboard"); + SetClipboardData(CF_METAFILEPICT, hmem); + +COPY_3X_EXIT: + ReleaseDC(ghwndDrawSurf, hDCDrawSurf); + goto COPY_EXIT; + + } + + // + // gbExport3X == FALSE + // + if (ghMetaf == 0) // requires conversion + { + UINT uiSize; + LPVOID pvData; + HDC hDCDrawSurf; + + SetWindowText(ghTextWnd, "Converting 3X Metafile to Enhanced Metafile format"); + if (!(uiSize = GetMetaFileBitsEx(ghmf, 0, NULL))) { + MessageBox(ghwndMain, "Fail in 1st GetMetaFileBitsEx!", "Error", MB_OK); + SetWindowText(ghTextWnd, "Conversion Failed"); + goto COPY_EXIT; + } + + if ((pvData = (LPVOID) LocalAlloc(LMEM_FIXED, uiSize)) == NULL) { + MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK); + SetWindowText(ghTextWnd, "Conversion Failed"); + goto COPY_EXIT; + } + + if (!(uiSize = GetMetaFileBitsEx(ghmf, uiSize, pvData))) { + MessageBox(ghwndMain, "Fail in 2nd GetMetaFileBitsEx!", "Error", MB_OK); + goto COPY_ENH_EXIT; + } + + hDCDrawSurf = GetDC(ghwndDrawSurf); + + // !!! provide the correct picture extents in the METAFILEPICT structure + // where possible + ghMetaf = SetWinMetaFileBits(uiSize, (LPBYTE)pvData, hDCDrawSurf, NULL); + +COPY_ENH_EXIT: + LocalFree(pvData); + ReleaseDC(ghwndDrawSurf ,hDCDrawSurf); + + if (ghMetaf == 0) { + SetWindowText(ghTextWnd, "Conversion Failed"); + goto COPY_EXIT; + } + + } + + // + // No Conversion required + // + { + + HENHMETAFILE hEmfTmp; + + hEmfTmp = CopyEnhMetaFile(ghMetaf, NULL); + + if (hEmfTmp) { + SetWindowText(ghTextWnd, "Copying Enhanced Metafile to Clipboard"); + SetClipboardData(CF_ENHMETAFILE, hEmfTmp); + DeleteEnhMetaFile(hEmfTmp); + } + + } + +COPY_EXIT: + + CloseClipboard(); + return 0L; + } + + case MM_PASTE: { + OpenClipboard(ghwndMain); + + if (gbImport3X) + { + HANDLE hmem; + DWORD dwXSugExt, dwYSugExt, dwMM; + HDC hDCDrawSurf; + RECT rc; + INT iSavedDC; + + + hmem = GetClipboardData(CF_METAFILEPICT); + + if (hmem) + { + LPMETAFILEPICT lpmfp; + + SetWindowText(ghTextWnd, "Pasting 3X Metafile"); + lpmfp = (LPMETAFILEPICT)GlobalLock(hmem); + ghmf = lpmfp->hMF; + dwMM = lpmfp->mm; + dwXSugExt = lpmfp->xExt; // in 0.01 mm + dwYSugExt = lpmfp->yExt; + GlobalUnlock(hmem); + + hDCDrawSurf = GetDC(ghwndDrawSurf); + + iSavedDC = SaveDC(hDCDrawSurf); + + GetClientRect(ghwndDrawSurf, &rc); + + SetMapMode(hDCDrawSurf, dwMM); + if ((dwXSugExt > 0 )&& (dwYSugExt > 0)) + { // suggested width & height of image + DWORD x; + DWORD y; + + // no. of pixels in x and y + x = dwXSugExt; + x *= GetDeviceCaps(hDCDrawSurf,LOGPIXELSX); + x /= 2540; + + y = dwYSugExt; + y *= GetDeviceCaps(hDCDrawSurf,LOGPIXELSY); + y /= 2540; + + SetWindowExtEx(hDCDrawSurf, x, y, NULL); + + if (gbFit2Wnd) + SetViewportExtEx(hDCDrawSurf, rc.right, rc.bottom, NULL); + else + SetViewportExtEx(hDCDrawSurf, x, y, NULL); + + } else { + SetWindowText(ghTextWnd, "No information on 3X Metafile's extensions"); + SetWindowExtEx(hDCDrawSurf, rc.right, rc.bottom, NULL); + SetViewportExtEx(hDCDrawSurf, rc.right, rc.bottom, NULL); + } + + SetViewportOrgEx(hDCDrawSurf, 0, 0, NULL); + SetWindowOrgEx(hDCDrawSurf, 0, 0, NULL); + + SetBoundsRect(hDCDrawSurf, NULL, DCB_ENABLE | DCB_SET); + PlayMetaFile(hDCDrawSurf, ghmf); + { + UINT uiRC; + char text[128]; + + wsprintf(text, "dwMM = %d\n", dwMM); + OutputDebugString(text); + wsprintf(text, "dwXSugExt = %d\n", dwXSugExt); + OutputDebugString(text); + wsprintf(text, "dwYSugExt = %d\n", dwYSugExt); + OutputDebugString(text); + + uiRC = GetBoundsRect(hDCDrawSurf, &rc, DCB_RESET); // in logical coordinates + wsprintf(text, "GetBoundsRect = %d\n", uiRC); + OutputDebugString(text); + wsprintf(text, "left = %d\n", rc.left); + OutputDebugString(text); + wsprintf(text, "right = %d\n", rc.right); + OutputDebugString(text); + wsprintf(text, "top = %d\n", rc.top); + OutputDebugString(text); + wsprintf(text, "bottom = %d\n", rc.bottom); + OutputDebugString(text); + } + +// !!! +// saving the wmf as an Aldus mf +// +{ +OPENFILENAME ofn; +char szFile[256], szFileTitle[256]; +static char *szFilter; +UINT uiSize; +HANDLE hFile, hMapFile; +LPVOID pMapFile; +DWORD dwHigh, dwLow; + +szFilter = + "EnhMeta files Windows Metafiles (*.wmf)\0*.wmf\0\0"; + +strcpy(szFile, "*.wmf\0"); +ofn.lStructSize = sizeof(OPENFILENAME); +ofn.hwndOwner = hwnd; +ofn.lpstrFilter = szFilter; +ofn.lpstrCustomFilter = (LPSTR) NULL; +ofn.nMaxCustFilter = 0L; +ofn.nFilterIndex = 1; +ofn.lpstrFile = szFile; +ofn.nMaxFile = sizeof(szFile); +ofn.lpstrFileTitle = szFileTitle; +ofn.nMaxFileTitle = sizeof(szFileTitle); +ofn.lpstrInitialDir = NULL; +ofn.lpstrTitle = "Save Metafile"; +ofn.Flags = 0L; +ofn.nFileOffset = 0; +ofn.nFileExtension = 0; +ofn.lpstrDefExt = "WMF"; + +if (!GetOpenFileName(&ofn)) + return 0L; + +uiSize = GetMetaFileBitsEx(ghmf, 0, NULL); +dwHigh = 0; +dwLow = uiSize; + +if ((hFile = CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == (HANDLE)-1) { + MessageBox(ghwndMain, "Fail in file open!", "Error", MB_OK); + return 0L; +} + +// +// Create a map file of the opened file +// +if ((hMapFile = CreateFileMapping(hFile, NULL, + PAGE_READWRITE, dwHigh, dwLow, "MapF")) == NULL) { + MessageBox(ghwndMain, "Fail in creating map file!", "Error", MB_OK); + goto ErrorExit1; +} + +// +// Map a view of the whole file +// +if ((pMapFile = MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, uiSize)) == NULL) { + MessageBox(ghwndMain, "Fail in mapping view of the Map File object!", "Error", MB_OK); + goto ErrorExit2; +} + +if (uiSize) { + APMFILEHEADER AldHdr; + PAPMFILEHEADER pAldHdr; + PBYTE pjTmp; + INT iSize; + char text[128]; + + AldHdr.key = ALDUS_ID; + AldHdr.hmf = 0; // Unused; must be zero + AldHdr.bbox.Left = 0; // in metafile units + AldHdr.bbox.Top = 0; + //AldHdr.bbox.Right = rc.right - rc.left; // in logical coordinates + //AldHdr.bbox.Bottom = rc.bottom - rc.top; + + switch (dwMM) { + case MM_HIENGLISH: + AldHdr.inch = 1000; + AldHdr.bbox.Right = (SHORT)dwXSugExt; + AldHdr.bbox.Bottom = (SHORT)dwYSugExt; + break; + case MM_HIMETRIC: + AldHdr.inch = 1440; + AldHdr.bbox.Right = (SHORT)(dwXSugExt / 2540 * 1440); + AldHdr.bbox.Bottom = (SHORT)(dwYSugExt / 2540 * 1440); + break; + case MM_LOENGLISH: + AldHdr.inch = 100; + AldHdr.bbox.Right = (SHORT)dwXSugExt; + AldHdr.bbox.Bottom = (SHORT)dwYSugExt; + break; + case MM_LOMETRIC: + AldHdr.inch = 254; + AldHdr.bbox.Right = (SHORT)dwXSugExt; + AldHdr.bbox.Bottom = (SHORT)dwYSugExt; + break; + case MM_TEXT: + AldHdr.inch = (WORD) (GetDeviceCaps(hDCDrawSurf, HORZRES) * 25.4 / + GetDeviceCaps(hDCDrawSurf, HORZSIZE)); + AldHdr.bbox.Right = (SHORT)dwXSugExt; + AldHdr.bbox.Bottom = (SHORT)dwYSugExt; + break; + case MM_TWIPS: + AldHdr.inch = 1440; + AldHdr.bbox.Right = (SHORT)dwXSugExt; + AldHdr.bbox.Bottom = (SHORT)dwYSugExt; + break; + default: + AldHdr.inch = 1440; + AldHdr.bbox.Right = (SHORT)(dwXSugExt / 2540 * 1440); + AldHdr.bbox.Bottom = (SHORT)(dwYSugExt / 2540 * 1440); + break; + } + + wsprintf(text, "MM = %d\n", dwMM); + OutputDebugString(text); + wsprintf(text, "AldHdr.inch = %d\n", AldHdr.inch); + OutputDebugString(text); + + AldHdr.reserved = 0; + AldHdr.checksum = 0; + { + WORD *p; + + for (p = (WORD *)&AldHdr, AldHdr.checksum = 0; + p < (WORD *)&(AldHdr.checksum); ++p) + AldHdr.checksum ^= *p; + } + + pAldHdr = &AldHdr; + pjTmp = (PBYTE)pMapFile; + + iSize = 22; + + //!!! use memcpy... + while (iSize--) { + *(((PBYTE)pjTmp)++) = *(((PBYTE)pAldHdr)++); + } + + pMapFile = (PBYTE)pMapFile + 22; + GetMetaFileBitsEx(ghmf, uiSize, pMapFile); +} + + +UnmapViewOfFile(pMapFile); + +ErrorExit2: + CloseHandle(hMapFile); +ErrorExit1: + CloseHandle(hFile); +} + + RestoreDC(hDCDrawSurf, iSavedDC); + ReleaseDC(ghwndDrawSurf, hDCDrawSurf); + + } else { + SetWindowText(ghTextWnd, "Cannot get 3X metafile from clipboard!"); + } + + goto PASTE_EXIT; + + } + + // + // gbImport3X == FALSE + // + { + HENHMETAFILE hEmfTmp; + ENHMETAHEADER EnhMetaHdr; + + hEmfTmp = GetClipboardData(CF_ENHMETAFILE); + if (hEmfTmp) { + SetWindowText(ghTextWnd, "Pasting Enhanced Metafile"); + DeleteEnhMetaFile(ghMetaf); + ghMetaf = CopyEnhMetaFile(hEmfTmp, NULL); + DeleteEnhMetaFile(hEmfTmp); + GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr); + SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, EnhMetaHdr.nRecords, FALSE); + bReset = TRUE; + } else { + SetWindowText(ghTextWnd, "Cannot get Enhanced metafile from clipboard!"); + } + } +PASTE_EXIT: + + CloseClipboard(); + EnableMenuItem(hMenu, MM_COPY, MF_ENABLED); + return 0L; + } + + case MM_DEL: { + OpenClipboard(ghwndMain); + EmptyClipboard(); + CloseClipboard(); + return 0L; + } + case MM_PEN: { HDC hDC; DWORD dwRGB; @@ -370,14 +854,44 @@ long MainWndProc( return 0L; } case MM_FONT: { + HDC hDC; + char text[128]; + if (bChooseNewFont(ghwndMain, &glf, &gCrText)) { ghCurFont = CreateFontIndirect(&glf); + + hDC = GetDC(ghwndDrawSurf); + EnumFonts(hDC, glf.lfFaceName, (FONTENUMPROC)iTT, (LPARAM)&gbTT); + wsprintf(text, "gbTT = %d\n", gbTT); + //OutputDebugString(text); + ReleaseDC(ghwndDrawSurf, hDC); + if (ghDCMetaf != NULL) SelectObject(ghDCMetaf, ghCurFont); } return 0L; } + case MM_TTOUTLN_STROKEFILL: { + gbSFOutln = (gbSFOutln ? FALSE : TRUE); + if (gbSFOutln) { + CheckMenuItem(hMenu, MM_TTOUTLN_STROKEFILL, MF_CHECKED); + CheckMenuItem(hMenu, MM_TTOUTLN_POLYDRAW, MF_UNCHECKED); + gbPDOutln = FALSE; + } + return 0L; + } + + case MM_TTOUTLN_POLYDRAW: { + gbPDOutln = (gbPDOutln ? FALSE : TRUE); + if (gbPDOutln) { + CheckMenuItem(hMenu, MM_TTOUTLN_STROKEFILL, MF_UNCHECKED); + CheckMenuItem(hMenu, MM_TTOUTLN_POLYDRAW, MF_CHECKED); + gbSFOutln = FALSE; + } + return 0L; + } + case MM_HITTEST: { static BOOL bHitTest=FALSE; HWND hwndRecBtn; @@ -403,9 +917,15 @@ long MainWndProc( } return 0L; } - case MM_ABOUT: + + case MM_LEABOUT: if (DialogBox(ghModule, (LPCSTR)"AboutBox", ghwndMain, (DLGPROC)About) == -1) MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK); + return 0L; + + case MM_ABOUT: + if (DialogBox(ghModule, "AboutBox", ghwndMain, (DLGPROC)About) == -1) + MessageBox(ghwndMain, "DEMO: About Dialog Creation Error!", "Error", MB_OK); return 0L; case MM_LOAD_MASKBMP: @@ -425,15 +945,39 @@ long MainWndProc( case MM_LOAD: case DID_OPEN: { ENHMETAHEADER EnhMetaHdr; + HENHMETAFILE hEmfTmp; SetWindowText(ghTextWnd, "Load Metafile"); - DeleteEnhMetaFile(ghMetaf); - ghMetaf = hemfLoadMetafile(hwnd); - if (ghMetaf != 0) { + // + // If user hit cancel, we still have the original metafile + // + //DeleteEnhMetaFile(ghMetaf); + //ghMetaf = hemfLoadMetafile(hwnd); + hEmfTmp = hemfLoadMetafile(hwnd); + if (hEmfTmp != 0) { + char szDesc[256]; + + DeleteEnhMetaFile(ghMetaf); + ghMetaf = CopyEnhMetaFile(hEmfTmp, NULL); GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr); SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, EnhMetaHdr.nRecords, FALSE); - } else { - SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, 0, FALSE); + DeleteEnhMetaFile(hEmfTmp); + EnableMenuItem(hMenu, MM_COPY, MF_ENABLED); + if (GetEnhMetaFileDescription(ghMetaf, 256, szDesc) != 0) { + char szText[256]; + char *szTmp, szSource[256]; + + szTmp = (char *)strtok(szDesc, "\\0"); + strcpy(szSource, szTmp); + szTmp = (char *)strtok(NULL, "\\0\\0"); + wsprintf(szText, "Source: %s Title: %s", szSource, szTmp); + SetWindowText(ghTextWnd, szText); + strcpy(szLoadedMetaf, szTmp); + } else { + strcpy(szLoadedMetaf, ""); + } + //} else { + // SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, 0, FALSE); } bReset = TRUE; return 0L; @@ -453,6 +997,27 @@ long MainWndProc( SetWindowText(ghTextWnd, "ERROR: Failed in creating the metafile DC!"); return 0L; } + + // Parse the szFilename for the title and GdiComment the metafile with it. + { + char szComment[256]; + char *szTmp, szTmp2[256]; + + szTmp = (char *)strtok(szFilename, "\\"); + strcpy(szTmp2, szTmp); + while (szTmp != NULL) { + szTmp = (char *)strtok(NULL, "\\"); + if (szTmp != NULL) { + strcpy(szTmp2, szTmp); + } + } + szTmp = (char *)strtok(szTmp2, "."); + wsprintf((LPSTR) szComment, "MfEdit:\\0%s\\0\\0", szTmp); + if (!GdiComment(ghDCMetaf, 256, szComment)) { + MessageBox(ghwndMain, "Fail in adding comment!", "Error", MB_OK); + } + } + gbRecording = TRUE; if (ghpnCur != NULL) @@ -466,8 +1031,12 @@ long MainWndProc( return 0L; case DID_RECORD: { - char tmp[256]; - char suffix[20]; + int iWidthMM, iHeightMM, iWidthPels, iHeightPels, iMMPerPelX, iMMPerPelY; + char szComment[256]; + char szTitle[256]; + RECT rc; + HDC hDC; + if (gbHitTest) { SetWindowText(ghTextWnd, "Please CANCEL Hit Testing Mode First!"); @@ -476,17 +1045,68 @@ long MainWndProc( SetWindowText(ghTextWnd, "Recording..."); if (!gbRecording) { - wsprintf((LPSTR) suffix, "%d.emf", iMetafCnt); - iMetafCnt++; - strcpy(tmp, szFilename); - strcat(tmp, suffix); - ghDCMetaf = CreateEnhMetaFile((HDC)NULL, tmp, (LPRECT)NULL, (LPSTR)NULL); + + hDC = GetDC(hwnd); + iWidthMM = GetDeviceCaps(hDC, HORZSIZE); + iHeightMM = GetDeviceCaps(hDC, VERTSIZE); + iWidthPels = GetDeviceCaps(hDC, HORZRES); + iHeightPels = GetDeviceCaps(hDC, VERTRES); + ReleaseDC(hwnd, hDC); + iMMPerPelX = (iWidthMM * 100)/iWidthPels; + iMMPerPelY = (iHeightMM * 100)/iHeightPels; + GetClientRect(ghwndDrawSurf, &rc); + rc.left = rc.left * iMMPerPelX; + rc.top = rc.top * iMMPerPelY; + rc.right = rc.right * iMMPerPelX; + rc.bottom = rc.bottom * iMMPerPelY; + + { + char szFilenameWithExt[256]; + char suffix[20]; + char szDesc[256]; + char *szTmp, szTmp2[256]; + + // + // assemble a new metafile name with the emf extension from + // the generic szFilename + // + wsprintf((LPSTR) suffix, "%d.emf", iMetafCnt); + iMetafCnt++; + strcpy(szFilenameWithExt, szFilename); + strcat(szFilenameWithExt, suffix); + + // + // parse szFilename for the title for description + // + szTmp = (char *)strtok(szFilename, "\\"); + strcpy(szTmp2, szTmp); + while (szTmp != NULL) { + szTmp = (char *)strtok(NULL, "\\"); + if (szTmp != NULL) { + strcpy(szTmp2, szTmp); + } + } + szTmp = (char *)strtok(szTmp2, "."); + strcpy(szTitle, szTmp); + wsprintf(szDesc, "SDK Enhanced Metafile Editor\\0%s\\0\\0", szTitle); + ghDCMetaf = CreateEnhMetaFile((HDC)NULL, szFilenameWithExt, (LPRECT)&rc, (LPSTR)szDesc); + } + + if ((SetGraphicsMode(ghDCMetaf, GM_ADVANCED)) == 0) { + MessageBox(ghwndMain, "Fail in setting Advanced Graphics Mode!", "Error", MB_OK); + } } if (ghDCMetaf == NULL) { SetWindowText(ghTextWnd, "ERROR: Failed in creating the metafile DC!"); return 0L; } + + wsprintf((LPSTR) szComment, "MfEdit:\\0%s\\0\\0", szTitle); + if (!GdiComment(ghDCMetaf, 256, szComment)) { + MessageBox(ghwndMain, "Fail in adding comment!", "Error", MB_OK); + } + gbRecording = TRUE; if (ghpnCur != NULL) @@ -507,35 +1127,109 @@ long MainWndProc( gbRecording = FALSE; } return 0L; + case DID_PLAY: { HDC hDCDrawSurf; ENHMETAHEADER EnhMetaHdr; - //!!!RECT rcClientDS; + RECT rcClientDS; + int iEntries; + PLOGPALETTE plogPal; + PBYTE pjTmp; + HPALETTE hPal; + char szTmp[256]; - SetWindowText(ghTextWnd, "Playing Metafile"); + wsprintf(szTmp, "Playing Metafile: %s", szLoadedMetaf); + SetWindowText(ghTextWnd, szTmp); if (ghMetaf != NULL) { hDCDrawSurf = GetDC(ghwndDrawSurf); - //!!!GetClientRect(ghwndDrawSurf, &rcClientDS); GetEnhMetaFileHeader(ghMetaf, sizeof(ENHMETAHEADER), &EnhMetaHdr); - //!!!PlayEnhMetaFile( hDCDrawSurf, ghMetaf, (LPRECT) &rcClientDS); - PlayEnhMetaFile( hDCDrawSurf, ghMetaf, (LPRECT) &EnhMetaHdr.rclBounds); + iEntries = GetEnhMetaFilePaletteEntries(ghMetaf, 0, NULL); + + if (iEntries) { + if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, + sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) { + MessageBox(ghwndMain, "Failed in Creating Palette!", "Error", MB_OK); + } + + plogPal->palVersion = 0x300; + plogPal->palNumEntries = (WORD) iEntries; + pjTmp = (PBYTE) plogPal; + pjTmp += 8; + + GetEnhMetaFilePaletteEntries(ghMetaf, iEntries, (PPALETTEENTRY)pjTmp); + hPal = CreatePalette(plogPal); + GlobalFree(plogPal); + + SelectPalette(hDCDrawSurf, hPal, FALSE); + RealizePalette(hDCDrawSurf); + } + + + if (gbFit2Wnd) { + GetClientRect(ghwndDrawSurf, &rcClientDS); + if (!PlayEnhMetaFile( hDCDrawSurf, ghMetaf, (LPRECT) &rcClientDS)) { + char text[128]; + + wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError()); + OutputDebugString(text); + } + } else { + RECT rc; + + rc.top = rc.left = 0; + rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left; + rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top; + if (!PlayEnhMetaFile( hDCDrawSurf, ghMetaf, (LPRECT) &rc)) { + char text[128]; + + wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError()); + OutputDebugString(text); + } + + } // // Enabling the user to embed another metafile // - if ((gbRecording) && (ghDCMetaf != NULL)) - PlayEnhMetaFile( ghDCMetaf, ghMetaf, (LPRECT) &EnhMetaHdr.rclBounds); + if ((gbRecording) && (ghDCMetaf != NULL)) { + if (hPal != (HPALETTE)NULL) { + SelectPalette(ghDCMetaf, hPal, FALSE); + RealizePalette(ghDCMetaf); + } + { + RECT rc; + + rc.top = rc.left = 0; + rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left; + rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top; + if (!PlayEnhMetaFile( ghDCMetaf, ghMetaf, (LPRECT) &rc)) { + char text[128]; + + wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError()); + OutputDebugString(text); + } + + } + } ReleaseDC(ghwndDrawSurf, hDCDrawSurf); + } else { + SetWindowText(ghTextWnd, "No Metafile for Playing"); } + return 0L; } case DID_FF: { HDC hDCDrawSurf; ENHMETAHEADER EnhMetaHdr; - //!!!RECT rcClientDS; + RECT rcClientDS; static int iRecord = 0; PLAYINFO PlayInfo; + int iEntries; + PLOGPALETTE plogPal; + PBYTE pjTmp; + HPALETTE hPal; + if (ghMetaf == 0) return 0L; @@ -546,16 +1240,43 @@ long MainWndProc( GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr); SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, iRecord, FALSE); if ((EnhMetaHdr.nRecords > 1) && (iRecord <= (INT)EnhMetaHdr.nRecords)) { - //!!!GetClientRect(ghwndDrawSurf, &rcClientDS); hDCDrawSurf = GetDC(ghwndDrawSurf); - //!!!EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT) &rcClientDS); - EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT) &EnhMetaHdr.rclBounds); + iEntries = GetEnhMetaFilePaletteEntries(ghMetaf, 0, NULL); + + if (iEntries) { + if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, + sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) { + MessageBox(ghwndMain, "Failed in Creating Palette!", "Error", MB_OK); + } + + plogPal->palVersion = 0x300; + plogPal->palNumEntries = (WORD) iEntries; + pjTmp = (PBYTE) plogPal; + pjTmp += 8; + + GetEnhMetaFilePaletteEntries(ghMetaf, iEntries, (PPALETTEENTRY)pjTmp); + hPal = CreatePalette(plogPal); + GlobalFree(plogPal); + + SelectPalette(hDCDrawSurf, hPal, FALSE); + RealizePalette(hDCDrawSurf); + } + + if (gbFit2Wnd) { + GetClientRect(ghwndDrawSurf, &rcClientDS); + EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT) &rcClientDS); + } else { + EnumEnhMetaFile(hDCDrawSurf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT) &EnhMetaHdr.rclBounds); + } // // Enabling the user to record a metafile records selectively // - if ((gbRecording) && (ghDCMetaf != NULL)) - EnumEnhMetaFile(ghDCMetaf, ghMetaf, (PROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds); + if ((gbRecording) && (ghDCMetaf != NULL)) { + SelectPalette(ghDCMetaf, hPal, FALSE); + RealizePalette(ghDCMetaf); + EnumEnhMetaFile(ghDCMetaf, ghMetaf, (ENHMFENUMPROC)bPlayRecord, (LPVOID) &PlayInfo, (LPRECT)&EnhMetaHdr.rclBounds); + } ReleaseDC(ghwndDrawSurf, hDCDrawSurf); } @@ -566,7 +1287,6 @@ long MainWndProc( SetDlgItemInt(ghwndCtrlPanel, DID_COUNTER, 0, FALSE); bReset = FALSE; } - return 0L; } case DID_CLEAR: { @@ -618,6 +1338,70 @@ long MainWndProc( SetWindowText(ghTextWnd, "External Metafile: Click three points for the destination of the Metafile"); return 0L; + case MM_IMPORT_3X: + gbImport3X = (gbImport3X ? FALSE : TRUE); + + if (gbImport3X) + CheckMenuItem(hMenu, MM_IMPORT_3X, MF_CHECKED); + else + CheckMenuItem(hMenu, MM_IMPORT_3X, MF_UNCHECKED); + return 0L; + + case MM_EXPORT_3X: + gbExport3X = (gbExport3X ? FALSE : TRUE); + + if (gbExport3X) + CheckMenuItem(hMenu, MM_EXPORT_3X, MF_CHECKED); + else + CheckMenuItem(hMenu, MM_EXPORT_3X, MF_UNCHECKED); + return 0L; + case MM_FIT2WND: + gbFit2Wnd = (gbFit2Wnd ? FALSE : TRUE); + + if (gbFit2Wnd) + CheckMenuItem(hMenu, MM_FIT2WND, MF_CHECKED); + else + CheckMenuItem(hMenu, MM_FIT2WND, MF_UNCHECKED); + return 0L; + + case MM_PRINT: { + DWORD dwThrdID; + HANDLE hThrd; + PPRTDATA pPrtData; + + if (ghMetaf == 0) { + SetWindowText(ghTextWnd, "NO Metafile to print"); + return 0L; + } + + // + // bPrintMf is supposed to free up the memory when done. + // + if ((pPrtData = (PPRTDATA) GlobalAlloc(GPTR, sizeof(PRTDATA))) == NULL) { + SetWindowText(ghTextWnd, "Failed in allocating memory"); + return 0L; + } + + pPrtData->hMetaf = ghMetaf; + pPrtData->bFit2Wnd = gbFit2Wnd; + + hThrd = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE)bPrintMf, + pPrtData, STANDARD_RIGHTS_REQUIRED, + &dwThrdID); + + // + // Free the memory if CreateThread fails... + // + if (hThrd == NULL) { + SetWindowText(ghTextWnd, "Failed in creating printing thread"); + GlobalFree(pPrtData); + } + + return 0L; + + } + default: return DefWindowProc(hwnd, message, wParam, lParam); } @@ -642,7 +1426,7 @@ long MainWndProc( * Wrote it. \**************************************************************************/ -long DrawSurfWndProc( +long APIENTRY DrawSurfWndProc( HWND hwnd, UINT message, DWORD wParam, @@ -659,6 +1443,12 @@ long DrawSurfWndProc( { RECT rect; + hDC = GetDC(hwnd); + if ((SetGraphicsMode(hDC, GM_ADVANCED)) == 0) { + MessageBox(ghwndMain, "Fail in setting Advanced Graphics Mode!", "Error", MB_OK); + } + ReleaseDC(hwnd, hDC); + GetClientRect(GetParent(hwnd), &rect); SetWindowPos(hwnd, NULL, @@ -783,8 +1573,8 @@ long DrawSurfWndProc( bDrawStuff(ghDCMetaf, OrgX, OrgY, PrevX, PrevY, TRUE, FALSE, FALSE, NULL); } - NextX = LOWORD(lParam); - NextY = HIWORD(lParam); + NextX = (SHORT) LOWORD(lParam); + NextY = (SHORT) HIWORD(lParam); // Draws the new box SetROP2(hDC, R2_COPYPEN); @@ -838,7 +1628,7 @@ long DrawSurfWndProc( * 04-13-91 ???? Created. \***************************************************************************/ -long About( +BOOL CALLBACK About ( HWND hDlg, UINT message, DWORD wParam, @@ -872,7 +1662,7 @@ long About( * \***************************************************************************/ -LONG TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam) +LONG APIENTRY TextWndProc (HWND hwnd, UINT message, DWORD wParam, LONG lParam) { static HFONT hFont = (HFONT) NULL; @@ -983,7 +1773,7 @@ LONG TextWndProc (HWND hwnd, UINT messag * Wrote it. \**************************************************************************/ -LONG CtrlPanelDlgProc(HWND hwnd, UINT msg, DWORD dwParam, LONG lParam) +LONG APIENTRY CtrlPanelDlgProc(HWND hwnd, UINT msg, DWORD dwParam, LONG lParam) { switch (msg) { case WM_INITDIALOG: { @@ -1141,18 +1931,24 @@ LONG CtrlPanelDlgProc(HWND hwnd, UINT ms //case WM_CTLCOLOR: case WM_CTLCOLORDLG: //case WM_CTLCOLORLISTBOX: - //case WM_CTLCOLORSTATIC: + case WM_CTLCOLORSTATIC: switch (GET_WM_CTLCOLOR_TYPE(dwParam, lParam, msg)) { case CTLCOLOR_DLG: //case CTLCOLOR_LISTBOX: return (BOOL)GetStockObject(LTGRAY_BRUSH); - //case CTLCOLOR_STATIC: + case CTLCOLOR_STATIC: + SetBkMode(GET_WM_CTLCOLOR_HDC(dwParam, lParam, msg), + TRANSPARENT); + // SetTextColor(GET_WM_CTLCOLOR_HDC(dwParam, lParam, msg), + // RGB(255,0,0)); // SetBkColor(GET_WM_CTLCOLOR_HDC(dwParam, lParam, msg), // LIGHTGRAY); - // return (BOOL)GetStockObject(LTGRAY_BRUSH); + // RGB(255, 255,0)); + return (BOOL)GetStockObject(DKGRAY_BRUSH); } - return (BOOL)NULL; + //return (BOOL)NULL; + return (BOOL)GetStockObject(LTGRAY_BRUSH); default: return FALSE; @@ -1233,18 +2029,142 @@ BOOL bDrawStuff(HDC hDC, INT OrgX, INT O break; } - SetTextAlign(hDC, TA_UPDATECP); + SetTextAlign(hDC, TA_BASELINE | TA_LEFT | TA_UPDATECP); hObjOld = SelectObject(hDC, ghCurFont); SetTextColor(hDC, gCrText); - SetBkMode(hDC, TRANSPARENT); - TextOut(hDC, 0, 0, lpstr, 1); - SelectObject(hDC, hObjOld); - GetCurrentPositionEx(hDC, (LPPOINT) &Pt); - SetCaretPos(Pt.x, Pt.y+2); + + if ((gbSFOutln || gbPDOutln) && gbTT) { + // get rid of the char box + SetBkMode(hDC, TRANSPARENT); + BeginPath(hDC); + TextOut(hDC, NextX, NextY, lpstr, 1); + EndPath(hDC); + + if (gbSFOutln) { + StrokeAndFillPath(hDC); + goto DT_UPDATE; + } + + // + // Get path and polydraw + // + { + int iNumPt; + PBYTE pjTypes; + PPOINT pPts; + + if (iNumPt = GetPath(hDC, NULL, NULL, 0)) { + if ((pPts = (PPOINT)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, + sizeof(POINT)*iNumPt )) == NULL) { + MessageBox(ghwndMain, "Failed in Creating POINT!", "Error", MB_OK); + break; + } + + if ((pjTypes = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, + sizeof(BYTE)*iNumPt )) == NULL) { + MessageBox(ghwndMain, "Failed in Creating PBYTE!", "Error", MB_OK); + goto GP_EXIT1; + } + + GetPath(hDC, pPts, pjTypes, iNumPt); + } + PolyDraw(hDC, pPts, pjTypes, iNumPt); + LocalFree(pjTypes); + +GP_EXIT1: + LocalFree(pPts); + + } + + } else { + TextOut(hDC, NextX, NextY, lpstr, 1); + } +DT_UPDATE: + // + // Updating current position + // + { + LONG lHeight; + LONG lWidth; + TEXTMETRIC tm; + + if (GetTextMetrics(hDC, &tm)) { + lHeight = tm.tmHeight; + lWidth = tm.tmMaxCharWidth; + } + + GetCurrentPositionEx(hDC, (LPPOINT) &Pt); + SetCaretPos(Pt.x+lWidth, Pt.y); + + } ShowCaret(ghwndDrawSurf); bCaretShown = TRUE; break; + +#if 0 + +#define PT_LINECLOSE (PT_LINETO | PT_CLOSEFIGURE) +#define PT_BEZIERCLOSE (PT_BEZIERTO | PT_CLOSEFIGURE) + + hpnRed = CreatePen(PS_SOLID, 0, RGB(255,0,0)); + SelectObject(hDC, hpnRed); + + while (iNumPt--) { + static POINT pPnt[3]; + static int iCnt=0; + + switch (*pjTypes++) { + case PT_MOVETO: { + MoveToEx(hDC, pPts->x, pPts->y, NULL); + pPts++; + break; + } + case PT_LINETO: { + LineTo(hDC, pPts->x, pPts->y); + pPts++; + break; + + } + case PT_LINECLOSE: { + LineTo(hDC, pPts->x, pPts->y); + pPts++; + goto GP_EXIT2; + } + case PT_BEZIERTO: { + pPnt[iCnt].x = pPts->x; + pPnt[iCnt].y = pPts->y; + pPts++; + + if (iCnt < 2) { + iCnt++; + } else { + PolyBezierTo(hDC, pPnt, 3); + iCnt = 0; + } + break; + } + case PT_BEZIERCLOSE: { + pPnt[iCnt].x = pPts->x; + pPnt[iCnt].y = pPts->y; + pPts++; + + if (iCnt < 2) { + iCnt++; + } else { + PolyBezierTo(hDC, pPnt, 3); + iCnt = 0; + } + goto GP_EXIT2; + } + + default: + break; + } + + } + +#endif } case DID_RECT: hObjOld = SelectObject(hDC, GetStockObject(NULL_BRUSH)); @@ -1290,9 +2210,6 @@ BOOL bDrawStuff(HDC hDC, INT OrgX, INT O case DID_BMPOBJ: { static BOOL bBltReady = FALSE; - HDC hDCRef; - HGDIOBJ hObjOld; - BITMAP bm; if (bErase || bMove) return bSuccess; @@ -1321,35 +2238,12 @@ BOOL bDrawStuff(HDC hDC, INT OrgX, INT O if (!bBltReady) { return bSuccess; } - hDCRef = CreateCompatibleDC(NULL); - hObjOld = SelectObject(hDCRef, ghBmp); - GetObject(ghBmp, sizeof(BITMAP), (LPSTR)&bm); - PlgBlt(hDC, rgPtsBMP, hDCRef, 0, 0, bm.bmWidth, bm.bmHeight, - ghBmpMask, 0, 0); - SelectObject(hDCRef, hObjOld); - DeleteDC(hDCRef); + bPlgBlt(hDC, rgPtsBMP); return bSuccess; } bBltReady = TRUE; - hDCRef = CreateCompatibleDC(NULL); - hObjOld = SelectObject(hDCRef, ghBmp); - - GetObject(ghBmpMask, sizeof(BITMAP), (LPSTR)&bm); - if (bm.bmBitsPixel != 1) { - SetWindowText(ghTextWnd, "ERROR: Mask has to be a Monochrome bitmap!"); - ghBmpMask = NULL; - } - // - // Avoiding a HT bug - // - //ghBmpMask = NULL; - GetObject(ghBmp, sizeof(BITMAP), (LPSTR)&bm); - //SetStretchBltMode(hDC, HALFTONE); - PlgBlt(hDC, rgPtsBMP, hDCRef, 0, 0, bm.bmWidth, bm.bmHeight, - ghBmpMask, 0, 0); - SelectObject(hDCRef, hObjOld); - DeleteDC(hDCRef); + bPlgBlt(hDC, rgPtsBMP); iCntBMP = 0; // reset return bSuccess; } @@ -1359,6 +2253,11 @@ BOOL bDrawStuff(HDC hDC, INT OrgX, INT O RECT rcClientDS; static XFORM xform; static BOOL bXformReady = FALSE; + int iEntries; + PLOGPALETTE plogPal; + PBYTE pjTmp; + HPALETTE hPal; + if (bErase || bMove) return bSuccess; @@ -1391,8 +2290,43 @@ BOOL bDrawStuff(HDC hDC, INT OrgX, INT O GetEnhMetaFileHeader(ghMetaf, sizeof(ENHMETAHEADER), &EnhMetaHdr); SetWorldTransform(hDC, &xform); GetClientRect(ghwndDrawSurf, &rcClientDS); + + iEntries = GetEnhMetaFilePaletteEntries(ghMetaf, 0, NULL); + + if (iEntries) { + if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, + sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) { + MessageBox(ghwndMain, "Failed in Creating Palette!", "Error", MB_OK); + } + + plogPal->palVersion = 0x300; + plogPal->palNumEntries = (WORD) iEntries; + pjTmp = (PBYTE) plogPal; + pjTmp += 8; + + GetEnhMetaFilePaletteEntries(ghMetaf, iEntries, (PPALETTEENTRY)pjTmp); + hPal = CreatePalette(plogPal); + GlobalFree(plogPal); + + SelectPalette(hDC, hPal, FALSE); + RealizePalette(hDC); + } + //PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &rcClientDS); - PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &EnhMetaHdr.rclBounds); + { + RECT rc; + + rc.top = rc.left = 0; + rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left; + rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top; + if (!PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &rc)) { + char text[128]; + + wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError()); + OutputDebugString(text); + } + + } ModifyWorldTransform(hDC, NULL, MWT_IDENTITY); return bSuccess; } @@ -1413,8 +2347,43 @@ BOOL bDrawStuff(HDC hDC, INT OrgX, INT O bXformReady = TRUE; SetWorldTransform(hDC, &xform); GetClientRect(ghwndDrawSurf, &rcClientDS); + + iEntries = GetEnhMetaFilePaletteEntries(ghMetaf, 0, NULL); + + if (iEntries) { + if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, + sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) { + MessageBox(ghwndMain, "Failed in Creating Palette!", "Error", MB_OK); + } + + plogPal->palVersion = 0x300; + plogPal->palNumEntries = (WORD) iEntries; + pjTmp = (PBYTE) plogPal; + pjTmp += 8; + + GetEnhMetaFilePaletteEntries(ghMetaf, iEntries, (PPALETTEENTRY)pjTmp); + hPal = CreatePalette(plogPal); + GlobalFree(plogPal); + + SelectPalette(hDC, hPal, FALSE); + RealizePalette(hDC); + } + //PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &rcClientDS); - PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &EnhMetaHdr.rclBounds); + { + RECT rc; + + rc.top = rc.left = 0; + rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left; + rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top; + if (!PlayEnhMetaFile(hDC, ghMetaf, (LPRECT) &rc)) { + char text[128]; + + wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError()); + OutputDebugString(text); + } + + } ModifyWorldTransform(hDC, NULL, MWT_IDENTITY); iCntMF = 0; // reset return bSuccess; @@ -1445,6 +2414,7 @@ BOOL bDrawStuff(HDC hDC, INT OrgX, INT O * History: * 08-May-1992 -by- Petrus Wong * Wrote it. +* 28-Aug-1992 -by- Petrus Wong supports aldus placable mf, wmf and emf \**************************************************************************/ HENHMETAFILE hemfLoadMetafile(HWND hwnd) { @@ -1452,8 +2422,24 @@ HENHMETAFILE hemfLoadMetafile(HWND hwnd) char szFile[256], szFileTitle[256]; static char *szFilter; + HMETAFILE hmf; + UINT uiSize; + LPVOID pvData; + HDC hDCDrawSurf; + HENHMETAFILE hemf; + + HANDLE hFile, hMapFile; + LPVOID pMapFile; + LPENHMETAHEADER pemh; + + BOOL bSuccess; + char text[128]; + + + bSuccess = TRUE; + szFilter = - "EnhMeta files (*.emf)\0*.emf\0\0"; + "EnhMeta files (*.emf)\0*.emf\0Windows Metafiles (*.wmf)\0*.wmf\0\0"; strcpy(szFile, "*.emf\0"); ofn.lStructSize = sizeof(OPENFILENAME); @@ -1476,7 +2462,175 @@ HENHMETAFILE hemfLoadMetafile(HWND hwnd) if (!GetOpenFileName(&ofn)) return 0L; - return GetEnhMetaFile(szFile); + if ((hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL)) == (HANDLE)-1) { + wsprintf(text, "Fail in file open! Error %ld\n", GetLastError()); + MessageBox(ghwndMain, text, "Error", MB_OK); + return 0L; + } + + // + // Create a map file of the opened file + // + if ((hMapFile = CreateFileMapping(hFile, NULL, + PAGE_READONLY, 0, 0, "MapF")) == NULL) { + wsprintf(text, "Fail in creating map file! Error %ld\n", GetLastError()); + MessageBox(ghwndMain, text, "Error", MB_OK); + bSuccess = FALSE; + goto ErrorExit1; + } + + // + // Map a view of the whole file + // + if ((pMapFile = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0)) == NULL) { + wsprintf(text, "Fail in mapping view of the Map File object! Error %ld\n", GetLastError()); + MessageBox(ghwndMain, text, "Error", MB_OK); + bSuccess = FALSE; + goto ErrorExit2; + } + + // + // First check that if it is an enhanced metafile + // + pemh = (LPENHMETAHEADER) pMapFile; + if (pemh->dSignature == META32_SIGNATURE) { + hemf = GetEnhMetaFile(szFile); + goto HLM_EXIT; + } + + // + // If it has an ALDUS header skip it + // Notice: APMSIZE is used because the HANDLE and RECT of the structure + // depends on the environment + // + if (*((LPDWORD)pemh) == ALDUS_ID) { + //METAFILEPICT mfp; + + MessageBox(ghwndMain, "This is an ALDUS metafile!", "Hey!", MB_OK); + uiSize = *((LPDWORD) ((PBYTE)pMapFile + APMSIZE + 6)); + hDCDrawSurf = GetDC(ghwndDrawSurf); + + // Notice: mtSize is size of the file in word. + // if LPMETAFILEPICT is NULL + // MM_ANISOTROPIC mode and default device size will be used. + hemf = SetWinMetaFileBits(uiSize*2L, (PBYTE)pMapFile + APMSIZE, hDCDrawSurf, NULL); +#if 0 + switch ( ((PAPMFILEHEADER) pMapFile)->inch ) { + // !!! End up in an upside down image + // + case 1440: + mfp.mm = MM_TWIPS; + OutputDebugString("MM_TWIPS\n"); + break; + case 2540: + OutputDebugString("MM_HIMETRIC\n"); + mfp.mm = MM_HIMETRIC; + break; + case 254: + OutputDebugString("MM_LOMETRIC\n"); + mfp.mm = MM_LOMETRIC; + break; + case 1000: + OutputDebugString("MM_HIENGLISH\n"); + mfp.mm = MM_HIENGLISH; + break; + case 100: + OutputDebugString("MM_LOENGLISH\n"); + mfp.mm = MM_LOENGLISH; + break; + default: + // !!! In addition, text is too small + // + OutputDebugString("MM_ANISOTROPIC\n"); + mfp.mm = MM_ANISOTROPIC; + mfp.xExt = (((PAPMFILEHEADER) pMapFile)->bbox.Right - ((PAPMFILEHEADER) pMapFile)->bbox.Left) + * ((PAPMFILEHEADER) pMapFile)->inch * 2560; + mfp.yExt = (((PAPMFILEHEADER) pMapFile)->bbox.Bottom - ((PAPMFILEHEADER) pMapFile)->bbox.Top) + * ((PAPMFILEHEADER) pMapFile)->inch * 2560; + break; + } + mfp.hMF = 0; + hemf = SetWinMetaFileBits(uiSize*2L, (PBYTE)pMapFile + APMSIZE, hDCDrawSurf, &mfp); +#endif + + if (!hemf) { + char text[256]; + + wsprintf(text, "SetWinMetaFileBits failed, %x", GetLastError()); + MessageBox(ghwndMain, text, "Error!", MB_OK); + } + + ghmf = SetMetaFileBitsEx(uiSize*2L, (PBYTE)pMapFile + APMSIZE); + if (!ghmf) { + char text[256]; + + wsprintf(text, "SetMetaFileBitsEx failed, %x", GetLastError()); + MessageBox(ghwndMain, text, "Error!", MB_OK); + } + +// !!! Displaying the Windows format metafile +//if (!PlayMetaFile(hDCDrawSurf, ghmf)) { +// wsprintf(text, "PlayMetaFile failed, %x", GetLastError()); +// MessageBox(ghwndMain, text, "Error!", MB_OK); +//} + ReleaseDC(ghwndDrawSurf, hDCDrawSurf); + goto HLM_EXIT; + } + + + // + // It is a Windows 3x format metafile (hopefully) + // + if (!(hmf = GetMetaFile((LPCSTR)szFile))) { + char text[256]; + + wsprintf(text, "GetMetaFile failed, %x", GetLastError()); + MessageBox(ghwndMain, text, "Error!", MB_OK); + bSuccess = FALSE; + goto ErrorExit3; + } + + if (!(uiSize = GetMetaFileBitsEx(hmf, 0, NULL))) { + MessageBox(ghwndMain, "Fail in 1st GetMetaFileBitsEx!", "Error", MB_OK); + return NULL; + } + + if ((pvData = (LPVOID) LocalAlloc(LMEM_FIXED, uiSize)) == NULL) { + MessageBox(ghwndMain, "Fail in Memory Allocation!", "Error", MB_OK); + bSuccess = FALSE; + goto ErrorExit3; + } + + if (!(uiSize = GetMetaFileBitsEx(hmf, uiSize, pvData))) { + MessageBox(ghwndMain, "Fail in 2nd GetMetaFileBitsEx!", "Error", MB_OK); + bSuccess = FALSE; + goto ErrorExit3; + } + + DeleteMetaFile(hmf); + + hDCDrawSurf = GetDC(ghwndDrawSurf); + hemf = SetWinMetaFileBits(uiSize, (LPBYTE)pvData, hDCDrawSurf, NULL); + ghmf = SetMetaFileBitsEx(uiSize, (LPBYTE) pvData); + + LocalFree(pvData); + + ReleaseDC(ghwndDrawSurf ,hDCDrawSurf); + +HLM_EXIT: +ErrorExit3: + UnmapViewOfFile(pMapFile); + +ErrorExit2: + CloseHandle(hMapFile); +ErrorExit1: + CloseHandle(hFile); + + if (bSuccess) + return hemf; + else + return 0L; } /******************************Public*Routine******************************\ @@ -1503,6 +2657,11 @@ HDC hDCRecordMetafileAs(HWND hwnd, LPSTR char *szTmp, szTmp2[256]; HDC hDCMeta; + int iWidthMM, iHeightMM, iWidthPels, iHeightPels, iMMPerPelX, iMMPerPelY; + RECT rc; + HDC hDC; + + szFilter = "EnhMeta files (*.emf)\0\0"; strcpy(szFile, "*.emf\0"); ofn.lStructSize = sizeof(OPENFILENAME); @@ -1526,7 +2685,32 @@ HDC hDCRecordMetafileAs(HWND hwnd, LPSTR return 0L; } - hDCMeta = CreateEnhMetaFile((HDC)NULL, szFile, (LPRECT)NULL, (LPSTR)NULL); + + hDC = GetDC(hwnd); + iWidthMM = GetDeviceCaps(hDC, HORZSIZE); + iHeightMM = GetDeviceCaps(hDC, VERTSIZE); + iWidthPels = GetDeviceCaps(hDC, HORZRES); + iHeightPels = GetDeviceCaps(hDC, VERTRES); + ReleaseDC(hwnd, hDC); + iMMPerPelX = (iWidthMM * 100)/iWidthPels; + iMMPerPelY = (iHeightMM * 100)/iHeightPels; + GetClientRect(ghwndDrawSurf, &rc); + rc.left = rc.left * iMMPerPelX; + rc.top = rc.top * iMMPerPelY; + rc.right = rc.right * iMMPerPelX; + rc.bottom = rc.bottom * iMMPerPelY; + + + //hDCMeta = CreateEnhMetaFile((HDC)NULL, szFile, (LPRECT)NULL, (LPSTR)NULL); + { + CHAR szDesc[256]; + + wsprintf(szDesc, "SDK Enhanced Metafile Editor\\0%s\\0\\0", szFileTitle); + hDCMeta = CreateEnhMetaFile((HDC)NULL, szFile, (LPRECT)&rc, (LPSTR)szDesc); + if ((SetGraphicsMode(hDCMeta, GM_ADVANCED)) == 0) { + MessageBox(ghwndMain, "Fail in setting Advanced Graphics Mode!", "Error", MB_OK); + } + } // // parses the new filename, removes the extension and copy it into @@ -1682,6 +2866,8 @@ PlayRec: * Warnings: pszFileName contains the full path * * History: +* 18-Feb-1993 Petrus Wong fix metaf bnp color problem +* 21-Oct-1992 Petrus Wong fix data-misalignment * 13-May-1992 Petrus Wong return bitmap handle * 09-Jan-1992 -by- Petrus Wong * Wrote it. @@ -1689,13 +2875,17 @@ PlayRec: HBITMAP hBmpLoadBitmapFile(HDC hDC, PSTR pszFileName) { - HANDLE hFile, hMapFile; - LPVOID pMapFile; - LPBITMAPINFOHEADER pbmh; - LPBITMAPINFO pbmi; - PBYTE pjTmp; - ULONG sizBMI; - HBITMAP hBitmap; + HANDLE hFile, hMapFile; + LPVOID pMapFile, pMapFileTmp; + LPBITMAPINFOHEADER pbmh; + LPBITMAPINFO pbmi; + PBYTE pjTmp; + ULONG sizBMI; + HBITMAP hBitmap; + INT iNumClr; + BOOL bCoreHdr; + WORD wBitCount; + PFILEINFO pFileInfo; hBitmap = NULL; @@ -1709,7 +2899,7 @@ HBITMAP hBmpLoadBitmapFile(HDC hDC, PSTR // Create a map file of the opened file // if ((hMapFile = CreateFileMapping(hFile, NULL, - PAGE_READONLY, 0, 0, "MapF")) == (HANDLE)-1) { + PAGE_READONLY, 0, 0, NULL)) == (HANDLE)-1) { SetWindowText(ghTextWnd, "Fail in creating map file"); goto ErrExit2; @@ -1723,6 +2913,8 @@ HBITMAP hBmpLoadBitmapFile(HDC hDC, PSTR goto ErrExit3; } + pMapFileTmp = pMapFile; + // // First check that it is a bitmap file // @@ -1731,21 +2923,63 @@ HBITMAP hBmpLoadBitmapFile(HDC hDC, PSTR goto ErrExit3; } - pbmh = (LPBITMAPINFOHEADER)((PBYTE)pMapFile + sizeof(BITMAPFILEHEADER)); - // - // Use the size to determine if it is a BitmapCoreHeader or - // BitmapInfoHeader + // The file header doesn't end on DWORD boundary... // - if (pbmh->biSize == sizeof(BITMAPCOREHEADER)) - { - sizBMI = sizeof(BITMAPCOREHEADER)+sizeof(RGBTRIPLE)* - ((((LPBITMAPCOREHEADER)pbmh)->bcBitCount == 24) ? 0 : (1 << ((LPBITMAPCOREHEADER)pbmh)->bcBitCount)); - } - else // BITMAPINFOHEADER + pbmh = (LPBITMAPINFOHEADER)((PBYTE)pMapFile + sizeof(BITMAPFILEHEADER)); + { - sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)* - ((pbmh->biBitCount == 24) ? 0 : (1 << pbmh->biBitCount)); + BITMAPCOREHEADER bmch, *pbmch; + BITMAPINFOHEADER bmih, *pbmih; + PBYTE pjTmp; + ULONG ulSiz; + + pbmch = &bmch; + pbmih = &bmih; + + pjTmp = (PBYTE)pbmh; + ulSiz = sizeof(BITMAPCOREHEADER); + while (ulSiz--) { + *(((PBYTE)pbmch)++) = *(((PBYTE)pjTmp)++); + } + + pjTmp = (PBYTE)pbmh; + ulSiz = sizeof(BITMAPINFOHEADER); + while (ulSiz--) { + *(((PBYTE)pbmih)++) = *(((PBYTE)pjTmp)++); + } + + // + // Use the size to determine if it is a BitmapCoreHeader or + // BitmapInfoHeader + // + // Does PM supports 16 and 32 bpp? How? + // + if (bmch.bcSize == sizeof(BITMAPCOREHEADER)) + { + wBitCount = bmch.bcBitCount; + iNumClr = ((wBitCount == 24) ? 0 : (1 << wBitCount)); + sizBMI = sizeof(BITMAPCOREHEADER)+sizeof(RGBTRIPLE)*iNumClr; + bCoreHdr = TRUE; + } + else // BITMAPINFOHEADER + { + wBitCount = bmih.biBitCount; + switch (wBitCount) { + case 16: + case 32: + sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3; + break; + case 24: + sizBMI = sizeof(BITMAPINFOHEADER); + break; + default: + iNumClr = (1 << wBitCount); + sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*iNumClr; + break; + } + bCoreHdr = FALSE; + } } if ((pbmi = (LPBITMAPINFO) LocalAlloc(LMEM_FIXED,sizBMI)) == NULL) { @@ -1767,13 +3001,47 @@ HBITMAP hBmpLoadBitmapFile(HDC hDC, PSTR pMapFile = (PBYTE)pMapFile + ((BITMAPFILEHEADER *)pMapFile)->bfOffBits; +// !!! Use CreateBitmap for monochrome bitmap? + + // + // Select the palette into the DC first before CreateDIBitmap() + // + bSelectDIBPal(hDC, pbmi, bCoreHdr); + +// !!! We always pass a screen DC to this routine. +// !!! Maybe we should pass a metafile DC to this routine too. +// !!! The bitmap handle created for the screen DC won't give correct +// !!! color for the metafile DC. So now, we always use the original +// !!! DIB info. if ((hBitmap = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)pbmi, CBM_INIT, pMapFile, pbmi, DIB_RGB_COLORS)) == NULL) { SetWindowText(ghTextWnd, "Fail in creating DIB bitmap from file!"); goto ErrExit4; } + // reset gbUseDIB flag, now that we have opened up a new DIB + gbUseDIB = FALSE; +// !!! Always use the DIB info o.w. metafile DC don't get the right color. +#if 0 + if (GetDeviceCaps(hDC, BITSPIXEL) < wBitCount) { +#endif + gbUseDIB = TRUE; + bFreeDibFile(&gDib); + pFileInfo = &(gDib.rgFileInfo[0]); + pFileInfo->hFile = hFile; + pFileInfo->hMapFile = hMapFile; + pFileInfo->lpvMapView = pMapFileTmp; + + gDib.rgpjFrame[0] = pMapFile; + gDib.rgpbmi[0] = pbmi; + gDib.rgbCoreHdr[0] = bCoreHdr; + gDib.ulFrames = + gDib.ulFiles = 1; + return (hBitmap); +#if 0 + } +#endif ErrExit4: LocalFree(pbmi); @@ -1787,6 +3055,50 @@ ErrExit1: } + +/******************************Public*Routine******************************\ +* +* bFreeDibFile +* +* Effects: +* +* Warnings: +* +* History: +* 09-Feb-1993 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bFreeDibFile(PDIBDATA pDibData) +{ + ULONG ulFiles; + ULONG ulFrames; + ULONG i; + PFILEINFO pFileInfo; + + ulFiles = pDibData->ulFiles; + ulFrames = pDibData->ulFrames; + + for (i = 0; i < ulFrames; i++) { + LocalFree(pDibData->rgpjFrame[i]); + LocalFree(pDibData->rgpbmi[i]); + } + + for (i = 0; i < ulFiles; i++) { + pFileInfo = &(pDibData->rgFileInfo[i]); + CloseHandle(pFileInfo->hFile); + CloseHandle(pFileInfo->hMapFile); + UnmapViewOfFile(pFileInfo->lpvMapView); + } + + pDibData->ulFiles = 0; + pDibData->ulFrames = 0; + return TRUE; +} + + + + /******************************Public*Routine******************************\ * * bGetBMP @@ -1867,22 +3179,37 @@ BOOL bGetBMP(HWND hwnd, BOOL bMask) { BOOL bHitTest(HDC hDC, INT x, INT y) { BOOL bSuccess; ENHMETAHEADER EnhMetaHdr; - //POINT point; - //!!!RECT rcClientDS; + RECT rcClientDS; HTDATA htData; + static HCURSOR hCurHT, hCurWait; bSuccess = TRUE; if (ghMetaf == 0) return 0L; + hCurHT = LoadCursor(NULL, IDC_CROSS); + hCurWait = LoadCursor(NULL, IDC_WAIT); + GetEnhMetaFileHeader(ghMetaf, sizeof(EnhMetaHdr), &EnhMetaHdr); - //!!!GetClientRect(ghwndDrawSurf, &rcClientDS); + htData.point.x = x; htData.point.y = y; htData.iRecord = EnhMetaHdr.nRecords; - EnumEnhMetaFile(hDC, ghMetaf, (PROC)bDoHitTest, (LPVOID) &htData, (LPRECT)&EnhMetaHdr.rclBounds); - //!!!EnumEnhMetaFile(hDC, ghMetaf, (PROC)bDoHitTest, (LPVOID) &point, (LPRECT)&rcClientDS); + + SetCursor(hCurWait); + if (gbFit2Wnd) { + GetClientRect(ghwndDrawSurf, &rcClientDS); + EnumEnhMetaFile(hDC, ghMetaf, (ENHMFENUMPROC)bDoHitTest, (LPVOID) &htData, (LPRECT)&rcClientDS); + } else { + RECT rc; + + rc.top = rc.left = 0; + rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left; + rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top; + EnumEnhMetaFile(hDC, ghMetaf, (ENHMFENUMPROC)bDoHitTest, (LPVOID) &htData, (LPRECT)&rc); + } + SetCursor(hCurHT); return bSuccess; } @@ -1959,7 +3286,7 @@ BOOL APIENTRY bDoHitTest(HDC hDC, LPHAND case MR_SETWORLDTRANSFORM: case MR_MODIFYWORLDTRANSFORM: { // - // play all records related to transformation + // play all records related to transformation & font // PlayEnhMetaFileRecord(hDC, lpHandleTable, lpEnhMetaRecord, nHandles); @@ -2025,6 +3352,8 @@ BOOL APIENTRY bDoHitTest(HDC hDC, LPHAND break; } default: + wsprintf((LPSTR) ach, "NO HIT: I don't Hit-Test %s", rgMetaName[lpEnhMetaRecord->iType]); + SetWindowText(ghTextWnd, ach); return TRUE; } //switch @@ -2067,8 +3396,8 @@ BOOL APIENTRY bDoHitTest(HDC hDC, LPHAND // test if mouse hit position is in region // bSuccess = PtInRegion(hRgn, PtOrg.x, PtOrg.y); - //Temporily comment this out to avoid a bug in 265 - //FillRgn(hDC, hRgn, ghbrRed); + //Temporily comment this out + FillRgn(hDC, hRgn, ghbrRed); DeleteObject(hRgn); // // Set transform back. @@ -2130,26 +3459,32 @@ BOOL APIENTRY bDoHitTest(HDC hDC, LPHAND \**************************************************************************/ BOOL bChooseNewFont(HWND hwnd, PLOGFONT plf, COLORREF *pClrRef) { - HDC hDC; - CHOOSEFONT chf; - - hDC = GetDC( hwnd ); - chf.hDC = CreateCompatibleDC( hDC ); - ReleaseDC( hwnd, hDC ); - chf.lStructSize = sizeof(CHOOSEFONT); - chf.hwndOwner = hwnd; - chf.lpLogFont = plf; - chf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT; - chf.rgbColors = *pClrRef; - chf.lCustData = 0; - chf.hInstance = (HANDLE)NULL; - chf.lpszStyle = (LPSTR)NULL; - chf.nFontType = SCREEN_FONTTYPE; - chf.nSizeMin = 0; - chf.nSizeMax = 0; - chf.Flags = CF_SCREENFONTS | CF_EFFECTS; - chf.lpfnHook = (FARPROC)NULL; - chf.lpTemplateName = (LPSTR)NULL; + HDC hDC; + static CHOOSEFONT chf; + static BOOL bInit=TRUE; + + + if (bInit) { + bInit = FALSE; + + hDC = GetDC( hwnd ); + chf.hDC = CreateCompatibleDC( hDC ); + ReleaseDC( hwnd, hDC ); + + chf.lStructSize = sizeof(CHOOSEFONT); + chf.hwndOwner = hwnd; + chf.lpLogFont = plf; + chf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT; + chf.rgbColors = *pClrRef; + chf.lCustData = 0; + chf.hInstance = (HANDLE)NULL; + chf.lpszStyle = (LPSTR)NULL; + chf.nFontType = SCREEN_FONTTYPE; + chf.nSizeMin = 0; + chf.nSizeMax = 0; + chf.lpfnHook = (LPCFHOOKPROC)NULL; + chf.lpTemplateName = (LPSTR)NULL; + } if (ChooseFont( &chf ) == FALSE ) { DeleteDC( hDC ); @@ -2259,3 +3594,460 @@ HBRUSH hBrCreateBrush(HDC hDC, DWORD dwR return hbr; } + + +/******************************Public*Routine******************************\ +* +* bPrintMf Brings up the print dialog for printer setup and then +* starts printing the enhanced metafile. +* +* pPD Points to a PRTDATA structure that contains the +* the handle for the Enh. Metafile for printing. +* +* Effects: Returns TRUE if sucessful. Otherwise, it is FALSE. +* GlobalFree pPD when exits. +* +* Warnings: +* +* History: +* 22-Oct-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bPrintMf(PPRTDATA pPD) { + DOCINFO DocInfo; + HDC hDCPrinter; + ENHMETAHEADER EnhMetaHdr; + HENHMETAFILE hEnhMf; + TCHAR buf[128]; + PRINTDLG pd; + BOOL bSuccess; + int iEntries; + PLOGPALETTE plogPal; + PBYTE pjTmp; + HPALETTE hPal; + + + bSuccess = TRUE; + + if (pPD->hMetaf == 0) { + SetWindowText(ghTextWnd, "NO Metafile to print"); + goto PMF_EXIT; + bSuccess = FALSE; + } + + hEnhMf = CopyEnhMetaFile(pPD->hMetaf, NULL); + pd.lStructSize = sizeof(PRINTDLG); + pd.hwndOwner = ghwndMain; + pd.Flags = PD_RETURNDC; + pd.hInstance = ghModule; + + if (!PrintDlg(&pd)) { + SetWindowText(ghTextWnd, "Cancel Printing"); + goto PMF_EXIT; + bSuccess = FALSE; + } + + + if (pd.hDC == NULL) { + SetWindowText(ghTextWnd, "Failed in creating printer DC"); + goto PMF_EXIT; + bSuccess = FALSE; + } + + hDCPrinter = pd.hDC; + GetEnhMetaFileDescription(hEnhMf, 128, (LPTSTR)buf); + + DocInfo.cbSize = sizeof(DOCINFO); + DocInfo.lpszDocName = (LPTSTR) buf; + DocInfo.lpszOutput = NULL; + StartDoc(hDCPrinter, &DocInfo); + StartPage(hDCPrinter); + + SetWindowText(ghTextWnd, "Printing..."); + + iEntries = GetEnhMetaFilePaletteEntries(hEnhMf, 0, NULL); + + if (iEntries) { + if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, + sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) { + MessageBox(ghwndMain, "Failed in Creating Palette!", "Error", MB_OK); + } + + plogPal->palVersion = 0x300; + plogPal->palNumEntries = (WORD) iEntries; + pjTmp = (PBYTE) plogPal; + pjTmp += 8; + + GetEnhMetaFilePaletteEntries(hEnhMf, iEntries, (PPALETTEENTRY)pjTmp); + hPal = CreatePalette(plogPal); + GlobalFree(plogPal); + + SelectPalette(hDCPrinter, hPal, FALSE); + RealizePalette(hDCPrinter); + } + + if (pPD->bFit2Wnd) { + int iWidth, iHeight; + RECT rc; + + iWidth = GetDeviceCaps(hDCPrinter, HORZRES); + iHeight = GetDeviceCaps(hDCPrinter, VERTRES); + rc.left = rc.top = 0; + rc.right = iWidth; + rc.bottom = iHeight; + bSuccess = PlayEnhMetaFile(hDCPrinter, hEnhMf, (LPRECT) &rc); + if (!bSuccess) { + char text[128]; + + wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError()); + OutputDebugString(text); + } + + + } else { + GetEnhMetaFileHeader(hEnhMf, sizeof(ENHMETAHEADER), &EnhMetaHdr); + { + RECT rc; + + rc.top = rc.left = 0; + rc.right = EnhMetaHdr.rclBounds.right - EnhMetaHdr.rclBounds.left; + rc.bottom = EnhMetaHdr.rclBounds.bottom - EnhMetaHdr.rclBounds.top; + bSuccess = PlayEnhMetaFile(hDCPrinter, hEnhMf, (LPRECT) &rc); + if (!bSuccess) { + char text[128]; + + wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError()); + OutputDebugString(text); + } + + } + } + + EndPage(hDCPrinter); + EndDoc(hDCPrinter); + SetWindowText(ghTextWnd, "Printing Thread Done..."); + +PMF_EXIT: + + ExitThread(0); + GlobalFree(pPD); + return bSuccess; + +} + +/******************************Public*Routine******************************\ +* +* bSelectDIBPal +* +* Effects: Creates a logical palette from the DIB and select it into the DC +* and realize the palette. Saving the hPal in the ghPal +* +* Warnings: Based on Windows NT DIB support. If PM support 16,24,32 bpp +* we need to modify this routine. +* Global alert! ghPal is changed here... +* +* History: +* 22-Jan-1993 Petrus Wong PM support +* 31-Dec-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bSelectDIBPal(HDC hDC, LPBITMAPINFO pbmi, BOOL bCoreHdr) +{ + LOGPALETTE *plogPal; + UINT uiSizPal; + INT i, iNumClr; + WORD wBitCount; + + if (bCoreHdr) { + wBitCount = ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcBitCount; + } else { + wBitCount = pbmi->bmiHeader.biBitCount; + } + + switch (wBitCount) { + case 16: + case 24: + case 32: // Does PM supports these? + return FALSE; + default: + iNumClr = (1 << wBitCount); + break; + } + + uiSizPal = sizeof(WORD)*2 + sizeof(PALETTEENTRY)*iNumClr; + if ((plogPal = (LOGPALETTE *) LocalAlloc(LMEM_FIXED,uiSizPal)) == NULL) { + MessageBox(ghwndMain, "Fail in Allocating palette!", "Error", MB_OK); + ghPal = NULL; + return FALSE; + } + + plogPal->palVersion = 0x300; + plogPal->palNumEntries = (WORD) iNumClr; + + if (bCoreHdr) { + for (i=0; ipalPalEntry[i].peRed = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtRed; + plogPal->palPalEntry[i].peGreen = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtGreen; + plogPal->palPalEntry[i].peBlue = ((LPBITMAPCOREINFO)pbmi)->bmciColors[i].rgbtBlue; + plogPal->palPalEntry[i].peFlags = PC_RESERVED; + } + } else { + for (i=0; ipalPalEntry[i].peRed = pbmi->bmiColors[i].rgbRed; + plogPal->palPalEntry[i].peGreen = pbmi->bmiColors[i].rgbGreen; + plogPal->palPalEntry[i].peBlue = pbmi->bmiColors[i].rgbBlue; + plogPal->palPalEntry[i].peFlags = PC_RESERVED; + } + } + + DeleteObject(ghPal); + ghPal = CreatePalette((LPLOGPALETTE)plogPal); + if ((ghPal) == NULL) { + MessageBox(ghwndMain, "Fail in creating palette!", "Error", MB_OK); + return FALSE; + } + + if ((GetDeviceCaps(hDC, RASTERCAPS)) & RC_PALETTE) { + SelectPalette(hDC, ghPal, FALSE); + RealizePalette(hDC); + } + + GlobalFree(plogPal); + + return TRUE; +} + + +/******************************Public*Routine******************************\ +* +* bPlgBlt +* +* Effects: If Source DIB bpp > Destination DC's +* use Halftone for PlgBlt. +* +* Warnings: Global Alert! +* gbUseDIB is always TRUE now. +* +* History: +* 12-Mar-1993 Petrus Wong fixed clr problem on playback (non-HT) +* 18-Feb-1993 Petrus Wong fixed clr problem on playback (HT) +* 10-Feb-1993 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +BOOL bPlgBlt(HDC hDC, LPPOINT rgPtsBMP) +{ + HDC hDCRef; + HDC hDCSrn; // hDC can be metaf DC + HGDIOBJ hObjOld, hBmpMem; + BITMAP bm; + INT iBpp; + WORD wBitCnt; + + + hDCSrn = GetDC(ghwndDrawSurf); + hDCRef = CreateCompatibleDC(hDC); + + if (gbUseDIB) { + int cx, cy, dx, dy; + PBITMAPINFO pbmi; + + pbmi = (gDib.rgpbmi[0]); + dx = rgPtsBMP[0].x - rgPtsBMP[1].x; + dy = rgPtsBMP[0].y - rgPtsBMP[1].y; + cx = (INT) sqrt( dx * dx + dy * dy ); + + dx = rgPtsBMP[0].x - rgPtsBMP[2].x; + dy = rgPtsBMP[0].y - rgPtsBMP[2].y; + cy = (INT) sqrt( dx * dx + dy * dy ); + + iBpp = GetDeviceCaps(hDC, BITSPIXEL); + + if (gDib.rgbCoreHdr[0]) { + wBitCnt = ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcBitCount; + } else { + wBitCnt = pbmi->bmiHeader.biBitCount; + } + + if (iBpp < wBitCnt) { // Do Halftone + SetStretchBltMode(hDCRef, HALFTONE); + if (ghHT) { + SelectPalette(hDCRef, ghHT, FALSE); + SelectPalette(hDC, ghHT, FALSE); + SelectPalette(hDCSrn, ghHT, FALSE); // hDC can be metaf DC + RealizePalette(hDCSrn); // always realize the srn DC + + // Don't have to realize the palette in hDCRef + // RealizePalette(hDCRef); + + // has to be compatible with screen DC, cannot be hDCRef + // memory DC has no bitmap by default? + // hDC may be a metafile DC, so use hDCSrn + hBmpMem = CreateCompatibleBitmap(hDCSrn, cx, cy); + SelectObject(hDCRef, hBmpMem); + } else { + MessageBox(ghwndMain, "Halftone palette is null!", "Error", MB_OK); + } + } else { + SetStretchBltMode(hDCRef, COLORONCOLOR); + if (ghPal) { + if (ghDCMetaf == hDC) + CopyPalette(ghPal); + SelectPalette(hDCRef, ghPal, FALSE); + SelectPalette(hDC, ghPal, FALSE); + SelectPalette(hDCSrn, ghPal, FALSE); // hDC can be metaf DC + RealizePalette(hDCSrn); // always realize the srn DC + + // Don't have to realize the palette in hDCRef + // RealizePalette(hDCRef); + + // has to be compatible with screen DC, cannot be hDCRef + // memory DC has no bitmap by default? + // hDC may be a metafile DC, so use hDCSrn + hBmpMem = CreateCompatibleBitmap(hDCSrn, cx, cy); + SelectObject(hDCRef, hBmpMem); + } else { + MessageBox(ghwndMain, "Palette is null!", "Error", MB_OK); + } + } + + if (gDib.rgbCoreHdr[0]) { + StretchDIBits(hDCRef, 0,0, cx, cy, + 0,0, ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcWidth, ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcHeight, + gDib.rgpjFrame[0], pbmi, DIB_RGB_COLORS, SRCCOPY); + } else { + StretchDIBits(hDCRef, 0,0, cx, cy, + 0,0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, + gDib.rgpjFrame[0], pbmi, DIB_RGB_COLORS, SRCCOPY); + } + + PlgBlt(hDC, rgPtsBMP, hDCRef, 0, 0, cx, cy, + ghBmpMask, 0, 0); + + DeleteObject(hBmpMem); + + } else { + hObjOld = SelectObject(hDCRef, ghBmp); + + GetObject(ghBmpMask, sizeof(BITMAP), (LPSTR)&bm); + if (bm.bmBitsPixel != 1) { + SetWindowText(ghTextWnd, "ERROR: Mask has to be a Monochrome bitmap!"); + ghBmpMask = NULL; + } + + GetObject(ghBmp, sizeof(BITMAP), (LPSTR)&bm); + + if (ghPal) { + SelectPalette(hDC, ghPal, FALSE); + RealizePalette(hDC); + SetStretchBltMode(hDC, COLORONCOLOR); + } + PlgBlt(hDC, rgPtsBMP, hDCRef, 0, 0, bm.bmWidth, bm.bmHeight, + ghBmpMask, 0, 0); + + SelectObject(hDCRef, hObjOld); + } + + DeleteDC(hDCRef); + ReleaseDC(ghwndDrawSurf, hDCSrn); + return TRUE; + +} + + + +/******************************Public*Routine******************************\ +* +* HPALETTE CopyPalette +* +* Effects: +* +* Warnings: +* +* History: +* 18-Sep-1992 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +HPALETTE CopyPalette(HPALETTE hPalSrc) +{ + PLOGPALETTE plogPal; + PBYTE pjTmp; + int iNumEntries=0; + HPALETTE hPal; + + if ((iNumEntries = GetPaletteEntries(hPalSrc, 0, iNumEntries, NULL)) == 0) { + MessageBox(ghwndMain, "No entry in palette to copy!", "Error", MB_OK); + return (HPALETTE) NULL; + } + + if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, + sizeof(DWORD) + sizeof(PALETTEENTRY)*iNumEntries )) == NULL) { + MessageBox(ghwndMain, "Failed in CopyPalette!", "Error", MB_OK); + return (HPALETTE) NULL; + } + + plogPal->palVersion = 0x300; + plogPal->palNumEntries = (WORD) iNumEntries; + pjTmp = (PBYTE) plogPal; + pjTmp += 8; + GetPaletteEntries(hPalSrc, 0, iNumEntries, (PPALETTEENTRY)pjTmp); + hPal = CreatePalette(plogPal); + + GlobalFree(plogPal); + + return hPal; +} + + + + +/******************************Public*Routine******************************\ +* +* iTT +* +* Effects: set the global variable gbTT if the family is true type +* +* Warnings: +* +* History: +* 29-Apr-1993 -by- Petrus Wong +* Wrote it. +\**************************************************************************/ + +int CALLBACK iTT( + LPLOGFONT lpLF, + LPTEXTMETRIC lpTM, + DWORD dwFontType, + LPARAM lpData) +{ + + if (lpTM->tmPitchAndFamily & TMPF_TRUETYPE) { + //OutputDebugString("TRUETYPE\n"); + *((BOOL *)lpData) = TRUE; + } else { + //OutputDebugString("NON-TRUETYPE\n"); + *((BOOL *)lpData) = FALSE; + } + +#if 0 + // + // that's equivalent + // + if (dwFontType & TRUETYPE_FONTTYPE) { + //OutputDebugString("TRUETYPE\n"); + *((BOOL *)lpData) = TRUE; + } else { + //OutputDebugString("NON-TRUETYPE\n"); + *((BOOL *)lpData) = FALSE; + } +#endif + return 0; + + UNREFERENCED_PARAMETER (lpLF); + //UNREFERENCED_PARAMETER (lpTM); + UNREFERENCED_PARAMETER (dwFontType); + +}