Index: dll/win32/shimgvw/CMakeLists.txt =================================================================== --- dll/win32/shimgvw/CMakeLists.txt (revision 61269) +++ dll/win32/shimgvw/CMakeLists.txt (working copy) @@ -17,6 +17,7 @@ user32 gdi32 gdiplus + comdlg32 msvcrt kernel32 ntdll) Index: dll/win32/shimgvw/shimgvw.c =================================================================== --- dll/win32/shimgvw/shimgvw.c (revision 61269) +++ dll/win32/shimgvw/shimgvw.c (working copy) @@ -22,8 +22,10 @@ #include #include #include +#include #include #include +#include #define NDEBUG #include @@ -69,6 +71,68 @@ } } +static void pSaveImageAs(HWND hwnd) +{ + OPENFILENAMEW sfn; + ImageCodecInfo *CodecInfo; + WCHAR szSaveFileName[MAX_PATH]; + WCHAR szFilterMask[2048]; + GUID RawFormat; + UINT num; + UINT size; + UINT SizeRemain; + UINT j; + WCHAR *c; + + ZeroMemory(szSaveFileName, sizeof(szSaveFileName)); + ZeroMemory(szFilterMask, sizeof(szFilterMask)); + ZeroMemory(&sfn, sizeof(OPENFILENAME)); + sfn.lStructSize = sizeof(OPENFILENAME); + sfn.hwndOwner = hwnd; + sfn.hInstance = hInstance; + sfn.lpstrFile = szSaveFileName; + sfn.lpstrFilter = szFilterMask; + sfn.nMaxFile = MAX_PATH; + sfn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; + + GdipGetImageEncodersSize(&num, &size); + CodecInfo = malloc(size); + if (!CodecInfo) + { + DPRINT1("malloc() failed in pSaveImageAs()\n"); + return; + } + + GdipGetImageEncoders(num, size, CodecInfo); + GdipGetImageRawFormat(image, &RawFormat); + + SizeRemain = sizeof(szFilterMask); + c = szFilterMask - 1; + + for (j = 0; j < num; ++j) + { + StringCbPrintfExW(c + 1, SizeRemain, &c, &SizeRemain, 0, L"%s (%s)", CodecInfo[j].FormatDescription, CodecInfo[j].FilenameExtension); + SizeRemain--; + StringCbPrintfExW(c + 1, SizeRemain, &c, &SizeRemain, 0, L"%s", CodecInfo[j].FilenameExtension); + SizeRemain--; + + if (IsEqualGUID(&RawFormat, &CodecInfo[j].FormatID) == TRUE) + { + sfn.nFilterIndex = j + 1; + } + } + + if (GetSaveFileNameW(&sfn)) + { + if (GdipSaveImageToFile(image, szSaveFileName, &CodecInfo[sfn.nFilterIndex - 1].Clsid, NULL) != Ok) + { + DPRINT1("GdipSaveImageToFile() failed\n"); + } + } + + free(CodecInfo); +} + static VOID ImageView_DrawImage(HWND hwnd) { @@ -332,6 +396,7 @@ break; case IDC_SAVE: + pSaveImageAs(hwnd); break; case IDC_PRINT: @@ -453,7 +518,7 @@ // Create the window WndClass.lpszClassName = _T("shimgvw_window"); - WndClass.lpfnWndProc = (WNDPROC)ImageView_WndProc; + WndClass.lpfnWndProc = ImageView_WndProc; WndClass.hInstance = hInstance; WndClass.style = CS_HREDRAW | CS_VREDRAW; WndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPICON));