Index: reactos/dll/win32/shimgvw/shimgvw.c =================================================================== --- reactos/dll/win32/shimgvw/shimgvw.c (revision 73640) +++ reactos/dll/win32/shimgvw/shimgvw.c (working copy) @@ -2,10 +2,12 @@ * PROJECT: ReactOS Picture and Fax Viewer * FILE: dll/win32/shimgvw/shimgvw.c * PURPOSE: shimgvw.dll - * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org) + * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org) + * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) * * UPDATE HISTORY: * 28/05/2008 Created + * 16/01/2017 Implemented Zooming by katahiromz */ #define WIN32_NO_STATUS @@ -41,6 +43,60 @@ HWND hDispWnd, hToolBar; +/* zooming */ +#define MIN_ZOOM 10 +#define MAX_ZOOM 1600 +UINT nZoomPercents = 100; +static const UINT aZoomPercents[] = +{ + 10, 25, 50, 100, 200, 400, 800, 1600 +}; + +static void ZoomIn(void) +{ + INT i; + for (i = 0; i < ARRAYSIZE(aZoomPercents); ++i) + { + if (nZoomPercents < aZoomPercents[i]) + break; + } + if (i == ARRAYSIZE(aZoomPercents)) + nZoomPercents = MAX_ZOOM; + else + nZoomPercents = aZoomPercents[i]; + + SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMM, TRUE); + if (nZoomPercents >= MAX_ZOOM) + SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMP, FALSE); + else + SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMP, TRUE); + + InvalidateRect(hDispWnd, NULL, TRUE); +} + +static void ZoomOut(void) +{ + INT i; + for (i = ARRAYSIZE(aZoomPercents); i > 0; ) + { + --i; + if (aZoomPercents[i] < nZoomPercents) + break; + } + if (i < 0) + nZoomPercents = MIN_ZOOM; + else + nZoomPercents = aZoomPercents[i]; + + SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMP, TRUE); + if (nZoomPercents <= MIN_ZOOM) + SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMM, FALSE); + else + SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMM, TRUE); + + InvalidateRect(hDispWnd, NULL, TRUE); +} + /* ToolBar Buttons */ static const TBBUTTON Buttons [] = { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */ @@ -166,6 +222,8 @@ WCHAR szTitleBuf[800]; WCHAR szResStr[512]; WCHAR *c; + RECT Rect; + UINT ImageWidth, ImageHeight; if (node) { @@ -185,6 +243,26 @@ } pLoadImage(node->FileName); + + /* calculate zoom percents */ + GetClientRect(hDispWnd, &Rect); + GdipGetImageWidth(image, &ImageWidth); + GdipGetImageHeight(image, &ImageHeight); + if (ImageHeight * Rect.right < Rect.bottom * ImageWidth) + { + if (Rect.right < ImageWidth) + nZoomPercents = (Rect.right * 100) / ImageWidth; + else + nZoomPercents = 100; + } + else + { + if (Rect.bottom < ImageHeight) + nZoomPercents = (Rect.bottom * 100) / ImageHeight; + else + nZoomPercents = 100; + } + InvalidateRect(hDispWnd, NULL, TRUE); UpdateWindow(hDispWnd); } @@ -330,8 +408,8 @@ ImageView_DrawImage(HWND hwnd) { GpGraphics *graphics; - UINT uImgWidth, uImgHeight; - UINT height = 0, width = 0, x = 0, y = 0; + UINT ImageWidth, ImageHeight; + INT ZoomedWidth, ZoomedHeight, x, y; PAINTSTRUCT ps; RECT rect; HDC hdc; @@ -350,38 +428,37 @@ return; } - GdipGetImageWidth(image, &uImgWidth); - GdipGetImageHeight(image, &uImgHeight); + GdipGetImageWidth(image, &ImageWidth); + GdipGetImageHeight(image, &ImageHeight); if (GetClientRect(hwnd, &rect)) { FillRect(hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH)); - if ((rect.right >= uImgWidth)&&(rect.bottom >= uImgHeight)) + ZoomedWidth = (ImageWidth * nZoomPercents) / 100; + ZoomedHeight = (ImageHeight * nZoomPercents) / 100; + + x = (rect.right - ZoomedWidth) / 2; + y = (rect.bottom - ZoomedHeight) / 2; + + DPRINT("x = %d, y = %d, ImageWidth = %u, ImageHeight = %u\n"); + DPRINT("rect.right = %ld, rect.bottom = %ld\n", rect.right, rect.bottom); + DPRINT("nZoomPercents = %d, ZoomedWidth = %d, ZoomedHeight = %d\n", + nZoomPercents, ZoomedWidth, ZoomedWidth); + + if (nZoomPercents % 100 == 0) { - width = uImgWidth; - height = uImgHeight; + GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor); + GdipSetSmoothingMode(graphics, SmoothingModeNone); } else { - height = uImgHeight * (UINT)rect.right / uImgWidth; - if (height <= rect.bottom) - { - width = rect.right; - } - else - { - width = uImgWidth * (UINT)rect.bottom / uImgHeight; - height = rect.bottom; - } + GdipSetInterpolationMode(graphics, InterpolationModeHighQualityBilinear); + GdipSetSmoothingMode(graphics, SmoothingModeHighQuality); } - y = (rect.bottom / 2) - (height / 2); - x = (rect.right / 2) - (width / 2); - - DPRINT("x = %d\ny = %d\nWidth = %d\nHeight = %d\n\nrect.right = %d\nrect.bottom = %d\n\nuImgWidth = %d\nuImgHeight = %d\n", x, y, width, height, rect.right, rect.bottom, uImgWidth, uImgHeight); - Rectangle(hdc, x - 1, y - 1, x + width + 1, y + height + 1); - GdipDrawImageRect(graphics, image, x, y, width, height); + Rectangle(hdc, x - 1, y - 1, x + ZoomedWidth + 1, y + ZoomedHeight + 1); + GdipDrawImageRectI(graphics, image, x, y, ZoomedWidth, ZoomedHeight); } GdipDeleteGraphics(graphics); EndPaint(hwnd, &ps); @@ -524,6 +601,19 @@ ImageView_CreateToolBar(hwnd); } +static VOID +ImageView_OnMouseWheel(HWND hwnd, INT x, INT y, INT zDelta, UINT fwKeys) +{ + if (zDelta < 0) + { + ZoomOut(); + } + else if (zDelta > 0) + { + ZoomIn(); + } +} + LRESULT CALLBACK ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { @@ -567,10 +657,14 @@ break; case IDC_ZOOMP: - + { + ZoomIn(); + } break; case IDC_ZOOMM: - + { + ZoomOut(); + } break; case IDC_SAVE: pSaveImageAs(hwnd); @@ -597,6 +691,12 @@ } break; + case WM_MOUSEWHEEL: + ImageView_OnMouseWheel(hwnd, + (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam), + (SHORT)HIWORD(wParam), (UINT)LOWORD(wParam)); + break; + case WM_NOTIFY: { LPNMHDR pnmhdr = (LPNMHDR)lParam;