[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
This commit is contained in:
Carlo Bramini 2021-03-01 15:40:06 +01:00 committed by GitHub
parent 9dff498b21
commit a141c91135
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 37 deletions

View file

@ -11,5 +11,5 @@ list(APPEND SOURCE
add_library(shimgvw MODULE ${SOURCE}) add_library(shimgvw MODULE ${SOURCE})
set_module_type(shimgvw win32dll UNICODE) set_module_type(shimgvw win32dll UNICODE)
target_link_libraries(shimgvw wine) 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) add_cd_file(TARGET shimgvw DESTINATION reactos/system32 FOR all)

View file

@ -28,6 +28,7 @@
#include <shlobj.h> #include <shlobj.h>
#include <strsafe.h> #include <strsafe.h>
#include <shlwapi.h> #include <shlwapi.h>
#include <shellapi.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
@ -241,9 +242,39 @@ BOOL Anime_Step(DWORD *pdwDelay)
return FALSE; 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) static void ZoomInOrOut(BOOL bZoomIn)
{ {
UINT i; UINT i, NewZoom;
if (image == NULL) if (image == NULL)
return; return;
@ -257,16 +288,9 @@ static void ZoomInOrOut(BOOL bZoomIn)
break; break;
} }
if (i == _countof(ZoomSteps)) if (i == _countof(ZoomSteps))
ZoomPercents = MAX_ZOOM; NewZoom = MAX_ZOOM;
else else
ZoomPercents = ZoomSteps[i]; NewZoom = 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);
else
SendMessageW(hToolBar, TB_ENABLEBUTTON, IDC_ZOOM_IN, TRUE);
} }
else /* zoom out */ else /* zoom out */
{ {
@ -278,26 +302,19 @@ static void ZoomInOrOut(BOOL bZoomIn)
break; break;
} }
if (i < 0) if (i < 0)
ZoomPercents = MIN_ZOOM; NewZoom = MIN_ZOOM;
else else
ZoomPercents = ZoomSteps[i]; NewZoom = 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);
} }
/* redraw */ /* Update toolbar and refresh screen */
InvalidateRect(hDispWnd, NULL, TRUE); UpdateZoom(NewZoom);
} }
static void ResetZoom(void) static void ResetZoom(void)
{ {
RECT Rect; RECT Rect;
UINT ImageWidth, ImageHeight; UINT ImageWidth, ImageHeight, NewZoom;
if (image == NULL) if (image == NULL)
return; return;
@ -314,12 +331,12 @@ static void ResetZoom(void)
if (Rect.right < ImageWidth) if (Rect.right < ImageWidth)
{ {
/* it's large, shrink it */ /* it's large, shrink it */
ZoomPercents = (Rect.right * 100) / ImageWidth; NewZoom = (Rect.right * 100) / ImageWidth;
} }
else else
{ {
/* it's small. show as original size */ /* it's small. show as original size */
ZoomPercents = 100; NewZoom = 100;
} }
} }
else else
@ -327,14 +344,16 @@ static void ResetZoom(void)
if (Rect.bottom < ImageHeight) if (Rect.bottom < ImageHeight)
{ {
/* it's large, shrink it */ /* it's large, shrink it */
ZoomPercents = (Rect.bottom * 100) / ImageHeight; NewZoom = (Rect.bottom * 100) / ImageHeight;
} }
else else
{ {
/* it's small. show as original size */ /* it's small. show as original size */
ZoomPercents = 100; NewZoom = 100;
} }
} }
UpdateZoom(NewZoom);
} }
static void pLoadImage(LPCWSTR szOpenFileName) static void pLoadImage(LPCWSTR szOpenFileName)
@ -358,11 +377,8 @@ static void pLoadImage(LPCWSTR szOpenFileName)
if (szOpenFileName && szOpenFileName[0]) if (szOpenFileName && szOpenFileName[0])
SHAddToRecentDocs(SHARD_PATHW, szOpenFileName); SHAddToRecentDocs(SHARD_PATHW, szOpenFileName);
/* reset zoom */ /* Reset zoom and redraw display */
ResetZoom(); ResetZoom();
/* redraw */
InvalidateRect(hDispWnd, NULL, TRUE);
} }
static void pSaveImageAs(HWND hwnd) static void pSaveImageAs(HWND hwnd)
@ -921,9 +937,9 @@ ImageView_InitControls(HWND hwnd)
if (shiSettings.Maximized) ShowWindow(hwnd, SW_MAXIMIZE); if (shiSettings.Maximized) ShowWindow(hwnd, SW_MAXIMIZE);
hDispWnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_STATIC, _T(""), hDispWnd = CreateWindowExW(WS_EX_CLIENTEDGE, WC_STATIC, L"",
WS_CHILD | WS_VISIBLE, WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, hwnd, NULL, hInstance, NULL); 0, 0, 0, 0, hwnd, NULL, hInstance, NULL);
SetClassLongPtr(hDispWnd, GCL_STYLE, CS_HREDRAW | CS_VREDRAW); SetClassLongPtr(hDispWnd, GCL_STYLE, CS_HREDRAW | CS_VREDRAW);
PrevProc = (WNDPROC) SetWindowLongPtr(hDispWnd, GWLP_WNDPROC, (LPARAM) ImageView_DispWndProc); 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 LRESULT CALLBACK
ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) 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; break;
case IDC_REAL_SIZE: case IDC_REAL_SIZE:
DPRINT1("IDC_REAL_SIZE unimplemented\n"); UpdateZoom(100);
break; return 0;
case IDC_SLIDE_SHOW: case IDC_SLIDE_SHOW:
DPRINT1("IDC_SLIDE_SHOW unimplemented\n"); DPRINT1("IDC_SLIDE_SHOW unimplemented\n");
@ -1027,6 +1092,12 @@ ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
ImageView_UpdateWindow(hwnd); ImageView_UpdateWindow(hwnd);
} }
break; break;
case IDC_DELETE:
return ImageView_Delete(hwnd);
case IDC_MODIFY:
return ImageView_Modify(hwnd);
} }
} }
break; break;
@ -1051,7 +1122,7 @@ ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
lpttt->hinst = hInstance; lpttt->hinst = hInstance;
lpttt->lpszText = MAKEINTRESOURCEW(BtnConfig[lpttt->hdr.idFrom - IDC_TOOL_BASE].ids); lpttt->lpszText = MAKEINTRESOURCEW(BtnConfig[lpttt->hdr.idFrom - IDC_TOOL_BASE].ids);
return TRUE; return 0;
} }
} }
break; break;
@ -1094,10 +1165,17 @@ ImageView_CreateWindow(HWND hwnd, LPCWSTR szFileName)
HWND hMainWnd; HWND hMainWnd;
MSG msg; MSG msg;
HACCEL hKbdAccel; HACCEL hKbdAccel;
HRESULT hComRes;
INITCOMMONCONTROLSEX Icc = { .dwSize = sizeof(Icc), .dwICC = ICC_WIN95_CLASSES }; INITCOMMONCONTROLSEX Icc = { .dwSize = sizeof(Icc), .dwICC = ICC_WIN95_CLASSES };
InitCommonControlsEx(&Icc); 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()) if (!ImageView_LoadSettings())
{ {
shiSettings.Maximized = FALSE; shiSettings.Maximized = FALSE;
@ -1177,6 +1255,11 @@ ImageView_CreateWindow(HWND hwnd, LPCWSTR szFileName)
Anime_FreeInfo(); Anime_FreeInfo();
GdiplusShutdown(gdiplusToken); GdiplusShutdown(gdiplusToken);
/* Release COM resources */
if (SUCCEEDED(hComRes))
CoUninitialize();
return -1; return -1;
} }