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,70 @@ } } +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(sfn)); + sfn.lStructSize = sizeof(sfn); + 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; + + for (j = 0; j < num; ++j) + { + StringCbPrintfExW(c, sizeRemain, &c, &sizeRemain, 0, L"%ls (%ls)", codecInfo[j].FormatDescription, codecInfo[j].FilenameExtension); + c++; + sizeRemain -= sizeof(*c); + StringCbPrintfExW(c, sizeRemain, &c, &sizeRemain, 0, L"%ls", codecInfo[j].FilenameExtension); + c++; + sizeRemain -= sizeof(*c); + + 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 +398,7 @@ break; case IDC_SAVE: + pSaveImageAs(hwnd); break; case IDC_PRINT: @@ -453,7 +520,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));