https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f0179741d1a5aa67ee62a0f33b07962b63a5fad1
commit f0179741d1a5aa67ee62a0f33b07962b63a5fad1 Author: Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> AuthorDate: Fri Dec 15 15:16:50 2023 +0900 Commit: GitHub <nore...@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