https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f0179741d1a5aa67ee62a…
commit f0179741d1a5aa67ee62a0f33b07962b63a5fad1
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Fri Dec 15 15:16:50 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Fri Dec 15 15:16:50 2023 +0900
[SHIMGVW] Fix and improve zooming (#6167)
- Add WC_ZOOM window class and
use it for zooming.
- Add ZoomWnd_OnDraw function
and use it in ZoomWnd_OnPaint.
- Use memory bitmap to reduce flickering.
- Make rendering pixel-perfect.
CORE-19220
---
dll/win32/shimgvw/shimgvw.c | 360 ++++++++++++++++++++++++--------------------
dll/win32/shimgvw/shimgvw.h | 1 +
2 files changed, 200 insertions(+), 161 deletions(-)
diff --git a/dll/win32/shimgvw/shimgvw.c b/dll/win32/shimgvw/shimgvw.c
index 17dfc369e38..c84314b1828 100644
--- a/dll/win32/shimgvw/shimgvw.c
+++ b/dll/win32/shimgvw/shimgvw.c
@@ -21,16 +21,16 @@
#define SLIDESHOW_TIMER_ID 0xFACE
#define SLIDESHOW_TIMER_INTERVAL 5000 /* 5 seconds */
-HINSTANCE g_hInstance = NULL;
-HWND g_hMainWnd = NULL;
-HWND g_hwndFullscreen = NULL;
-SHIMGVW_SETTINGS g_Settings;
-SHIMGVW_FILENODE *g_pCurrentFile;
-GpImage *g_pImage = NULL;
+HINSTANCE g_hInstance = NULL;
+HWND g_hMainWnd = NULL;
+HWND g_hwndFullscreen = NULL;
+SHIMGVW_FILENODE * g_pCurrentFile = NULL;
+GpImage * g_pImage = NULL;
+SHIMGVW_SETTINGS g_Settings;
static const UINT s_ZoomSteps[] =
{
- 5, 10, 25, 50, 100, 125, 200, 300, 500, 1000
+ 5, 10, 25, 50, 100, 200, 300, 500, 1000, 2000, 4000
};
#define MIN_ZOOM s_ZoomSteps[0]
@@ -100,7 +100,6 @@ typedef struct tagPREVIEW_DATA
HWND m_hwndZoom;
HWND m_hwndToolBar;
INT m_nZoomPercents;
- WNDPROC m_fnPrevProc;
ANIME m_Anime; /* Animation */
} PREVIEW_DATA, *PPREVIEW_DATA;
@@ -116,30 +115,39 @@ Preview_IsMainWnd(HWND hwnd)
return hwnd == g_hMainWnd;
}
+static VOID
+Preview_RestartTimer(HWND hwnd)
+{
+ if (!Preview_IsMainWnd(hwnd))
+ {
+ KillTimer(hwnd, SLIDESHOW_TIMER_ID);
+ SetTimer(hwnd, SLIDESHOW_TIMER_ID, SLIDESHOW_TIMER_INTERVAL, NULL);
+ }
+}
+
static VOID
Preview_UpdateZoom(PPREVIEW_DATA pData, UINT NewZoom, BOOL bEnableBestFit, BOOL
bEnableRealSize)
{
BOOL bEnableZoomIn, bEnableZoomOut;
HWND hToolBar = pData->m_hwndToolBar;
- /* If zoom has not been changed, ignore it */
- if (pData->m_nZoomPercents == NewZoom)
- return;
-
pData->m_nZoomPercents = NewZoom;
/* Check if a zoom button of the toolbar must be grayed */
- bEnableZoomIn = (NewZoom < MAX_ZOOM);
+ bEnableZoomIn = (NewZoom < MAX_ZOOM);
bEnableZoomOut = (NewZoom > MIN_ZOOM);
/* Update toolbar buttons */
- SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_OUT, bEnableZoomOut);
- SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_IN, bEnableZoomIn);
- SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_BEST_FIT, bEnableBestFit);
- SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_REAL_SIZE, bEnableRealSize);
+ PostMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_OUT, bEnableZoomOut);
+ PostMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_IN, bEnableZoomIn);
+ PostMessageW(hToolBar, TB_ENABLEBUTTON, IDC_BEST_FIT, bEnableBestFit);
+ PostMessageW(hToolBar, TB_ENABLEBUTTON, IDC_REAL_SIZE, bEnableRealSize);
/* Redraw the display window */
- InvalidateRect(pData->m_hwndZoom, NULL, FALSE);
+ InvalidateRect(pData->m_hwndZoom, NULL, TRUE);
+
+ /* Restart timer if necessary */
+ Preview_RestartTimer(pData->m_hwnd);
}
static VOID
@@ -389,8 +397,8 @@ static VOID
Preview_UpdateUI(PPREVIEW_DATA pData)
{
BOOL bEnable = (g_pImage != NULL);
- SendMessageW(pData->m_hwndToolBar, TB_ENABLEBUTTON, IDC_SAVEAS, bEnable);
- SendMessageW(pData->m_hwndToolBar, TB_ENABLEBUTTON, IDC_PRINT, bEnable);
+ PostMessageW(pData->m_hwndToolBar, TB_ENABLEBUTTON, IDC_SAVEAS, bEnable);
+ PostMessageW(pData->m_hwndToolBar, TB_ENABLEBUTTON, IDC_PRINT, bEnable);
if (!Preview_IsMainWnd(pData->m_hwnd))
Preview_ResetZoom(pData);
@@ -530,7 +538,7 @@ pFreeFileList(SHIMGVW_FILENODE *root)
}
}
-static HBRUSH CreateCheckerBoardBrush(HDC hdc)
+static HBRUSH CreateCheckerBoardBrush(VOID)
{
static const CHAR pattern[] =
"\x28\x00\x00\x00\x10\x00\x00\x00\x10\x00\x00\x00\x01\x00\x04\x00\x00\x00"
@@ -551,59 +559,63 @@ static HBRUSH CreateCheckerBoardBrush(HDC hdc)
}
static VOID
-ZoomWnd_OnPaint(PPREVIEW_DATA pData, HWND hwnd)
+ZoomWnd_OnDraw(
+ PPREVIEW_DATA pData,
+ HDC hdc,
+ LPRECT prcPaint,
+ LPRECT prcClient)
{
GpGraphics *graphics;
- INT ZoomedWidth, ZoomedHeight, x, y;
- PAINTSTRUCT ps;
- RECT rect, margin;
- HDC hdc;
+ INT ZoomedWidth, ZoomedHeight;
+ RECT rect, rcClient = *prcClient;
+ HDC hdcMem;
HBRUSH hBrush;
HPEN hPen;
- HGDIOBJ hbrOld, hPenOld, hFontOld;
+ HGDIOBJ hbrOld, hbmOld, hPenOld;
UINT uFlags;
+ HBITMAP hbmMem;
+ SIZE paintSize = { prcPaint->right - prcPaint->left, prcPaint->bottom -
prcPaint->top };
+ COLORREF color0, color1;
+ GpImageAttributes *imageAttributes;
- hdc = BeginPaint(hwnd, &ps);
- if (!hdc)
- {
- DPRINT1("BeginPaint() failed\n");
- return;
- }
-
- GdipCreateFromHDC(hdc, &graphics);
- if (!graphics)
- {
- DPRINT1("GdipCreateFromHDC() failed\n");
- return;
- }
-
- GetClientRect(hwnd, &rect);
+ /* We use a memory bitmap to reduce flickering */
+ hdcMem = CreateCompatibleDC(hdc);
+ hbmMem = CreateCompatibleBitmap(hdc, paintSize.cx, paintSize.cy);
+ hbmOld = SelectObject(hdcMem, hbmMem);
+ /* Choose colors */
if (Preview_IsMainWnd(pData->m_hwnd))
{
- hPen = (HPEN)GetStockObject(BLACK_PEN);
- hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
- SetTextColor(hdc, RGB(0, 0, 0)); /* Black text */
+ color0 = GetSysColor(COLOR_WINDOW);
+ color1 = GetSysColor(COLOR_WINDOWTEXT);
}
else
{
- hPen = (HPEN)GetStockObject(WHITE_PEN);
- hBrush = (HBRUSH)GetStockObject(BLACK_BRUSH);
- SetTextColor(hdc, RGB(255, 255, 255)); /* White text */
+ color0 = RGB(0, 0, 0);
+ color1 = RGB(255, 255, 255);
}
+ hBrush = CreateSolidBrush(color0);
+ SetBkColor(hdcMem, color0);
+
+ hPen = CreatePen(PS_SOLID, 1, color1);
+ SetTextColor(hdcMem, color1);
+
+ /* Fill background */
+ SetRect(&rect, 0, 0, paintSize.cx, paintSize.cy);
+ FillRect(hdcMem, &rect, hBrush);
+
+ DeleteObject(hBrush);
+
if (g_pImage == NULL)
{
WCHAR szText[128];
LoadStringW(g_hInstance, IDS_NOPREVIEW, szText, _countof(szText));
- FillRect(hdc, &rect, hBrush);
-
- hFontOld = SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
- SetBkMode(hdc, TRANSPARENT);
- DrawTextW(hdc, szText, -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER |
- DT_NOPREFIX);
- SelectObject(hdc, hFontOld);
+ SelectObject(hdcMem, GetStockFont(DEFAULT_GUI_FONT));
+ OffsetRect(&rcClient, -prcPaint->left, -prcPaint->top);
+ DrawTextW(hdcMem, szText, -1, &rcClient, DT_SINGLELINE | DT_CENTER |
DT_VCENTER |
+ DT_NOPREFIX);
}
else
{
@@ -612,34 +624,17 @@ ZoomWnd_OnPaint(PPREVIEW_DATA pData, HWND hwnd)
GdipGetImageWidth(g_pImage, &ImageWidth);
GdipGetImageHeight(g_pImage, &ImageHeight);
- ZoomedWidth = (ImageWidth * pData->m_nZoomPercents) / 100;
+ ZoomedWidth = (ImageWidth * pData->m_nZoomPercents) / 100;
ZoomedHeight = (ImageHeight * pData->m_nZoomPercents) / 100;
- x = (rect.right - ZoomedWidth) / 2;
- y = (rect.bottom - ZoomedHeight) / 2;
-
- // Fill top part
- margin = rect;
- margin.bottom = y - 1;
- FillRect(hdc, &margin, hBrush);
- // Fill bottom part
- margin.top = y + ZoomedHeight + 1;
- margin.bottom = rect.bottom;
- FillRect(hdc, &margin, hBrush);
- // Fill left part
- margin.top = y - 1;
- margin.bottom = y + ZoomedHeight + 1;
- margin.right = x - 1;
- FillRect(hdc, &margin, hBrush);
- // Fill right part
- margin.left = x + ZoomedWidth + 1;
- margin.right = rect.right;
- FillRect(hdc, &margin, hBrush);
-
- DPRINT("x = %d, y = %d, ImageWidth = %u, ImageHeight = %u\n");
- DPRINT("rect.right = %ld, rect.bottom = %ld\n", rect.right,
rect.bottom);
- DPRINT("m_nZoomPercents = %d, ZoomedWidth = %d, ZoomedHeight = %d\n",
- pData->m_nZoomPercents, ZoomedWidth, ZoomedWidth);
+ GdipCreateFromHDC(hdcMem, &graphics);
+ if (!graphics)
+ {
+ DPRINT1("error: GdipCreateFromHDC\n");
+ return;
+ }
+
+ GdipGetImageFlags(g_pImage, &uFlags);
if (pData->m_nZoomPercents % 100 == 0)
{
@@ -652,30 +647,61 @@ ZoomWnd_OnPaint(PPREVIEW_DATA pData, HWND hwnd)
GdipSetSmoothingMode(graphics, SmoothingModeHighQuality);
}
- uFlags = 0;
- GdipGetImageFlags(g_pImage, &uFlags);
+ rect.left = (rcClient.right - ZoomedWidth ) / 2;
+ rect.top = (rcClient.bottom - ZoomedHeight) / 2;
+ rect.right = rect.left + ZoomedWidth;
+ rect.bottom = rect.top + ZoomedHeight;
+ OffsetRect(&rect, -prcPaint->left, -prcPaint->top);
- hPenOld = SelectObject(hdc, hPen);
+ InflateRect(&rect, +1, +1); /* Add Rectangle() pen width */
+
+ /* Draw a rectangle. Fill by checker board if necessary */
if (uFlags & (ImageFlagsHasAlpha | ImageFlagsHasTranslucent))
- {
- HBRUSH hbr = CreateCheckerBoardBrush(hdc);
- hbrOld = SelectObject(hdc, hbr);
- Rectangle(hdc, x - 1, y - 1, x + ZoomedWidth + 1, y + ZoomedHeight + 1);
- SelectObject(hdc, hbrOld);
- DeleteObject(hbr);
- }
+ hbrOld = SelectObject(hdcMem, CreateCheckerBoardBrush());
else
- {
- hbrOld = SelectObject(hdc, GetStockObject(NULL_BRUSH));
- Rectangle(hdc, x - 1, y - 1, x + ZoomedWidth + 1, y + ZoomedHeight + 1);
- SelectObject(hdc, hbrOld);
- }
- SelectObject(hdc, hPenOld);
+ hbrOld = SelectObject(hdcMem, GetStockBrush(NULL_BRUSH));
+ hPenOld = SelectObject(hdcMem, hPen);
+ Rectangle(hdcMem, rect.left, rect.top, rect.right, rect.bottom);
+ DeleteObject(SelectObject(hdcMem, hbrOld));
+ DeleteObject(SelectObject(hdcMem, hPenOld));
+
+ InflateRect(&rect, -1, -1); /* Subtract Rectangle() pen width */
+
+ /* Image attributes are required to draw image correctly */
+ GdipCreateImageAttributes(&imageAttributes);
+ GdipSetImageAttributesWrapMode(imageAttributes, WrapModeTile,
+ GetBkColor(hdcMem) | 0xFF000000, TRUE);
+
+ /* Draw image. -0.5f is used for interpolation */
+ GdipDrawImageRectRect(graphics, g_pImage,
+ rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ -0.5f, -0.5f, ImageWidth, ImageHeight,
+ UnitPixel, imageAttributes, NULL, NULL);
+
+ GdipDisposeImageAttributes(imageAttributes);
+ GdipDeleteGraphics(graphics);
+ }
- GdipDrawImageRectI(graphics, g_pImage, x, y, ZoomedWidth, ZoomedHeight);
+ BitBlt(hdc, prcPaint->left, prcPaint->top, paintSize.cx, paintSize.cy, hdcMem,
0, 0, SRCCOPY);
+ DeleteObject(SelectObject(hdcMem, hbmOld));
+ DeleteDC(hdcMem);
+}
+
+static VOID
+ZoomWnd_OnPaint(PPREVIEW_DATA pData, HWND hwnd)
+{
+ PAINTSTRUCT ps;
+ HDC hDC;
+ RECT rcClient;
+
+ hDC = BeginPaint(hwnd, &ps);
+ if (hDC)
+ {
+ GetClientRect(hwnd, &rcClient);
+ ZoomWnd_OnDraw(pData, hDC, &ps.rcPaint, &rcClient);
+ EndPaint(hwnd, &ps);
}
- GdipDeleteGraphics(graphics);
- EndPaint(hwnd, &ps);
}
static VOID
@@ -727,13 +753,12 @@ Preview_CreateToolBar(PPREVIEW_DATA pData)
HWND hwndToolBar;
HIMAGELIST hImageList, hOldImageList;
DWORD style = WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS;
- DWORD exstyle = 0;
if (!Preview_IsMainWnd(pData->m_hwnd))
return TRUE; /* FIXME */
style |= CCS_BOTTOM;
- hwndToolBar = CreateWindowExW(exstyle, TOOLBARCLASSNAMEW, NULL, style,
+ hwndToolBar = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, style,
0, 0, 0, 0, pData->m_hwnd, NULL, g_hInstance,
NULL);
if (!hwndToolBar)
return FALSE;
@@ -762,12 +787,39 @@ Preview_CreateToolBar(PPREVIEW_DATA pData)
return TRUE;
}
+static VOID
+Preview_EndSlideShow(HWND hwnd)
+{
+ if (Preview_IsMainWnd(hwnd))
+ return;
+
+ KillTimer(hwnd, SLIDESHOW_TIMER_ID);
+ ShowWindow(hwnd, SW_HIDE);
+ ShowWindow(g_hMainWnd, SW_SHOWNORMAL);
+ Preview_ResetZoom(Preview_GetData(g_hMainWnd));
+}
+
+static VOID
+ZoomWnd_OnButtonDown(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ HWND hParent = GetParent(hwnd);
+ if (!Preview_IsMainWnd(hParent))
+ Preview_EndSlideShow(hParent);
+}
+
LRESULT CALLBACK
ZoomWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PPREVIEW_DATA pData = Preview_GetData(hwnd);
switch (uMsg)
{
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ {
+ ZoomWnd_OnButtonDown(hwnd, uMsg, wParam, lParam);
+ break;
+ }
case WM_PAINT:
{
ZoomWnd_OnPaint(pData, hwnd);
@@ -781,7 +833,7 @@ ZoomWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
default:
{
- return CallWindowProcW(pData->m_fnPrevProc, hwnd, uMsg, wParam, lParam);
+ return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
}
return 0;
@@ -790,21 +842,29 @@ ZoomWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static BOOL
Preview_OnCreate(HWND hwnd, LPCREATESTRUCT pCS)
{
+ DWORD exstyle = 0;
HWND hwndZoom;
PPREVIEW_DATA pData = QuickAlloc(sizeof(PREVIEW_DATA), TRUE);
pData->m_hwnd = hwnd;
SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)pData);
+ DragAcceptFiles(hwnd, TRUE);
+
if (g_hMainWnd == NULL)
+ {
g_hMainWnd = hwnd;
+ exstyle |= WS_EX_CLIENTEDGE;
+ }
else if (g_hwndFullscreen == NULL)
+ {
g_hwndFullscreen = hwnd;
+ }
else
+ {
return FALSE;
+ }
- DragAcceptFiles(hwnd, TRUE);
-
- hwndZoom = CreateWindowExW(WS_EX_CLIENTEDGE, WC_STATIC, NULL, WS_CHILD | WS_VISIBLE,
+ hwndZoom = CreateWindowExW(exstyle, WC_ZOOM, NULL, WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, hwnd, NULL, g_hInstance, NULL);
if (!hwndZoom)
{
@@ -814,10 +874,7 @@ Preview_OnCreate(HWND hwnd, LPCREATESTRUCT pCS)
pData->m_hwndZoom = hwndZoom;
SetWindowLongPtrW(hwndZoom, GWLP_USERDATA, (LONG_PTR)pData);
-
- SetClassLongPtr(pData->m_hwndZoom, GCL_STYLE, CS_HREDRAW | CS_VREDRAW);
- pData->m_fnPrevProc = (WNDPROC)SetWindowLongPtrW(pData->m_hwndZoom,
- GWLP_WNDPROC, (LPARAM)ZoomWndProc);
+ Anime_SetTimerWnd(&pData->m_Anime, pData->m_hwndZoom);
if (!Preview_CreateToolBar(pData))
{
@@ -825,8 +882,6 @@ Preview_OnCreate(HWND hwnd, LPCREATESTRUCT pCS)
return FALSE;
}
- Anime_SetTimerWnd(&pData->m_Anime, pData->m_hwndZoom);
-
if (pCS && pCS->lpCreateParams)
{
LPCWSTR pszFileName = (LPCWSTR)pCS->lpCreateParams;
@@ -867,6 +922,7 @@ Preview_OnMoveSize(HWND hwnd)
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hwnd, &wp);
+ /* Remember window position and size */
prc = &wp.rcNormalPosition;
g_Settings.X = prc->left;
g_Settings.Y = prc->top;
@@ -906,18 +962,6 @@ Preview_OnSize(HWND hwnd)
}
}
-static VOID
-Preview_EndSlideShow(HWND hwnd)
-{
- if (Preview_IsMainWnd(hwnd))
- return;
-
- KillTimer(hwnd, SLIDESHOW_TIMER_ID);
- ShowWindow(hwnd, SW_HIDE);
- ShowWindow(g_hMainWnd, SW_SHOWNORMAL);
- Preview_ResetZoom(Preview_GetData(g_hMainWnd));
-}
-
static VOID
Preview_Delete(PPREVIEW_DATA pData)
{
@@ -995,37 +1039,35 @@ Preview_Edit(HWND hwnd)
}
static VOID
-Preview_StartSlideShow(PPREVIEW_DATA pData)
+Preview_ToggleSlideShow(PPREVIEW_DATA pData)
{
- HWND hwnd = g_hwndFullscreen;
- DWORD style = WS_POPUP | WS_CLIPSIBLINGS, exstyle = WS_EX_TOPMOST;
-
- ShowWindow(pData->m_hwnd, SW_HIDE);
-
- if (!IsWindow(hwnd))
+ if (!IsWindow(g_hwndFullscreen))
{
+ DWORD style = WS_POPUP | WS_CLIPSIBLINGS, exstyle = WS_EX_TOPMOST;
WCHAR szTitle[256];
LoadStringW(g_hInstance, IDS_APPTITLE, szTitle, _countof(szTitle));
- hwnd = CreateWindowExW(exstyle, WC_PREVIEW, szTitle, style,
- 0, 0, 0, 0, NULL, NULL, g_hInstance, NULL);
+ g_hwndFullscreen = CreateWindowExW(exstyle, WC_PREVIEW, szTitle, style,
+ 0, 0, 0, 0, NULL, NULL, g_hInstance, NULL);
}
- ShowWindow(hwnd, SW_SHOWMAXIMIZED);
- UpdateWindow(hwnd);
-
- SetTimer(hwnd, SLIDESHOW_TIMER_ID, SLIDESHOW_TIMER_INTERVAL, NULL);
+ if (IsWindowVisible(g_hwndFullscreen))
+ {
+ ShowWindow(g_hwndFullscreen, SW_HIDE);
+ ShowWindow(g_hMainWnd, SW_SHOWNORMAL);
+ KillTimer(g_hwndFullscreen, SLIDESHOW_TIMER_ID);
+ }
+ else
+ {
+ ShowWindow(g_hMainWnd, SW_HIDE);
+ ShowWindow(g_hwndFullscreen, SW_SHOWMAXIMIZED);
+ Preview_RestartTimer(g_hwndFullscreen);
+ }
}
static VOID
Preview_GoNextPic(PPREVIEW_DATA pData, BOOL bNext)
{
- HWND hwnd = pData->m_hwnd;
- if (!Preview_IsMainWnd(hwnd))
- {
- KillTimer(hwnd, SLIDESHOW_TIMER_ID);
- SetTimer(hwnd, SLIDESHOW_TIMER_ID, SLIDESHOW_TIMER_INTERVAL, NULL);
- }
-
+ Preview_RestartTimer(pData->m_hwnd);
if (g_pCurrentFile)
{
if (bNext)
@@ -1061,10 +1103,7 @@ Preview_OnCommand(HWND hwnd, UINT nCommandID)
break;
case IDC_SLIDE_SHOW:
- if (Preview_IsMainWnd(hwnd))
- Preview_StartSlideShow(pData);
- else
- Preview_EndSlideShow(hwnd);
+ Preview_ToggleSlideShow(pData);
break;
case IDC_ZOOM_IN:
@@ -1162,7 +1201,6 @@ Preview_OnDestroy(HWND hwnd)
Anime_FreeInfo(&pData->m_Anime);
- SetWindowLongPtrW(pData->m_hwndZoom, GWLP_WNDPROC,
(LPARAM)pData->m_fnPrevProc);
SetWindowLongPtrW(pData->m_hwndZoom, GWLP_USERDATA, 0);
DestroyWindow(pData->m_hwndZoom);
pData->m_hwndZoom = NULL;
@@ -1170,6 +1208,7 @@ Preview_OnDestroy(HWND hwnd)
DestroyWindow(pData->m_hwndToolBar);
pData->m_hwndToolBar = NULL;
+ SetWindowLongPtrW(pData->m_hwnd, GWLP_USERDATA, 0);
QuickFree(pData);
PostQuitMessage(0);
@@ -1190,13 +1229,6 @@ Preview_OnDropFiles(HWND hwnd, HDROP hDrop)
DragFinish(hDrop);
}
-static VOID
-Preview_OnButtonDown(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- if (!Preview_IsMainWnd(hwnd))
- Preview_EndSlideShow(hwnd);
-}
-
LRESULT CALLBACK
PreviewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
@@ -1245,11 +1277,11 @@ PreviewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
lParam)
Preview_OnDropFiles(hwnd, (HDROP)wParam);
break;
}
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDOWN:
+ case WM_SYSCOLORCHANGE:
{
- Preview_OnButtonDown(hwnd, uMsg, wParam, lParam);
+ PPREVIEW_DATA pData = Preview_GetData(hwnd);
+ InvalidateRect(pData->m_hwnd, NULL, TRUE);
+ InvalidateRect(pData->m_hwndZoom, NULL, TRUE);
break;
}
case WM_DESTROY:
@@ -1311,7 +1343,13 @@ ImageView_Main(HWND hwnd, LPCWSTR szFileName)
WndClass.style = CS_HREDRAW | CS_VREDRAW;
WndClass.hIcon = LoadIconW(g_hInstance, MAKEINTRESOURCEW(IDI_APP_ICON));
WndClass.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
- WndClass.hbrBackground = NULL; /* less flicker */
+ WndClass.hbrBackground = (HBRUSH)UlongToHandle(COLOR_3DFACE + 1);
+ if (!RegisterClassW(&WndClass))
+ return -1;
+ WndClass.lpszClassName = WC_ZOOM;
+ WndClass.lpfnWndProc = ZoomWndProc;
+ WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
+ WndClass.hbrBackground = GetStockBrush(NULL_BRUSH); /* less flicker */
if (!RegisterClassW(&WndClass))
return -1;
diff --git a/dll/win32/shimgvw/shimgvw.h b/dll/win32/shimgvw/shimgvw.h
index cebbaea06b3..0506c2a6af2 100644
--- a/dll/win32/shimgvw/shimgvw.h
+++ b/dll/win32/shimgvw/shimgvw.h
@@ -49,6 +49,7 @@ typedef struct tagSHIMGVW_FILENODE
} SHIMGVW_FILENODE;
#define WC_PREVIEW L"ShImgVw:CPreviewWnd"
+#define WC_ZOOM L"ShImgVw:CZoomWnd"
/* Animation */
typedef struct tagANIME