Skip to content

Commit 22add14

Browse files
committed
Add optional High Resolution rendering to shell extension for large thumbnails (preview pane)
1 parent ba20d37 commit 22add14

File tree

7 files changed

+151
-22
lines changed

7 files changed

+151
-22
lines changed

SarThumbnailHandler/SarThumbnailHandler.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ POPD</Command>
208208
</ItemDefinitionGroup>
209209
<ItemGroup>
210210
<ClInclude Include="ClassFactory.h" />
211+
<ClInclude Include="registry.h" />
211212
<ClInclude Include="resource_th.h" />
212213
<ClInclude Include="ThumbnailProvider.h" />
213214
<ClInclude Include="version.h" />

SarThumbnailHandler/SarThumbnailHandler.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
<ClInclude Include="resource_th.h">
2828
<Filter>Header Files</Filter>
2929
</ClInclude>
30+
<ClInclude Include="registry.h">
31+
<Filter>Header Files</Filter>
32+
</ClInclude>
3033
</ItemGroup>
3134
<ItemGroup>
3235
<ClCompile Include="ClassFactory.cpp">

SarThumbnailHandler/ThumbnailProvider.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#include <memory>
55

66
#include "openglrenderer.h"
7+
#include "config.h"
8+
#include "debug.h"
9+
#include "registry.h"
710

811
ThumbnailProvider::ThumbnailProvider()
912
: m_cRef(1), m_pStream(nullptr)
@@ -72,6 +75,9 @@ extern void __hexdump(void* d, int l);
7275

7376
IFACEMETHODIMP ThumbnailProvider::GetThumbnail(UINT thumb_size, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha)
7477
{
78+
DEBUG_LAUNCH();
79+
DEBUG_PRINT("Request Thumbnail: " << thumb_size);
80+
7581
std::unique_ptr<SarFile> sar;
7682
try {
7783
sar = std::make_unique<SarFile>(m_pStream);
@@ -80,12 +86,16 @@ IFACEMETHODIMP ThumbnailProvider::GetThumbnail(UINT thumb_size, HBITMAP* phbmp,
8086
return E_FAIL;
8187
}
8288

89+
90+
8391
int maxDim = __max(sar->width(), sar->height());
8492
thumb_size = __min(8 * maxDim, thumb_size);
8593

8694
int newW = sar->width() * thumb_size / maxDim;
8795
int newH = sar->height() * thumb_size / maxDim;
8896

97+
bool isThumbHighRes = thumb_size > 256;
98+
8999
BITMAPINFO bmi = {};
90100
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
91101
bmi.bmiHeader.biWidth = newW;
@@ -110,6 +120,14 @@ IFACEMETHODIMP ThumbnailProvider::GetThumbnail(UINT thumb_size, HBITMAP* phbmp,
110120
}
111121
}
112122

123+
DWORD highDefEnabled;
124+
HRESULT hr = registry::RegistryGetValue(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\" SZ_CLSID_ShellExtendionHandler, L"HighDefinition", &highDefEnabled);
125+
if (!SUCCEEDED(hr))
126+
highDefEnabled = 0;
127+
128+
bool renderInHd = isThumbHighRes && (highDefEnabled != 0);
129+
130+
g_pSarRenderer->SetFlag(OpenGLRenderer::FLAG_HD, renderInHd);
113131
g_pSarRenderer->Render(*sar, newW, newH, pBits);
114132

115133
*pdwAlpha = WTSAT_ARGB;

SarThumbnailHandler/dllmain.cpp

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "config.h"
99
#include "debug.h"
10+
#include "registry.h"
1011

1112

1213
HINSTANCE g_hInstDll = NULL;
@@ -85,7 +86,7 @@ HRESULT CreateRegKeyAndSetValue(const REGISTRY_ENTRY* pEntry)
8586

8687
STDAPI DllRegisterServer(void)
8788
{
88-
HRESULT hr;
89+
HRESULT hr = S_OK;
8990

9091
WCHAR szModuleName[MAX_PATH];
9192

@@ -95,29 +96,21 @@ STDAPI DllRegisterServer(void)
9596
}
9697
else
9798
{
98-
DWORD dwTreatment = 1; // Picture
99-
DWORD dwModuleNameLen = wcslen(szModuleName) * sizeof(WCHAR);
100-
const REGISTRY_ENTRY rgRegistryEntries[] =
101-
{
102-
// RootKey KeyName ValueName Type Size, Data
103-
{HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\" SZ_CLSID_ShellExtendionHandler, NULL, REG_SZ, sizeof(HANDLER_DESCRIPTION), HANDLER_DESCRIPTION},
104-
{HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\" SZ_CLSID_ShellExtendionHandler L"\\InProcServer32", NULL, REG_SZ, dwModuleNameLen, szModuleName},
105-
{HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\" SZ_CLSID_ShellExtendionHandler L"\\InProcServer32", L"ThreadingModel", REG_SZ, sizeof(L"Apartment"), L"Apartment"},
106-
107-
{HKEY_CURRENT_USER, L"Software\\Classes\\" SZ_FORMAT_EXTENSION, L"Treatment", REG_DWORD, sizeof(DWORD), &dwTreatment},
108-
{HKEY_CURRENT_USER, L"Software\\Classes\\" SZ_FORMAT_EXTENSION "\\ShellEx\\{e357fccd-a995-4576-b01f-234630154e96}", NULL, REG_SZ, sizeof(SZ_CLSID_ShellExtendionHandler), SZ_CLSID_ShellExtendionHandler},
109-
};
110-
111-
hr = S_OK;
112-
for (int i = 0; i < ARRAYSIZE(rgRegistryEntries) && SUCCEEDED(hr); i++)
113-
{
114-
hr = CreateRegKeyAndSetValue(&rgRegistryEntries[i]);
115-
}
99+
//DEBUG_LAUNCH();
100+
registry::RegistrySetValue(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\" SZ_CLSID_ShellExtendionHandler, NULL, HANDLER_DESCRIPTION);
101+
registry::RegistrySetValue<DWORD>(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\" SZ_CLSID_ShellExtendionHandler, L"HighDefinition", 0);
102+
registry::RegistrySetValue(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\" SZ_CLSID_ShellExtendionHandler L"\\InProcServer32", NULL, szModuleName);
103+
registry::RegistrySetValue(HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\" SZ_CLSID_ShellExtendionHandler L"\\InProcServer32", L"ThreadingModel", L"Apartment");
104+
105+
registry::RegistrySetValue<DWORD>(HKEY_CURRENT_USER, L"Software\\Classes\\" SZ_FORMAT_EXTENSION, L"Treatment", 1);
106+
registry::RegistrySetValue(HKEY_CURRENT_USER, L"Software\\Classes\\" SZ_FORMAT_EXTENSION "\\ShellEx\\{e357fccd-a995-4576-b01f-234630154e96}", NULL, SZ_CLSID_ShellExtendionHandler);
116107
}
108+
117109
if (SUCCEEDED(hr))
118110
{
119111
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
120112
}
113+
121114
return hr;
122115
}
123116

@@ -133,11 +126,9 @@ STDAPI DllUnregisterServer(void)
133126

134127
for (int i = 0; i < ARRAYSIZE(rgpszKeys) && SUCCEEDED(hr); i++)
135128
{
136-
hr = HRESULT_FROM_WIN32(RegDeleteTreeW(HKEY_CURRENT_USER, rgpszKeys[i]));
129+
hr = registry::RegistryDeleteTree(HKEY_CURRENT_USER, rgpszKeys[i]);
137130
if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
138-
{
139131
hr = S_OK;
140-
}
141132
}
142133
return hr;
143134
}

SarThumbnailHandler/registry.h

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#pragma once
2+
3+
#include <Windows.h>
4+
5+
namespace registry {
6+
7+
template<typename TValue>
8+
struct registry_io {
9+
10+
HRESULT write(HKEY root, LPCWSTR key, LPCWSTR valueName, const TValue& value);
11+
12+
template<int _Size>
13+
HRESULT write(HKEY root, LPCWSTR key, LPCWSTR valueName, const TValue (&value)[_Size]);
14+
15+
HRESULT read(HKEY root, LPCWSTR key, LPCWSTR valueName, TValue* value);
16+
};
17+
18+
static inline HRESULT RegistryDeleteTree(HKEY root, LPCWSTR key) {
19+
HRESULT hr = HRESULT_FROM_WIN32(RegDeleteTreeW(HKEY_CURRENT_USER, key));
20+
return hr;
21+
}
22+
23+
static inline HRESULT RegistrySetValue(HKEY root, LPCWSTR key, LPCWSTR valueName, DWORD dataType, LPCBYTE data, DWORD dataSize) {
24+
25+
HKEY hKey;
26+
HRESULT hr = HRESULT_FROM_WIN32(RegCreateKeyExW(root, key, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL));
27+
if (SUCCEEDED(hr))
28+
{
29+
hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, valueName, 0, dataType, data, dataSize));
30+
RegCloseKey(hKey);
31+
}
32+
return hr;
33+
}
34+
35+
static inline HRESULT RegistryGetValue(HKEY root, LPCWSTR key, LPCWSTR valueName, LPDWORD dataType, LPBYTE data, LPDWORD dataSize) {
36+
37+
HKEY hKey;
38+
HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyEx(root, key, 0, KEY_READ, &hKey));
39+
40+
if (!SUCCEEDED(hr))
41+
return hr;
42+
43+
hr = HRESULT_FROM_WIN32(RegQueryValueEx(hKey, valueName, NULL, dataType, data, dataSize));
44+
if (!SUCCEEDED(hr))
45+
return hr;
46+
47+
RegCloseKey(hKey);
48+
return hr;
49+
}
50+
51+
template<typename TValue>
52+
static inline HRESULT RegistryGetValue(HKEY root, LPCWSTR key, LPCWSTR valueName, TValue* value) {
53+
registry_io<TValue> reader;
54+
return reader.read(root, key, valueName, value);
55+
}
56+
57+
template<typename TValue, int ArraySize = sizeof(TValue)>
58+
static inline HRESULT RegistryGetValue(HKEY root, LPCWSTR key, LPCWSTR valueName, TValue(*value)[ArraySize]) {
59+
registry_io<TValue> reader;
60+
return reader.read(root, key, valueName, value);
61+
}
62+
63+
template<typename TValue>
64+
static inline HRESULT RegistrySetValue(HKEY root, LPCWSTR key, LPCWSTR valueName, const TValue& value) {
65+
registry_io<TValue> writer;
66+
return writer.write(root, key, valueName, value);
67+
}
68+
69+
template<typename TValue, int ArraySize = sizeof(TValue)>
70+
static inline HRESULT RegistrySetValue(HKEY root, LPCWSTR key, LPCWSTR valueName, const TValue(&value)[ArraySize]) {
71+
registry_io<TValue> writer;
72+
return writer.write(root, key, valueName, value);
73+
}
74+
}
75+
76+
template<>
77+
inline HRESULT registry::registry_io<DWORD>::read(HKEY root, LPCWSTR key, LPCWSTR valueName, DWORD* value)
78+
{
79+
DWORD dType;
80+
DWORD dSize;
81+
HRESULT hr = registry::RegistryGetValue(root, key, valueName, &dType, nullptr, &dSize);
82+
if (!SUCCEEDED(hr))
83+
return hr;
84+
85+
if (dType != REG_DWORD || dSize != sizeof(DWORD))
86+
return E_FAIL;
87+
88+
hr = registry::RegistryGetValue(root, key, valueName, &dType, (LPBYTE)value, &dSize);
89+
return hr;
90+
}
91+
92+
template<>
93+
inline HRESULT registry::registry_io<DWORD>::write(HKEY root, LPCWSTR key, LPCWSTR valueName, const DWORD& value)
94+
{
95+
return registry::RegistrySetValue(root, key, valueName, REG_DWORD, (LPCBYTE)&value, sizeof(DWORD));
96+
}
97+
98+
template<>
99+
template<int _Size>
100+
inline HRESULT registry::registry_io<WCHAR>::write(HKEY root, LPCWSTR key, LPCWSTR valueName, const WCHAR(&value)[_Size])
101+
{
102+
return registry::RegistrySetValue(root, key, valueName, REG_SZ, (LPCBYTE)&value, sizeof(WCHAR) * _Size);
103+
}

Shared/install_remove.bat

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ reg query "HKCR\CLSID" | find /i "{63424DF1-FAA8-4598-97E5-6E95D4A4ED67}" > NUL
4242
:INSTALL
4343
echo Installing Thumbnail Handler (%OS%)
4444
regsvr32 Pso2SarThumbnailHandler.%OS%.dll
45+
46+
choice /c yn /t 30 /d n /m "Enable High Resolution Rendering?"
47+
if %errorlevel% == 1 (
48+
reg add "HKCR\CLSID\{63424DF1-FAA8-4598-97E5-6E95D4A4ED67}" /v "HighDefinition" /t REG_DWORD /d 1 /f
49+
) else (
50+
reg add "HKCR\CLSID\{63424DF1-FAA8-4598-97E5-6E95D4A4ED67}" /v "HighDefinition" /t REG_DWORD /d 0 /f
51+
)
52+
53+
4554
goto END
4655
:REMOVE
4756
echo Removing Thumbnail Handler (%OS%)

Shared/src/symbolart.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,17 @@ SarFile::SarFile(IStream* stream)
6161
sar.rseek(4, SEEK_SET);
6262
sar.read<SarHeader>(&m_Header, 1);
6363

64+
#ifndef _USRDLL
65+
6466
DEBUG_SCOPE({
6567
FILE * fp;
6668
fopen_s(&fp, "dump.bin", "wb");
6769
fwrite((uint8_t*)sar, 1, sar.size(), fp);
6870
fclose(fp);
6971
});
7072

73+
#endif // _USRDLL
74+
7175
DEBUG_HEXDUMP_E(m_Header);
7276
DEBUG_BINDUMP_E(m_Header);
7377
DEBUG_PRINT_E(m_Header.author());

0 commit comments

Comments
 (0)