Index: reactos/sdk/lib/atl/atlimage.h =================================================================== --- reactos/sdk/lib/atl/atlimage.h (revision 72721) +++ reactos/sdk/lib/atl/atlimage.h (working copy) @@ -12,12 +12,15 @@ // See rostest/apitests/atl/CImage_WIP.txt for test results. // !!!! -// TODO: GetImporterFilterString, GetExporterFilterString, Load, Save +// TODO: CImage::Load, CImage::Save // TODO: make CImage thread-safe #pragma once -#include +#include // for ATL Core +#include // for CAtlStringMgr +#include // for CSimpleString +#include // for CSimpleArray #include #include // for GUID_NULL @@ -705,31 +708,117 @@ return TRUE; } -#if 0 - // TODO: implement this + enum ExcludeFlags + { + excludeGIF = 0x01, + excludeBMP = 0x02, + excludeEMF = 0x04, + excludeWMF = 0x08, + excludeJPEG = 0x10, + excludePNG = 0x20, + excludeTIFF = 0x40, + excludeIcon = 0x80, + excludeOther = 0x80000000, + excludeDefaultLoad = 0, + excludeDefaultSave = excludeIcon | excludeEMF | excludeWMF + }; + + struct FILTER_DATA { + DWORD dwExclude; + const TCHAR *title; + const TCHAR *extensions; + const GUID *guid; + }; + + static HRESULT GetCommonFilterString( + CSimpleString& strFilter, + CSimpleArray& aguidFileTypes, + LPCTSTR pszAllFilesDescription, + DWORD dwExclude, + TCHAR chSeparator) + { + static const FILTER_DATA table[] = + { + {excludeBMP, TEXT("BMP"), TEXT("*.BMP;*.DIB;*.RLE"), &Gdiplus::ImageFormatBMP}, + {excludeJPEG, TEXT("JPEG"), TEXT("*.JPG;*.JPEG;*.JPE;*.JFIF"), &Gdiplus::ImageFormatJPEG}, + {excludeGIF, TEXT("GIF"), TEXT("*.GIF"), &Gdiplus::ImageFormatGIF}, + {excludeEMF, TEXT("EMF"), TEXT("*.EMF"), &Gdiplus::ImageFormatEMF}, + {excludeWMF, TEXT("WMF"), TEXT("*.WMF"), &Gdiplus::ImageFormatWMF}, + {excludeTIFF, TEXT("TIFF"), TEXT("*.TIF;*.TIFF"), &Gdiplus::ImageFormatTIFF}, + {excludePNG, TEXT("PNG"), TEXT("*.PNG"), &Gdiplus::ImageFormatPNG}, + {excludeIcon, TEXT("ICO"), TEXT("*.ICO"), &Gdiplus::ImageFormatIcon} + }; + + if (pszAllFilesDescription) + { + strFilter += pszAllFilesDescription; + strFilter += chSeparator; + + BOOL bFirst = TRUE; + for (size_t i = 0; i < _countof(table); ++i) + { + if ((dwExclude & table[i].dwExclude) != 0) + continue; + + if (bFirst) + bFirst = FALSE; + else + strFilter += TEXT(';'); + + strFilter += table[i].extensions; + } + strFilter += chSeparator; + + aguidFileTypes.Add(GUID_NULL); + } + + for (size_t i = 0; i < _countof(table); ++i) + { + if ((dwExclude & table[i].dwExclude) != 0) + continue; + strFilter += table[i].title; + strFilter += TEXT(" ("); + strFilter += table[i].extensions; + strFilter += TEXT(")"); + strFilter += chSeparator; + strFilter += table[i].extensions; + strFilter += chSeparator; + + aguidFileTypes.Add(*table[i].guid); + } + + strFilter += chSeparator; + + return S_OK; + } + static HRESULT GetImporterFilterString( CSimpleString& strImporters, CSimpleArray& aguidFileTypes, LPCTSTR pszAllFilesDescription = NULL, DWORD dwExclude = excludeDefaultLoad, - TCHAR chSeparator = _T('|')) + TCHAR chSeparator = TEXT('|')) { - ATLASSERT(0); - return -1; + return GetCommonFilterString(strImporters, + aguidFileTypes, + pszAllFilesDescription, + dwExclude, + chSeparator); } - // TODO: implement this static HRESULT GetExporterFilterString( CSimpleString& strExporters, CSimpleArray& aguidFileTypes, LPCTSTR pszAllFilesDescription = NULL, DWORD dwExclude = excludeDefaultSave, - TCHAR chSeparator = _T('|')) + TCHAR chSeparator = TEXT('|')) { - ATLASSERT(0); - return -1; + return GetCommonFilterString(strExporters, + aguidFileTypes, + pszAllFilesDescription, + dwExclude, + chSeparator); } -#endif // 0 protected: // an extension of BITMAPINFO Index: reactos/sdk/lib/atl/atlsimpstr.h =================================================================== --- reactos/sdk/lib/atl/atlsimpstr.h (revision 72721) +++ reactos/sdk/lib/atl/atlsimpstr.h (working copy) @@ -234,6 +234,12 @@ return *this; } + CSimpleStringT& operator+=(XCHAR ch) + { + Append(&ch, 1); + return *this; + } + operator PCXSTR() const throw() { return m_pszData; @@ -603,6 +609,12 @@ } }; + +#ifdef UNICODE +typedef CSimpleStringT CSimpleString; +#else +typedef CSimpleStringT CSimpleString; +#endif } -#endif \ No newline at end of file +#endif Index: rostests/apitests/atl/CImage.cpp =================================================================== --- rostests/apitests/atl/CImage.cpp (revision 72721) +++ rostests/apitests/atl/CImage.cpp (working copy) @@ -8,6 +8,10 @@ #include #include "resource.h" +#ifdef _MSC_VER +#pragma comment(lib, "rpcrt4.lib") +#endif + #ifdef __REACTOS__ #include #else @@ -34,6 +38,17 @@ #define START_TEST(x) int main(void) #endif +bool IsGuidEqual(const GUID& guid1, const GUID& guid2) +{ + RPC_STATUS status; + if (::UuidEqual(const_cast(&guid1), + const_cast(&guid2), &status)) + { + if (status == RPC_S_OK) + return true; + } + return false; +} const TCHAR* szFiles[] = { TEXT("ant.png"), @@ -270,6 +285,69 @@ ok(bOK, "Expected bOK to be TRUE, was: %d (for %i)\n", bOK, n); } + ATL::IAtlStringMgr *mgr = CAtlStringMgr::GetInstance(); + CSimpleArray aguidFileTypes; +#ifdef UNICODE + CHAR szBuff[512]; + const WCHAR *psz; +#else + const CHAR *psz; +#endif + + CSimpleString strImporters(mgr); + aguidFileTypes.RemoveAll(); + hr = CImage::GetImporterFilterString(strImporters, + aguidFileTypes, + TEXT("All Image Files"), 0); + ok(hr == S_OK, "Expected hr to be S_OK, was: %ld\n", hr); + ok(aguidFileTypes.GetSize() == 9, "Expected aguidFileTypes.GetSize() to be 8, was %d.", aguidFileTypes.GetSize()); + ok(IsGuidEqual(aguidFileTypes[0], GUID_NULL), "Expected aguidFileTypes[0] to be GUID_NULL.\n"); + ok(IsGuidEqual(aguidFileTypes[1], Gdiplus::ImageFormatBMP), "Expected aguidFileTypes[1] to be Gdiplus::ImageFormatBMP.\n"); + ok(IsGuidEqual(aguidFileTypes[2], Gdiplus::ImageFormatJPEG), "Expected aguidFileTypes[2] to be Gdiplus::ImageFormatJPEG.\n"); + ok(IsGuidEqual(aguidFileTypes[3], Gdiplus::ImageFormatGIF), "Expected aguidFileTypes[3] to be Gdiplus::ImageFormatGIF.\n"); + ok(IsGuidEqual(aguidFileTypes[4], Gdiplus::ImageFormatEMF), "Expected aguidFileTypes[4] to be Gdiplus::ImageFormatEMF.\n"); + ok(IsGuidEqual(aguidFileTypes[5], Gdiplus::ImageFormatWMF), "Expected aguidFileTypes[5] to be Gdiplus::ImageFormatWMF.\n"); + ok(IsGuidEqual(aguidFileTypes[6], Gdiplus::ImageFormatTIFF), "Expected aguidFileTypes[6] to be Gdiplus::ImageFormatTIFF.\n"); + ok(IsGuidEqual(aguidFileTypes[7], Gdiplus::ImageFormatPNG), "Expected aguidFileTypes[7] to be Gdiplus::ImageFormatPNG.\n"); + ok(IsGuidEqual(aguidFileTypes[8], Gdiplus::ImageFormatIcon), "Expected aguidFileTypes[8] to be Gdiplus::ImageFormatIcon.\n"); + + psz = strImporters.GetString(); +#ifdef UNICODE + WideCharToMultiByte(CP_ACP, 0, psz, -1, szBuff, 512, NULL, NULL); + ok(lstrcmpA(szBuff, "All Image Files|*.BMP;*.DIB;*.RLE;*.JPG;*.JPEG;*.JPE;*.JFIF;*.GIF;*.EMF;*.WMF;*.TIF;*.TIFF;*.PNG;*.ICO|BMP (*.BMP;*.DIB;*.RLE)|*.BMP;*.DIB;*.RLE|JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)|*.JPG;*.JPEG;*.JPE;*.JFIF|GIF (*.GIF)|*.GIF|EMF (*.EMF)|*.EMF|WMF (*.WMF)|*.WMF|TIFF (*.TIF;*.TIFF)|*.TIF;*.TIFF|PNG (*.PNG)|*.PNG|ICO (*.ICO)|*.ICO||") == 0, + "The importer filter string is bad, was: %s\n", szBuff); +#else + ok(lstrcmpA(psz, "All Image Files|*.BMP;*.DIB;*.RLE;*.JPG;*.JPEG;*.JPE;*.JFIF;*.GIF;*.EMF;*.WMF;*.TIF;*.TIFF;*.PNG;*.ICO|BMP (*.BMP;*.DIB;*.RLE)|*.BMP;*.DIB;*.RLE|JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)|*.JPG;*.JPEG;*.JPE;*.JFIF|GIF (*.GIF)|*.GIF|EMF (*.EMF)|*.EMF|WMF (*.WMF)|*.WMF|TIFF (*.TIF;*.TIFF)|*.TIF;*.TIFF|PNG (*.PNG)|*.PNG|ICO (*.ICO)|*.ICO||") == 0, + "The importer filter string is bad, was: %s\n", psz); +#endif + + CSimpleString strExporters(mgr); + aguidFileTypes.RemoveAll(); + hr = CImage::GetExporterFilterString(strExporters, + aguidFileTypes, + TEXT("All Image Files"), 0); + ok(hr == S_OK, "Expected hr to be S_OK, was: %ld\n", hr); + ok(aguidFileTypes.GetSize() == 9, "Expected aguidFileTypes.GetSize() to be 8, was %d.", aguidFileTypes.GetSize()); + ok(IsGuidEqual(aguidFileTypes[0], GUID_NULL), "Expected aguidFileTypes[0] to be GUID_NULL.\n"); + ok(IsGuidEqual(aguidFileTypes[1], Gdiplus::ImageFormatBMP), "Expected aguidFileTypes[1] to be Gdiplus::ImageFormatBMP.\n"); + ok(IsGuidEqual(aguidFileTypes[2], Gdiplus::ImageFormatJPEG), "Expected aguidFileTypes[2] to be Gdiplus::ImageFormatJPEG.\n"); + ok(IsGuidEqual(aguidFileTypes[3], Gdiplus::ImageFormatGIF), "Expected aguidFileTypes[3] to be Gdiplus::ImageFormatGIF.\n"); + ok(IsGuidEqual(aguidFileTypes[4], Gdiplus::ImageFormatEMF), "Expected aguidFileTypes[4] to be Gdiplus::ImageFormatEMF.\n"); + ok(IsGuidEqual(aguidFileTypes[5], Gdiplus::ImageFormatWMF), "Expected aguidFileTypes[5] to be Gdiplus::ImageFormatWMF.\n"); + ok(IsGuidEqual(aguidFileTypes[6], Gdiplus::ImageFormatTIFF), "Expected aguidFileTypes[6] to be Gdiplus::ImageFormatTIFF.\n"); + ok(IsGuidEqual(aguidFileTypes[7], Gdiplus::ImageFormatPNG), "Expected aguidFileTypes[7] to be Gdiplus::ImageFormatPNG.\n"); + ok(IsGuidEqual(aguidFileTypes[8], Gdiplus::ImageFormatIcon), "Expected aguidFileTypes[8] to be Gdiplus::ImageFormatIcon.\n"); + + psz = strExporters.GetString(); +#ifdef UNICODE + WideCharToMultiByte(CP_ACP, 0, psz, -1, szBuff, 512, NULL, NULL); + ok(lstrcmpA(szBuff, "All Image Files|*.BMP;*.DIB;*.RLE;*.JPG;*.JPEG;*.JPE;*.JFIF;*.GIF;*.EMF;*.WMF;*.TIF;*.TIFF;*.PNG;*.ICO|BMP (*.BMP;*.DIB;*.RLE)|*.BMP;*.DIB;*.RLE|JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)|*.JPG;*.JPEG;*.JPE;*.JFIF|GIF (*.GIF)|*.GIF|EMF (*.EMF)|*.EMF|WMF (*.WMF)|*.WMF|TIFF (*.TIF;*.TIFF)|*.TIF;*.TIFF|PNG (*.PNG)|*.PNG|ICO (*.ICO)|*.ICO||") == 0, + "The exporter filter string is bad, was: %s\n", szBuff); +#else + ok(lstrcmpA(psz, "All Image Files|*.BMP;*.DIB;*.RLE;*.JPG;*.JPEG;*.JPE;*.JFIF;*.GIF;*.EMF;*.WMF;*.TIF;*.TIFF;*.PNG;*.ICO|BMP (*.BMP;*.DIB;*.RLE)|*.BMP;*.DIB;*.RLE|JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)|*.JPG;*.JPEG;*.JPE;*.JFIF|GIF (*.GIF)|*.GIF|EMF (*.EMF)|*.EMF|WMF (*.WMF)|*.WMF|TIFF (*.TIF;*.TIFF)|*.TIF;*.TIFF|PNG (*.PNG)|*.PNG|ICO (*.ICO)|*.ICO||") == 0, + "The exporter filter string is bad, was: %s\n", psz); +#endif + #ifndef __REACTOS__ printf("CImage: %i tests executed (0 marked as todo, %i failures), 0 skipped.\n", g_tests_executed, g_tests_failed); return g_tests_failed;