https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a141c911351641d6aa2818...
commit a141c911351641d6aa2818affab8616bb4152b3b Author: Carlo Bramini 30959007+carlo-bramini@users.noreply.github.com AuthorDate: Mon Mar 1 15:40:06 2021 +0100 Commit: GitHub noreply@github.com CommitDate: Mon Mar 1 23:40:06 2021 +0900
[SHIMGVW] Improve zooming feature and realize image edit (#3473)
* [SHIMGVW] Add OLE32 for CoInitializeEx() * Implemented support for effective image size (100%). * Fix bug that could leave one of the zoom buttons if 100% size button is now pressed. * Replace a CreateWindowEx() with CreateWindowExW(). * Added stub for image delete function. * Implemented support for 'Modify' button. * [SHIMGVW] Added CoUninitialize() * [SHIMGVW] Pair CoUninitialize with CoInitializeEx --- dll/win32/shimgvw/CMakeLists.txt | 2 +- dll/win32/shimgvw/shimgvw.c | 155 ++++++++++++++++++++++++++++++--------- 2 files changed, 120 insertions(+), 37 deletions(-)
diff --git a/dll/win32/shimgvw/CMakeLists.txt b/dll/win32/shimgvw/CMakeLists.txt index 43e9f10c839..11df2db4098 100644 --- a/dll/win32/shimgvw/CMakeLists.txt +++ b/dll/win32/shimgvw/CMakeLists.txt @@ -11,5 +11,5 @@ list(APPEND SOURCE add_library(shimgvw MODULE ${SOURCE}) set_module_type(shimgvw win32dll UNICODE) target_link_libraries(shimgvw wine) -add_importlibs(shimgvw advapi32 comctl32 user32 gdi32 shell32 gdiplus comdlg32 shlwapi msvcrt kernel32 ntdll) +add_importlibs(shimgvw advapi32 comctl32 user32 gdi32 shell32 ole32 gdiplus comdlg32 shlwapi msvcrt kernel32 ntdll) add_cd_file(TARGET shimgvw DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/shimgvw/shimgvw.c b/dll/win32/shimgvw/shimgvw.c index 962ddd50274..7a0d5372096 100644 --- a/dll/win32/shimgvw/shimgvw.c +++ b/dll/win32/shimgvw/shimgvw.c @@ -28,6 +28,7 @@ #include <shlobj.h> #include <strsafe.h> #include <shlwapi.h> +#include <shellapi.h>
#define NDEBUG #include <debug.h> @@ -241,9 +242,39 @@ BOOL Anime_Step(DWORD *pdwDelay) return FALSE; }
+static void UpdateZoom(UINT NewZoom) +{ + BOOL bEnableZoomIn, bEnableZoomOut; + + /* If zoom has not been changed, ignore it */ + if (ZoomPercents == NewZoom) + return; + + ZoomPercents = NewZoom; + + /* Check if a zoom button of the toolbar must be grayed */ + bEnableZoomIn = bEnableZoomOut = TRUE; + + if (NewZoom >= MAX_ZOOM) + { + bEnableZoomIn = FALSE; + } + else if (NewZoom <= MIN_ZOOM) + { + bEnableZoomOut = FALSE; + } + + /* Update the state of the zoom buttons */ + SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_OUT, bEnableZoomOut); + SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_IN, bEnableZoomIn); + + /* Redraw the display window */ + InvalidateRect(hDispWnd, NULL, FALSE); +} + static void ZoomInOrOut(BOOL bZoomIn) { - UINT i; + UINT i, NewZoom;
if (image == NULL) return; @@ -257,16 +288,9 @@ static void ZoomInOrOut(BOOL bZoomIn) break; } if (i == _countof(ZoomSteps)) - ZoomPercents = MAX_ZOOM; - else - ZoomPercents = ZoomSteps[i]; - - /* update tool bar buttons */ - SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_OUT, TRUE); - if (ZoomPercents >= MAX_ZOOM) - SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_IN, FALSE); + NewZoom = MAX_ZOOM; else - SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_IN, TRUE); + NewZoom = ZoomSteps[i]; } else /* zoom out */ { @@ -278,26 +302,19 @@ static void ZoomInOrOut(BOOL bZoomIn) break; } if (i < 0) - ZoomPercents = MIN_ZOOM; + NewZoom = MIN_ZOOM; else - ZoomPercents = ZoomSteps[i]; - - /* update tool bar buttons */ - SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_IN, TRUE); - if (ZoomPercents <= MIN_ZOOM) - SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_OUT, FALSE); - else - SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_OUT, TRUE); + NewZoom = ZoomSteps[i]; }
- /* redraw */ - InvalidateRect(hDispWnd, NULL, TRUE); + /* Update toolbar and refresh screen */ + UpdateZoom(NewZoom); }
static void ResetZoom(void) { RECT Rect; - UINT ImageWidth, ImageHeight; + UINT ImageWidth, ImageHeight, NewZoom;
if (image == NULL) return; @@ -314,12 +331,12 @@ static void ResetZoom(void) if (Rect.right < ImageWidth) { /* it's large, shrink it */ - ZoomPercents = (Rect.right * 100) / ImageWidth; + NewZoom = (Rect.right * 100) / ImageWidth; } else { /* it's small. show as original size */ - ZoomPercents = 100; + NewZoom = 100; } } else @@ -327,14 +344,16 @@ static void ResetZoom(void) if (Rect.bottom < ImageHeight) { /* it's large, shrink it */ - ZoomPercents = (Rect.bottom * 100) / ImageHeight; + NewZoom = (Rect.bottom * 100) / ImageHeight; } else { /* it's small. show as original size */ - ZoomPercents = 100; + NewZoom = 100; } } + + UpdateZoom(NewZoom); }
static void pLoadImage(LPCWSTR szOpenFileName) @@ -358,11 +377,8 @@ static void pLoadImage(LPCWSTR szOpenFileName) if (szOpenFileName && szOpenFileName[0]) SHAddToRecentDocs(SHARD_PATHW, szOpenFileName);
- /* reset zoom */ + /* Reset zoom and redraw display */ ResetZoom(); - - /* redraw */ - InvalidateRect(hDispWnd, NULL, TRUE); }
static void pSaveImageAs(HWND hwnd) @@ -921,9 +937,9 @@ ImageView_InitControls(HWND hwnd)
if (shiSettings.Maximized) ShowWindow(hwnd, SW_MAXIMIZE);
- hDispWnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_STATIC, _T(""), - WS_CHILD | WS_VISIBLE, - 0, 0, 0, 0, hwnd, NULL, hInstance, NULL); + hDispWnd = CreateWindowExW(WS_EX_CLIENTEDGE, WC_STATIC, L"", + WS_CHILD | WS_VISIBLE, + 0, 0, 0, 0, hwnd, NULL, hInstance, NULL);
SetClassLongPtr(hDispWnd, GCL_STYLE, CS_HREDRAW | CS_VREDRAW); PrevProc = (WNDPROC) SetWindowLongPtr(hDispWnd, GWLP_WNDPROC, (LPARAM) ImageView_DispWndProc); @@ -959,6 +975,55 @@ ImageView_OnSize(HWND hwnd, UINT state, INT cx, INT cy) } }
+static LRESULT +ImageView_Delete(HWND hwnd) +{ + DPRINT1("ImageView_Delete: unimplemented.\n"); + return 0; +} + +static LRESULT +ImageView_Modify(HWND hwnd) +{ + int nChars = GetFullPathNameW(currentFile->FileName, 0, NULL, NULL); + LPWSTR pszPathName; + SHELLEXECUTEINFOW sei; + + if (!nChars) + { + DPRINT1("ImageView_Modify: failed to get full path name.\n"); + return 1; + } + + pszPathName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, nChars * sizeof(WCHAR)); + if (pszPathName == NULL) + { + DPRINT1("HeapAlloc() failed in ImageView_Modify()\n"); + return 1; + } + + GetFullPathNameW(currentFile->FileName, nChars, pszPathName, NULL); + + sei.cbSize = sizeof(sei); + sei.fMask = 0; + sei.hwnd = NULL; + sei.lpVerb = L"edit"; + sei.lpFile = pszPathName; + sei.lpParameters = NULL; + sei.lpDirectory = NULL; + sei.nShow = SW_SHOWNORMAL; + sei.hInstApp = NULL; + + if (!ShellExecuteExW(&sei)) + { + DPRINT1("ImageView_Modify: ShellExecuteExW() failed with code %08X\n", (int)GetLastError()); + } + + HeapFree(GetProcessHeap(), 0, pszPathName); + + return 0; +} + LRESULT CALLBACK ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { @@ -989,8 +1054,8 @@ ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) break;
case IDC_REAL_SIZE: - DPRINT1("IDC_REAL_SIZE unimplemented\n"); - break; + UpdateZoom(100); + return 0;
case IDC_SLIDE_SHOW: DPRINT1("IDC_SLIDE_SHOW unimplemented\n"); @@ -1027,6 +1092,12 @@ ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) ImageView_UpdateWindow(hwnd); } break; + + case IDC_DELETE: + return ImageView_Delete(hwnd); + + case IDC_MODIFY: + return ImageView_Modify(hwnd); } } break; @@ -1051,7 +1122,7 @@ ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) lpttt->hinst = hInstance;
lpttt->lpszText = MAKEINTRESOURCEW(BtnConfig[lpttt->hdr.idFrom - IDC_TOOL_BASE].ids); - return TRUE; + return 0; } } break; @@ -1094,10 +1165,17 @@ ImageView_CreateWindow(HWND hwnd, LPCWSTR szFileName) HWND hMainWnd; MSG msg; HACCEL hKbdAccel; + HRESULT hComRes; INITCOMMONCONTROLSEX Icc = { .dwSize = sizeof(Icc), .dwICC = ICC_WIN95_CLASSES };
InitCommonControlsEx(&Icc);
+ hComRes = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + if (hComRes != S_OK && hComRes != S_FALSE) + { + DPRINT1("Warning, CoInitializeEx failed with code=%08X\n", (int)hComRes); + } + if (!ImageView_LoadSettings()) { shiSettings.Maximized = FALSE; @@ -1177,6 +1255,11 @@ ImageView_CreateWindow(HWND hwnd, LPCWSTR szFileName) Anime_FreeInfo();
GdiplusShutdown(gdiplusToken); + + /* Release COM resources */ + if (SUCCEEDED(hComRes)) + CoUninitialize(); + return -1; }