https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e62d12b1401f2f9e44673…
commit e62d12b1401f2f9e4467301d12b77c5c74572639
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Dec 16 19:45:37 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Dec 16 19:45:37 2023 +0900
[SHIMGVW] Enable scrolling (#6172)
- Add m_xScrollOffset and m_yScrollOffset to
PREVIEW_DATA structure.
- Add ZoomWnd_UpdateScroll helper function.
- Handle WM_HSCROLL and WM_VSCROLL messages.
- Enable mouse wheel scrolling.
CORE-19358
---
dll/win32/shimgvw/shimgvw.c | 214 +++++++++++++++++++++++++++++++++++++++-----
dll/win32/shimgvw/shimgvw.h | 1 -
2 files changed, 192 insertions(+), 23 deletions(-)
diff --git a/dll/win32/shimgvw/shimgvw.c b/dll/win32/shimgvw/shimgvw.c
index c84314b1828..b04363ed896 100644
--- a/dll/win32/shimgvw/shimgvw.c
+++ b/dll/win32/shimgvw/shimgvw.c
@@ -101,6 +101,8 @@ typedef struct tagPREVIEW_DATA
HWND m_hwndToolBar;
INT m_nZoomPercents;
ANIME m_Anime; /* Animation */
+ INT m_xScrollOffset;
+ INT m_yScrollOffset;
} PREVIEW_DATA, *PPREVIEW_DATA;
static inline PPREVIEW_DATA
@@ -125,6 +127,78 @@ Preview_RestartTimer(HWND hwnd)
}
}
+static VOID
+ZoomWnd_UpdateScroll(PPREVIEW_DATA pData, HWND hwnd, BOOL bResetPos)
+{
+ RECT rcClient;
+ UINT ImageWidth, ImageHeight, ZoomedWidth, ZoomedHeight;
+ SCROLLINFO si;
+ BOOL bShowHorz, bShowVert;
+
+ if (bResetPos)
+ pData->m_xScrollOffset = pData->m_yScrollOffset = 0;
+
+ if (!g_pImage)
+ {
+ ShowScrollBar(hwnd, SB_BOTH, FALSE);
+ InvalidateRect(hwnd, NULL, TRUE);
+ return;
+ }
+
+ GdipGetImageWidth(g_pImage, &ImageWidth);
+ GdipGetImageHeight(g_pImage, &ImageHeight);
+
+ ZoomedWidth = (ImageWidth * pData->m_nZoomPercents) / 100;
+ ZoomedHeight = (ImageHeight * pData->m_nZoomPercents) / 100;
+
+ GetClientRect(hwnd, &rcClient);
+
+ bShowHorz = (rcClient.right < ZoomedWidth);
+ bShowVert = (rcClient.bottom < ZoomedHeight);
+ ShowScrollBar(hwnd, SB_HORZ, bShowHorz);
+ ShowScrollBar(hwnd, SB_VERT, bShowVert);
+
+ GetClientRect(hwnd, &rcClient);
+
+ ZeroMemory(&si, sizeof(si));
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_ALL;
+
+ if (bShowHorz)
+ {
+ GetScrollInfo(hwnd, SB_HORZ, &si);
+ si.nPage = rcClient.right;
+ si.nMin = 0;
+ si.nMax = ZoomedWidth;
+ si.nPos = (ZoomedWidth - rcClient.right) / 2 + pData->m_xScrollOffset;
+ si.nPos = max(min(si.nPos, si.nMax - (INT)si.nPage), si.nMin);
+ SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
+ pData->m_xScrollOffset = si.nPos - (ZoomedWidth - rcClient.right) / 2;
+ }
+ else
+ {
+ pData->m_xScrollOffset = 0;
+ }
+
+ if (bShowVert)
+ {
+ GetScrollInfo(hwnd, SB_VERT, &si);
+ si.nPage = rcClient.bottom;
+ si.nMin = 0;
+ si.nMax = ZoomedHeight;
+ si.nPos = (ZoomedHeight - rcClient.bottom) / 2 + pData->m_yScrollOffset;
+ si.nPos = max(min(si.nPos, si.nMax - (INT)si.nPage), si.nMin);
+ SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
+ pData->m_yScrollOffset = si.nPos - (ZoomedHeight - rcClient.bottom) / 2;
+ }
+ else
+ {
+ pData->m_yScrollOffset = 0;
+ }
+
+ InvalidateRect(hwnd, NULL, TRUE);
+}
+
static VOID
Preview_UpdateZoom(PPREVIEW_DATA pData, UINT NewZoom, BOOL bEnableBestFit, BOOL
bEnableRealSize)
{
@@ -148,6 +222,9 @@ Preview_UpdateZoom(PPREVIEW_DATA pData, UINT NewZoom, BOOL
bEnableBestFit, BOOL
/* Restart timer if necessary */
Preview_RestartTimer(pData->m_hwnd);
+
+ /* Update scroll info */
+ ZoomWnd_UpdateScroll(pData, pData->m_hwndZoom, FALSE);
}
static VOID
@@ -399,11 +476,15 @@ Preview_UpdateUI(PPREVIEW_DATA pData)
BOOL bEnable = (g_pImage != NULL);
PostMessageW(pData->m_hwndToolBar, TB_ENABLEBUTTON, IDC_SAVEAS, bEnable);
PostMessageW(pData->m_hwndToolBar, TB_ENABLEBUTTON, IDC_PRINT, bEnable);
+}
+static VOID
+Preview_UpdateImage(PPREVIEW_DATA pData)
+{
if (!Preview_IsMainWnd(pData->m_hwnd))
Preview_ResetZoom(pData);
- InvalidateRect(pData->m_hwndZoom, NULL, FALSE);
+ ZoomWnd_UpdateScroll(pData, pData->m_hwndZoom, TRUE);
}
static SHIMGVW_FILENODE*
@@ -651,7 +732,9 @@ ZoomWnd_OnDraw(
rect.top = (rcClient.bottom - ZoomedHeight) / 2;
rect.right = rect.left + ZoomedWidth;
rect.bottom = rect.top + ZoomedHeight;
- OffsetRect(&rect, -prcPaint->left, -prcPaint->top);
+ OffsetRect(&rect,
+ -prcPaint->left - pData->m_xScrollOffset,
+ -prcPaint->top - pData->m_yScrollOffset);
InflateRect(&rect, +1, +1); /* Add Rectangle() pen width */
@@ -807,6 +890,98 @@ ZoomWnd_OnButtonDown(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
lParam)
Preview_EndSlideShow(hParent);
}
+static VOID
+ZoomWnd_OnHVScroll(PPREVIEW_DATA pData, HWND hwnd, WPARAM wParam, BOOL bVertical)
+{
+ UINT ImageWidth, ImageHeight, ZoomedWidth, ZoomedHeight;
+ RECT rcClient;
+ UINT nBar = (bVertical ? SB_VERT : SB_HORZ);
+ SCROLLINFO si = { sizeof(si), SIF_ALL };
+ GetScrollInfo(hwnd, nBar, &si);
+
+ if (!g_pImage)
+ return;
+
+ if (bVertical)
+ {
+ if (!(GetWindowLongPtrW(hwnd, GWL_STYLE) & WS_VSCROLL))
+ return;
+ }
+ else
+ {
+ if (!(GetWindowLongPtrW(hwnd, GWL_STYLE) & WS_HSCROLL))
+ return;
+ }
+
+ switch (LOWORD(wParam))
+ {
+ case SB_THUMBTRACK:
+ case SB_THUMBPOSITION:
+ si.nPos = (SHORT)HIWORD(wParam);
+ break;
+ case SB_LINELEFT:
+ si.nPos -= 48;
+ break;
+ case SB_LINERIGHT:
+ si.nPos += 48;
+ break;
+ case SB_PAGELEFT:
+ si.nPos -= si.nPage;
+ break;
+ case SB_PAGERIGHT:
+ si.nPos += si.nPage;
+ break;
+ }
+
+ si.fMask = SIF_POS;
+ SetScrollInfo(hwnd, nBar, &si, TRUE);
+ GetScrollInfo(hwnd, nBar, &si);
+
+ GetClientRect(hwnd, &rcClient);
+
+ if (bVertical)
+ {
+ GdipGetImageHeight(g_pImage, &ImageHeight);
+ ZoomedHeight = (ImageHeight * pData->m_nZoomPercents) / 100;
+ pData->m_yScrollOffset = si.nPos - (ZoomedHeight - rcClient.bottom) / 2;
+ }
+ else
+ {
+ GdipGetImageWidth(g_pImage, &ImageWidth);
+ ZoomedWidth = (ImageWidth * pData->m_nZoomPercents) / 100;
+ pData->m_xScrollOffset = si.nPos - (ZoomedWidth - rcClient.right) / 2;
+ }
+
+ InvalidateRect(hwnd, NULL, TRUE);
+}
+
+static VOID
+ZoomWnd_OnMouseWheel(HWND hwnd, INT x, INT y, INT zDelta, UINT fwKeys)
+{
+ PPREVIEW_DATA pData = Preview_GetData(hwnd);
+ if (zDelta == 0)
+ return;
+
+ if (GetKeyState(VK_CONTROL) < 0)
+ {
+ Preview_ZoomInOrOut(pData, zDelta > 0);
+ }
+ else if (GetKeyState(VK_SHIFT) < 0)
+ {
+ if (zDelta > 0)
+ SendMessageW(hwnd, WM_HSCROLL, SB_LINELEFT, 0);
+ else
+ SendMessageW(hwnd, WM_HSCROLL, SB_LINERIGHT, 0);
+ }
+ else
+ {
+ if (zDelta > 0)
+ SendMessageW(hwnd, WM_VSCROLL, SB_LINEUP, 0);
+ else
+ SendMessageW(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);
+ }
+}
+
LRESULT CALLBACK
ZoomWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
@@ -825,6 +1000,16 @@ ZoomWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
ZoomWnd_OnPaint(pData, hwnd);
break;
}
+ case WM_MOUSEWHEEL:
+ {
+ ZoomWnd_OnMouseWheel(hwnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
+ (SHORT)HIWORD(wParam), (UINT)LOWORD(wParam));
+ break;
+ }
+ case WM_HSCROLL:
+ case WM_VSCROLL:
+ ZoomWnd_OnHVScroll(pData, hwnd, wParam, uMsg == WM_VSCROLL);
+ break;
case WM_TIMER:
{
if (Anime_OnTimer(&pData->m_Anime, wParam))
@@ -893,23 +1078,13 @@ Preview_OnCreate(HWND hwnd, LPCREATESTRUCT pCS)
g_pCurrentFile = pBuildFileList(szFile);
Preview_pLoadImageFromNode(pData, g_pCurrentFile);
+ Preview_UpdateImage(pData);
Preview_UpdateUI(pData);
}
return TRUE;
}
-static VOID
-Preview_OnMouseWheel(HWND hwnd, INT x, INT y, INT zDelta, UINT fwKeys)
-{
- PPREVIEW_DATA pData = Preview_GetData(hwnd);
- if (zDelta != 0)
- {
- if (GetKeyState(VK_CONTROL) < 0)
- Preview_ZoomInOrOut(pData, zDelta > 0);
- }
-}
-
static VOID
Preview_OnMoveSize(HWND hwnd)
{
@@ -1075,6 +1250,7 @@ Preview_GoNextPic(PPREVIEW_DATA pData, BOOL bNext)
else
g_pCurrentFile = g_pCurrentFile->Prev;
Preview_pLoadImageFromNode(pData, g_pCurrentFile);
+ Preview_UpdateImage(pData);
Preview_UpdateUI(pData);
}
}
@@ -1140,7 +1316,7 @@ Preview_OnCommand(HWND hwnd, UINT nCommandID)
if (g_pImage)
{
GdipImageRotateFlip(g_pImage, Rotate270FlipNone);
- Preview_UpdateUI(pData);
+ Preview_UpdateImage(pData);
}
break;
@@ -1148,18 +1324,18 @@ Preview_OnCommand(HWND hwnd, UINT nCommandID)
if (g_pImage)
{
GdipImageRotateFlip(g_pImage, Rotate90FlipNone);
- Preview_UpdateUI(pData);
+ Preview_UpdateImage(pData);
}
break;
case IDC_DELETE:
Preview_Delete(pData);
+ Preview_UpdateImage(pData);
Preview_UpdateUI(pData);
break;
case IDC_MODIFY:
Preview_Edit(hwnd);
- Preview_UpdateUI(pData);
break;
default:
@@ -1245,12 +1421,6 @@ PreviewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Preview_OnCommand(hwnd, LOWORD(wParam));
break;
}
- case WM_MOUSEWHEEL:
- {
- Preview_OnMouseWheel(hwnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
- (SHORT)HIWORD(wParam), (UINT)LOWORD(wParam));
- break;
- }
case WM_NOTIFY:
{
return Preview_OnNotify(hwnd, (LPNMHDR)lParam);
diff --git a/dll/win32/shimgvw/shimgvw.h b/dll/win32/shimgvw/shimgvw.h
index 0506c2a6af2..776da7f849c 100644
--- a/dll/win32/shimgvw/shimgvw.h
+++ b/dll/win32/shimgvw/shimgvw.h
@@ -24,7 +24,6 @@
#include <shlwapi.h>
#include <strsafe.h>
-#define NDEBUG
#include <debug.h>
#include "resource.h"