mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 02:36:13 +00:00
[SHIMGVW] Enable zooming
* merge ZoomIn and ZoomOut functions * NULL to hbrBackground * use GET_X_LPARAM and GET_Y_LPARAM for WM_MOUSEWHEEL
This commit is contained in:
parent
f5d679aeb9
commit
0864d2de85
1 changed files with 161 additions and 32 deletions
|
@ -2,10 +2,8 @@
|
||||||
* PROJECT: ReactOS Picture and Fax Viewer
|
* PROJECT: ReactOS Picture and Fax Viewer
|
||||||
* FILE: dll/win32/shimgvw/shimgvw.c
|
* FILE: dll/win32/shimgvw/shimgvw.c
|
||||||
* PURPOSE: shimgvw.dll
|
* 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
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
|
@ -19,6 +17,7 @@
|
||||||
#include <winnls.h>
|
#include <winnls.h>
|
||||||
#include <winreg.h>
|
#include <winreg.h>
|
||||||
#include <wingdi.h>
|
#include <wingdi.h>
|
||||||
|
#include <windowsx.h>
|
||||||
#include <objbase.h>
|
#include <objbase.h>
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
#include <commdlg.h>
|
#include <commdlg.h>
|
||||||
|
@ -41,6 +40,105 @@ WNDPROC PrevProc = NULL;
|
||||||
|
|
||||||
HWND hDispWnd, hToolBar;
|
HWND hDispWnd, hToolBar;
|
||||||
|
|
||||||
|
/* zooming */
|
||||||
|
#define MIN_ZOOM 10
|
||||||
|
#define MAX_ZOOM 1600
|
||||||
|
UINT ZoomPercents = 100;
|
||||||
|
static const UINT ZoomSteps[] =
|
||||||
|
{
|
||||||
|
10, 25, 50, 100, 200, 400, 800, 1600
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ZoomInOrOut(BOOL bZoomIn)
|
||||||
|
{
|
||||||
|
INT i;
|
||||||
|
|
||||||
|
if (bZoomIn) /* zoom in */
|
||||||
|
{
|
||||||
|
/* find next step */
|
||||||
|
for (i = 0; i < ARRAYSIZE(ZoomSteps); ++i)
|
||||||
|
{
|
||||||
|
if (ZoomPercents < ZoomSteps[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == ARRAYSIZE(ZoomSteps))
|
||||||
|
ZoomPercents = MAX_ZOOM;
|
||||||
|
else
|
||||||
|
ZoomPercents = ZoomSteps[i];
|
||||||
|
|
||||||
|
/* update tool bar buttons */
|
||||||
|
SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMM, TRUE);
|
||||||
|
if (ZoomPercents >= MAX_ZOOM)
|
||||||
|
SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMP, FALSE);
|
||||||
|
else
|
||||||
|
SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMP, TRUE);
|
||||||
|
}
|
||||||
|
else /* zoom out */
|
||||||
|
{
|
||||||
|
/* find previous step */
|
||||||
|
for (i = ARRAYSIZE(ZoomSteps); i > 0; )
|
||||||
|
{
|
||||||
|
--i;
|
||||||
|
if (ZoomSteps[i] < ZoomPercents)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < 0)
|
||||||
|
ZoomPercents = MIN_ZOOM;
|
||||||
|
else
|
||||||
|
ZoomPercents = ZoomSteps[i];
|
||||||
|
|
||||||
|
/* update tool bar buttons */
|
||||||
|
SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMP, TRUE);
|
||||||
|
if (ZoomPercents <= MIN_ZOOM)
|
||||||
|
SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMM, FALSE);
|
||||||
|
else
|
||||||
|
SendMessage(hToolBar, TB_ENABLEBUTTON, IDC_ZOOMM, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* redraw */
|
||||||
|
InvalidateRect(hDispWnd, NULL, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResetZoom(void)
|
||||||
|
{
|
||||||
|
RECT Rect;
|
||||||
|
UINT ImageWidth, ImageHeight;
|
||||||
|
|
||||||
|
/* get disp window size and image size */
|
||||||
|
GetClientRect(hDispWnd, &Rect);
|
||||||
|
GdipGetImageWidth(image, &ImageWidth);
|
||||||
|
GdipGetImageHeight(image, &ImageHeight);
|
||||||
|
|
||||||
|
/* compare two aspect rates. same as
|
||||||
|
(ImageHeight / ImageWidth < Rect.bottom / Rect.right) in real */
|
||||||
|
if (ImageHeight * Rect.right < Rect.bottom * ImageWidth)
|
||||||
|
{
|
||||||
|
if (Rect.right < ImageWidth)
|
||||||
|
{
|
||||||
|
/* it's large, shrink it */
|
||||||
|
ZoomPercents = (Rect.right * 100) / ImageWidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* it's small. show as original size */
|
||||||
|
ZoomPercents = 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Rect.bottom < ImageHeight)
|
||||||
|
{
|
||||||
|
/* it's large, shrink it */
|
||||||
|
ZoomPercents = (Rect.bottom * 100) / ImageHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* it's small. show as original size */
|
||||||
|
ZoomPercents = 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ToolBar Buttons */
|
/* ToolBar Buttons */
|
||||||
static const TBBUTTON Buttons [] =
|
static const TBBUTTON Buttons [] =
|
||||||
{ /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
|
{ /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
|
||||||
|
@ -59,17 +157,26 @@ static const TBBUTTON Buttons [] =
|
||||||
|
|
||||||
static void pLoadImage(LPWSTR szOpenFileName)
|
static void pLoadImage(LPWSTR szOpenFileName)
|
||||||
{
|
{
|
||||||
|
/* check file presence */
|
||||||
if (GetFileAttributesW(szOpenFileName) == 0xFFFFFFFF)
|
if (GetFileAttributesW(szOpenFileName) == 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
DPRINT1("File %s not found!\n", szOpenFileName);
|
DPRINT1("File %s not found!\n", szOpenFileName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* load now */
|
||||||
GdipLoadImageFromFile(szOpenFileName, &image);
|
GdipLoadImageFromFile(szOpenFileName, &image);
|
||||||
if (!image)
|
if (!image)
|
||||||
{
|
{
|
||||||
DPRINT1("GdipLoadImageFromFile() failed\n");
|
DPRINT1("GdipLoadImageFromFile() failed\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reset zoom */
|
||||||
|
ResetZoom();
|
||||||
|
|
||||||
|
/* redraw */
|
||||||
|
InvalidateRect(hDispWnd, NULL, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pSaveImageAs(HWND hwnd)
|
static void pSaveImageAs(HWND hwnd)
|
||||||
|
@ -185,8 +292,6 @@ pLoadImageFromNode(SHIMGVW_FILENODE *node, HWND hwnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
pLoadImage(node->FileName);
|
pLoadImage(node->FileName);
|
||||||
InvalidateRect(hDispWnd, NULL, TRUE);
|
|
||||||
UpdateWindow(hDispWnd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,8 +435,8 @@ static VOID
|
||||||
ImageView_DrawImage(HWND hwnd)
|
ImageView_DrawImage(HWND hwnd)
|
||||||
{
|
{
|
||||||
GpGraphics *graphics;
|
GpGraphics *graphics;
|
||||||
UINT uImgWidth, uImgHeight;
|
UINT ImageWidth, ImageHeight;
|
||||||
UINT height = 0, width = 0, x = 0, y = 0;
|
INT ZoomedWidth, ZoomedHeight, x, y;
|
||||||
PAINTSTRUCT ps;
|
PAINTSTRUCT ps;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
|
@ -350,38 +455,37 @@ ImageView_DrawImage(HWND hwnd)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GdipGetImageWidth(image, &uImgWidth);
|
GdipGetImageWidth(image, &ImageWidth);
|
||||||
GdipGetImageHeight(image, &uImgHeight);
|
GdipGetImageHeight(image, &ImageHeight);
|
||||||
|
|
||||||
if (GetClientRect(hwnd, &rect))
|
if (GetClientRect(hwnd, &rect))
|
||||||
{
|
{
|
||||||
FillRect(hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
|
FillRect(hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
|
||||||
|
|
||||||
if ((rect.right >= uImgWidth)&&(rect.bottom >= uImgHeight))
|
ZoomedWidth = (ImageWidth * ZoomPercents) / 100;
|
||||||
|
ZoomedHeight = (ImageHeight * ZoomPercents) / 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("ZoomPercents = %d, ZoomedWidth = %d, ZoomedHeight = %d\n",
|
||||||
|
ZoomPercents, ZoomedWidth, ZoomedWidth);
|
||||||
|
|
||||||
|
if (ZoomPercents % 100 == 0)
|
||||||
{
|
{
|
||||||
width = uImgWidth;
|
GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
|
||||||
height = uImgHeight;
|
GdipSetSmoothingMode(graphics, SmoothingModeNone);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
height = uImgHeight * (UINT)rect.right / uImgWidth;
|
GdipSetInterpolationMode(graphics, InterpolationModeHighQualityBilinear);
|
||||||
if (height <= rect.bottom)
|
GdipSetSmoothingMode(graphics, SmoothingModeHighQuality);
|
||||||
{
|
|
||||||
width = rect.right;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
width = uImgWidth * (UINT)rect.bottom / uImgHeight;
|
|
||||||
height = rect.bottom;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
y = (rect.bottom / 2) - (height / 2);
|
Rectangle(hdc, x - 1, y - 1, x + ZoomedWidth + 1, y + ZoomedHeight + 1);
|
||||||
x = (rect.right / 2) - (width / 2);
|
GdipDrawImageRectI(graphics, image, x, y, ZoomedWidth, ZoomedHeight);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
GdipDeleteGraphics(graphics);
|
GdipDeleteGraphics(graphics);
|
||||||
EndPaint(hwnd, &ps);
|
EndPaint(hwnd, &ps);
|
||||||
|
@ -524,6 +628,15 @@ ImageView_InitControls(HWND hwnd)
|
||||||
ImageView_CreateToolBar(hwnd);
|
ImageView_CreateToolBar(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
ImageView_OnMouseWheel(HWND hwnd, INT x, INT y, INT zDelta, UINT fwKeys)
|
||||||
|
{
|
||||||
|
if (zDelta != 0)
|
||||||
|
{
|
||||||
|
ZoomInOrOut(zDelta > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK
|
LRESULT CALLBACK
|
||||||
ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -567,10 +680,14 @@ ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IDC_ZOOMP:
|
case IDC_ZOOMP:
|
||||||
|
{
|
||||||
|
ZoomInOrOut(TRUE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case IDC_ZOOMM:
|
case IDC_ZOOMM:
|
||||||
|
{
|
||||||
|
ZoomInOrOut(FALSE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case IDC_SAVE:
|
case IDC_SAVE:
|
||||||
pSaveImageAs(hwnd);
|
pSaveImageAs(hwnd);
|
||||||
|
@ -597,6 +714,12 @@ ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
ImageView_OnMouseWheel(hwnd,
|
||||||
|
GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
|
||||||
|
(SHORT)HIWORD(wParam), (UINT)LOWORD(wParam));
|
||||||
|
break;
|
||||||
|
|
||||||
case WM_NOTIFY:
|
case WM_NOTIFY:
|
||||||
{
|
{
|
||||||
LPNMHDR pnmhdr = (LPNMHDR)lParam;
|
LPNMHDR pnmhdr = (LPNMHDR)lParam;
|
||||||
|
@ -660,6 +783,12 @@ ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||||
SendMessage(hToolBar, TB_AUTOSIZE, 0, 0);
|
SendMessage(hToolBar, TB_AUTOSIZE, 0, 0);
|
||||||
GetWindowRect(hToolBar, &rc);
|
GetWindowRect(hToolBar, &rc);
|
||||||
MoveWindow(hDispWnd, 1, 1, LOWORD(lParam) - 1, HIWORD(lParam) - (rc.bottom - rc.top) - 1, TRUE);
|
MoveWindow(hDispWnd, 1, 1, LOWORD(lParam) - 1, HIWORD(lParam) - (rc.bottom - rc.top) - 1, TRUE);
|
||||||
|
/* is it maximized or restored? */
|
||||||
|
if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED)
|
||||||
|
{
|
||||||
|
/* reset zoom */
|
||||||
|
ResetZoom();
|
||||||
|
}
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
|
@ -710,7 +839,7 @@ ImageView_CreateWindow(HWND hwnd, LPWSTR szFileName)
|
||||||
WndClass.style = CS_HREDRAW | CS_VREDRAW;
|
WndClass.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
WndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPICON));
|
WndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPICON));
|
||||||
WndClass.hCursor = LoadCursor(hInstance, IDC_ARROW);
|
WndClass.hCursor = LoadCursor(hInstance, IDC_ARROW);
|
||||||
WndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
WndClass.hbrBackground = NULL; /* less flicker */
|
||||||
|
|
||||||
if (!RegisterClass(&WndClass)) return -1;
|
if (!RegisterClass(&WndClass)) return -1;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue