diff --git a/reactos/dll/win32/gdi32/include/gdi32p.h b/reactos/dll/win32/gdi32/include/gdi32p.h index 68ea0237b99..104725b86f3 100644 --- a/reactos/dll/win32/gdi32/include/gdi32p.h +++ b/reactos/dll/win32/gdi32/include/gdi32p.h @@ -35,12 +35,12 @@ typedef INT /* TYPES *********************************************************************/ -// Based on wmfapi.h and Wine. This is the DC_ATTR for a MetaDC file. +// Based on wmfapi.h and Wine. typedef struct tagMETAFILEDC { PVOID pvMetaBuffer; HANDLE hFile; DWORD Size; - PMETAHEADER mf; + METAHEADER mh; UINT handles_size, cur_handles; HGDIOBJ *handles; @@ -49,9 +49,17 @@ typedef struct tagMETAFILEDC { HGDIOBJ Brush; HGDIOBJ Palette; HGDIOBJ Font; + + WCHAR Filename[MAX_PATH+2]; // Add more later. } METAFILEDC,*PMETAFILEDC; +// Metafile Entry handle +typedef struct tagMF_ENTRY { + LIST_ENTRY List; + HGDIOBJ hmDC; // Handle return from NtGdiCreateClientObj. + PMETAFILEDC pmfDC; +} MF_ENTRY, *PMF_ENTRY; typedef struct tagENHMETAFILE { PVOID pvMetaBuffer; diff --git a/reactos/dll/win32/gdi32/misc/stubs.c b/reactos/dll/win32/gdi32/misc/stubs.c index dcde0a1b162..b7a8991db53 100644 --- a/reactos/dll/win32/gdi32/misc/stubs.c +++ b/reactos/dll/win32/gdi32/misc/stubs.c @@ -33,37 +33,7 @@ CancelDC( SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } - - -/* - * @unimplemented - */ -HMETAFILE -STDCALL -CloseMetaFile( - HDC a0 - ) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/* - * @unimplemented - */ -BOOL -STDCALL -DeleteMetaFile( - HMETAFILE a0 - ) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - + /* * @unimplemented diff --git a/reactos/dll/win32/gdi32/objects/metafile.c b/reactos/dll/win32/gdi32/objects/metafile.c index 0495fbdc1df..1e76c01954b 100644 --- a/reactos/dll/win32/gdi32/objects/metafile.c +++ b/reactos/dll/win32/gdi32/objects/metafile.c @@ -1,5 +1,94 @@ #include "precomp.h" +/* DEFINES *******************************************************************/ + + +/* PRIVATE DATA **************************************************************/ + +PMF_ENTRY hMF_List = NULL; +DWORD hMFCount = 0; + +/* INTERNAL FUNCTIONS ********************************************************/ + +BOOL +MF_CreateMFDC ( HGDIOBJ hMDC, + PMETAFILEDC pmfDC ) +{ + PMF_ENTRY pMFME; + + pMFME = LocalAlloc(LMEM_ZEROINIT, sizeof(MF_ENTRY)); + if (!pMFME) + { + return FALSE; + } + + if (hMF_List == NULL) + { + hMF_List = pMFME; + InitializeListHead(&hMF_List->List); + } + else + InsertTailList(&hMF_List->List, &pMFME->List); + + pMFME->hmDC = hMDC; + pMFME->pmfDC = pmfDC; + + hMFCount++; + return TRUE; +} + + +PMETAFILEDC +MF_GetMFDC ( HGDIOBJ hMDC ) +{ + PMF_ENTRY pMFME = hMF_List; + + do + { + if ( pMFME->hmDC == hMDC ) return pMFME->pmfDC; + pMFME = (PMF_ENTRY) pMFME->List.Flink; + } + while ( pMFME != hMF_List ); + + return NULL; +} + + +BOOL +MF_DeleteMFDC ( HGDIOBJ hMDC ) +{ + PMF_ENTRY pMFME = hMF_List; + + do + { + if ( pMFME->hmDC == hMDC) + { + RemoveEntryList(&pMFME->List); + LocalFree ( pMFME ); + hMFCount--; + return TRUE; + } + pMFME = (PMF_ENTRY) pMFME->List.Flink; + } + while ( pMFME != hMF_List ); + + return FALSE; +} + +/* FUNCTIONS *****************************************************************/ + +/* + * @unimplemented + */ +HMETAFILE +STDCALL +CloseMetaFile( + HDC a0 + ) +{ + return 0; +} + /* * @implemented @@ -34,8 +123,7 @@ CopyMetaFileA( SetLastError (RtlNtStatusToDosError(Status)); else { - - rc = NULL; + rc = CopyMetaFileW( hmfSrc, lpszFileW ); HEAP_free ( lpszFileW ); } @@ -52,7 +140,50 @@ CreateMetaFileW( LPCWSTR lpszFile ) { - return NULL; + HANDLE hFile; + HDC hmDC; + PMETAFILEDC pmfDC = LocalAlloc(LMEM_ZEROINIT, sizeof(METAFILEDC)); + if (!pmfDC) return NULL; + + pmfDC->mh.mtHeaderSize = sizeof(METAHEADER) / sizeof(WORD); + pmfDC->mh.mtVersion = 0x0300; + pmfDC->mh.mtSize = pmfDC->mh.mtHeaderSize; + + if (lpszFile) /* disk based metafile */ + { + pmfDC->mh.mtType = METAFILE_DISK; + + if(!GetFullPathName( lpszFile, + MAX_PATH, + (LPTSTR) &pmfDC->Filename, + (LPTSTR*) &lpszFile)) + { +// MFDRV_DeleteDC( dc->physDev ); + return NULL; + } + + if ((hFile = CreateFileW(pmfDC->Filename, GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) + { +// MFDRV_DeleteDC( dc->physDev ); + return NULL; + } + + if (!WriteFile( hFile, &pmfDC->mh, sizeof(pmfDC->mh), NULL, NULL )) + { +// MFDRV_DeleteDC( dc->physDev ); + return NULL; + } + pmfDC->hFile = hFile; + } + else /* memory based metafile */ + pmfDC->mh.mtType = METAFILE_MEMORY; + + hmDC = NtGdiCreateClientObj ( GDI_OBJECT_TYPE_METADC ); + + MF_CreateMFDC ( hmDC, pmfDC ); + + return hmDC; } @@ -74,14 +205,26 @@ CreateMetaFileA( SetLastError (RtlNtStatusToDosError(Status)); else { - rc = NULL; - + rc = CreateMetaFileW( lpszFileW ); HEAP_free ( lpszFileW ); } return rc; } +/* + * @unimplemented + */ +BOOL +STDCALL +DeleteMetaFile( + HMETAFILE a0 + ) +{ + return FALSE; +} + + /* * @implemented */ @@ -113,8 +256,7 @@ GetMetaFileA( SetLastError (RtlNtStatusToDosError(Status)); else { - rc = NULL; - + rc = GetMetaFileW( lpszMetaFileW ); HEAP_free ( lpszMetaFileW ); }