mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 23:15:39 +00:00
[CORE-7737]
Implement browsing with the shell image viewer. Patch by Ricardo Hanke. svn path=/trunk/; revision=65608
This commit is contained in:
parent
f758aece6f
commit
cbc7920dbe
3 changed files with 191 additions and 1 deletions
|
@ -10,5 +10,5 @@ list(APPEND SOURCE
|
||||||
add_library(shimgvw SHARED ${SOURCE})
|
add_library(shimgvw SHARED ${SOURCE})
|
||||||
set_module_type(shimgvw win32dll)
|
set_module_type(shimgvw win32dll)
|
||||||
target_link_libraries(shimgvw wine)
|
target_link_libraries(shimgvw wine)
|
||||||
add_importlibs(shimgvw advapi32 comctl32 user32 gdi32 gdiplus comdlg32 msvcrt kernel32 ntdll)
|
add_importlibs(shimgvw advapi32 comctl32 user32 gdi32 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)
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <gdiplus.h>
|
#include <gdiplus.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
|
|
||||||
HINSTANCE hInstance;
|
HINSTANCE hInstance;
|
||||||
SHIMGVW_SETTINGS shiSettings;
|
SHIMGVW_SETTINGS shiSettings;
|
||||||
|
SHIMGVW_FILENODE *currentFile;
|
||||||
GpImage *image;
|
GpImage *image;
|
||||||
WNDPROC PrevProc = NULL;
|
WNDPROC PrevProc = NULL;
|
||||||
|
|
||||||
|
@ -159,6 +161,166 @@ static void pSaveImageAs(HWND hwnd)
|
||||||
free(codecInfo);
|
free(codecInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
pLoadImageFromNode(SHIMGVW_FILENODE *node, HWND hwnd)
|
||||||
|
{
|
||||||
|
WCHAR szTitleBuf[800];
|
||||||
|
WCHAR szResStr[512];
|
||||||
|
WCHAR *c;
|
||||||
|
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
c = wcsrchr(node->FileName, '\\');
|
||||||
|
if (c)
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadStringW(hInstance, IDS_APPTITLE, szResStr, 512);
|
||||||
|
StringCbPrintfExW(szTitleBuf, 800, NULL, NULL, 0, L"%ls%ls%ls", szResStr, L" - ", c);
|
||||||
|
SetWindowTextW(hwnd, szTitleBuf);
|
||||||
|
|
||||||
|
if (image)
|
||||||
|
{
|
||||||
|
GdipDisposeImage(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
pLoadImage(node->FileName);
|
||||||
|
InvalidateRect(hDispWnd, NULL, TRUE);
|
||||||
|
UpdateWindow(hDispWnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SHIMGVW_FILENODE*
|
||||||
|
pBuildFileList(LPWSTR szFirstFile)
|
||||||
|
{
|
||||||
|
HANDLE hFindHandle;
|
||||||
|
WCHAR *extension;
|
||||||
|
WCHAR szSearchPath[MAX_PATH];
|
||||||
|
WCHAR szSearchMask[MAX_PATH];
|
||||||
|
WCHAR szFileTypes[MAX_PATH];
|
||||||
|
WIN32_FIND_DATAW findData;
|
||||||
|
SHIMGVW_FILENODE *currentNode;
|
||||||
|
SHIMGVW_FILENODE *root;
|
||||||
|
SHIMGVW_FILENODE *conductor;
|
||||||
|
ImageCodecInfo *codecInfo;
|
||||||
|
UINT num;
|
||||||
|
UINT size;
|
||||||
|
UINT j;
|
||||||
|
|
||||||
|
|
||||||
|
wcscpy(szSearchPath, szFirstFile);
|
||||||
|
PathRemoveFileSpecW(szSearchPath);
|
||||||
|
|
||||||
|
GdipGetImageDecodersSize(&num, &size);
|
||||||
|
codecInfo = malloc(size);
|
||||||
|
if (!codecInfo)
|
||||||
|
{
|
||||||
|
DPRINT1("malloc() failed in pLoadFileList()\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GdipGetImageDecoders(num, size, codecInfo);
|
||||||
|
|
||||||
|
root = malloc(sizeof(SHIMGVW_FILENODE));
|
||||||
|
if (!root)
|
||||||
|
{
|
||||||
|
DPRINT1("malloc() failed in pLoadFileList()\n");
|
||||||
|
free(codecInfo);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
conductor = root;
|
||||||
|
|
||||||
|
for (j = 0; j < num; ++j)
|
||||||
|
{
|
||||||
|
StringCbPrintfExW(szFileTypes, MAX_PATH, NULL, NULL, 0, L"%ls", codecInfo[j].FilenameExtension);
|
||||||
|
|
||||||
|
extension = wcstok(szFileTypes, L";");
|
||||||
|
while (extension != NULL)
|
||||||
|
{
|
||||||
|
StringCbPrintfExW(szSearchMask, MAX_PATH, NULL, NULL, 0, L"%ls%ls%ls", szSearchPath, L"\\", extension);
|
||||||
|
|
||||||
|
hFindHandle = FindFirstFileW(szSearchMask, &findData);
|
||||||
|
if (hFindHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
StringCbPrintfExW(conductor->FileName, MAX_PATH, NULL, NULL, 0, L"%ls%ls%ls", szSearchPath, L"\\", findData.cFileName);
|
||||||
|
|
||||||
|
// compare the name of the requested file with the one currently found.
|
||||||
|
// if the name matches, the current node is returned by the function.
|
||||||
|
if (wcscmp(szFirstFile, conductor->FileName) == 0)
|
||||||
|
{
|
||||||
|
currentNode = conductor;
|
||||||
|
}
|
||||||
|
|
||||||
|
conductor->Next = malloc(sizeof(SHIMGVW_FILENODE));
|
||||||
|
|
||||||
|
// if malloc fails, make circular what we have and return it
|
||||||
|
if (!conductor->Next)
|
||||||
|
{
|
||||||
|
DPRINT1("malloc() failed in pLoadFileList()\n");
|
||||||
|
|
||||||
|
conductor->Next = root;
|
||||||
|
root->Prev = conductor;
|
||||||
|
|
||||||
|
FindClose(hFindHandle);
|
||||||
|
free(codecInfo);
|
||||||
|
return conductor;
|
||||||
|
}
|
||||||
|
|
||||||
|
conductor->Next->Prev = conductor;
|
||||||
|
conductor = conductor->Next;
|
||||||
|
}
|
||||||
|
while (FindNextFileW(hFindHandle, &findData) != 0);
|
||||||
|
|
||||||
|
FindClose(hFindHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension = wcstok(NULL, L";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we now have a node too much in the list. In case the requested file was not found,
|
||||||
|
// we use this node to store the name of it, otherwise we free it.
|
||||||
|
if (currentNode == NULL)
|
||||||
|
{
|
||||||
|
StringCbPrintfExW(conductor->FileName, MAX_PATH, NULL, NULL, 0, L"%ls", szFirstFile);
|
||||||
|
currentNode = conductor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
conductor = conductor->Prev;
|
||||||
|
free(conductor->Next);
|
||||||
|
}
|
||||||
|
|
||||||
|
// link the last node with the first one to make the list circular
|
||||||
|
conductor->Next = root;
|
||||||
|
root->Prev = conductor;
|
||||||
|
conductor = currentNode;
|
||||||
|
|
||||||
|
free(codecInfo);
|
||||||
|
|
||||||
|
return conductor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
pFreeFileList(SHIMGVW_FILENODE *root)
|
||||||
|
{
|
||||||
|
SHIMGVW_FILENODE *conductor;
|
||||||
|
|
||||||
|
root->Prev->Next = NULL;
|
||||||
|
root->Prev = NULL;
|
||||||
|
|
||||||
|
while (root)
|
||||||
|
{
|
||||||
|
conductor = root;
|
||||||
|
root = conductor->Next;
|
||||||
|
free(conductor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
ImageView_DrawImage(HWND hwnd)
|
ImageView_DrawImage(HWND hwnd)
|
||||||
{
|
{
|
||||||
|
@ -410,9 +572,17 @@ ImageView_WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||||
switch (wParam)
|
switch (wParam)
|
||||||
{
|
{
|
||||||
case IDC_PREV:
|
case IDC_PREV:
|
||||||
|
{
|
||||||
|
currentFile = currentFile->Prev;
|
||||||
|
pLoadImageFromNode(currentFile, hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IDC_NEXT:
|
case IDC_NEXT:
|
||||||
|
{
|
||||||
|
currentFile = currentFile->Next;
|
||||||
|
pLoadImageFromNode(currentFile, hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IDC_ZOOMP:
|
case IDC_ZOOMP:
|
||||||
|
@ -522,6 +692,7 @@ ImageView_CreateWindow(HWND hwnd, LPWSTR szFileName)
|
||||||
ULONG_PTR gdiplusToken;
|
ULONG_PTR gdiplusToken;
|
||||||
WNDCLASS WndClass = {0};
|
WNDCLASS WndClass = {0};
|
||||||
TCHAR szBuf[512];
|
TCHAR szBuf[512];
|
||||||
|
WCHAR szInitialFile[MAX_PATH];
|
||||||
HWND hMainWnd;
|
HWND hMainWnd;
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
|
||||||
|
@ -560,6 +731,16 @@ ImageView_CreateWindow(HWND hwnd, LPWSTR szFileName)
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
0, 0, NULL, NULL, hInstance, NULL);
|
0, 0, NULL, NULL, hInstance, NULL);
|
||||||
|
|
||||||
|
// make sure the path has no quotes on it
|
||||||
|
wcscpy(szInitialFile, szFileName);
|
||||||
|
PathUnquoteSpacesW(szInitialFile);
|
||||||
|
|
||||||
|
currentFile = pBuildFileList(szInitialFile);
|
||||||
|
if (currentFile)
|
||||||
|
{
|
||||||
|
pLoadImageFromNode(currentFile, hMainWnd);
|
||||||
|
}
|
||||||
|
|
||||||
// Show it
|
// Show it
|
||||||
ShowWindow(hMainWnd, SW_SHOW);
|
ShowWindow(hMainWnd, SW_SHOW);
|
||||||
UpdateWindow(hMainWnd);
|
UpdateWindow(hMainWnd);
|
||||||
|
@ -571,6 +752,8 @@ ImageView_CreateWindow(HWND hwnd, LPWSTR szFileName)
|
||||||
DispatchMessageW(&msg);
|
DispatchMessageW(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pFreeFileList(currentFile);
|
||||||
|
|
||||||
if (image)
|
if (image)
|
||||||
GdipDisposeImage(image);
|
GdipDisposeImage(image);
|
||||||
GdiplusShutdown(gdiplusToken);
|
GdiplusShutdown(gdiplusToken);
|
||||||
|
|
|
@ -13,3 +13,10 @@ typedef struct
|
||||||
INT Right;
|
INT Right;
|
||||||
INT Bottom;
|
INT Bottom;
|
||||||
} SHIMGVW_SETTINGS;
|
} SHIMGVW_SETTINGS;
|
||||||
|
|
||||||
|
typedef struct SHIMGVW_FILENODE_INTERNAL
|
||||||
|
{
|
||||||
|
WCHAR FileName[MAX_PATH];
|
||||||
|
struct SHIMGVW_FILENODE_INTERNAL *Prev;
|
||||||
|
struct SHIMGVW_FILENODE_INTERNAL *Next;
|
||||||
|
} SHIMGVW_FILENODE;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue