Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement fast drag drop support. #502

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions NanaZip.Extras/CNanaZipCopyHook.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* PROJECT: NanaZip
* FILE: CNanaZipCopyHook.cpp
* PURPOSE: Copy hook implementation
*
* LICENSE: The MIT License
*
* DEVELOPER: dinhngtu (contact@tudinh.xyz)
*/

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <exception>
#include <filesystem>
#include <Unknwn.h>
#include <olectl.h>
#include <shellapi.h>
#include <strsafe.h>

#include "CNanaZipCopyHook.hpp"

static constexpr PCWSTR DRAGNOTIFIER_PREFIX = L"{7F4FD2EA-8CC8-43C4-8440-CD76805B4E95}";
static constexpr ULONG_PTR DRAGNOTIFIER_COPY = 0x7F4FD2EA;

IFACEMETHODIMP_(UINT)
CNanaZipCopyHook::CopyCallback(
_In_opt_ HWND hwnd,
UINT wFunc,
UINT wFlags,
_In_ PCWSTR pszSrcFile,
DWORD dwSrcAttribs,
_In_opt_ PCWSTR pszDestFile,
DWORD dwDestAttribs) {

UNREFERENCED_PARAMETER(wFlags);
UNREFERENCED_PARAMETER(dwSrcAttribs);
UNREFERENCED_PARAMETER(dwDestAttribs);

try {
if (wFunc != FO_COPY && wFunc == FO_MOVE)
return IDYES;

std::filesystem::path srcpath(pszSrcFile);
std::filesystem::path dstpath(pszDestFile);
if (srcpath.stem() != DRAGNOTIFIER_PREFIX)
return IDYES;

auto hwndString = srcpath.extension().wstring();
if (!hwndString.length())
return IDYES;

auto hwndDest = reinterpret_cast<HWND>(std::stoull(hwndString.substr(1)));
auto dest = dstpath.parent_path();
DragNotifierCopyData data{};
if (FAILED(StringCchCopyW(&data.filename[0], ARRAYSIZE(data.filename), dest.c_str())))
return IDYES;

COPYDATASTRUCT cds{DRAGNOTIFIER_COPY, sizeof(DragNotifierCopyData), &data};
DWORD_PTR res;
// we can't use PostMessage since the copydata message needs to stay alive during the send
SendMessageTimeoutW(
hwndDest,
WM_COPYDATA,
reinterpret_cast<WPARAM>(hwnd),
reinterpret_cast<LPARAM>(&cds),
SMTO_ABORTIFHUNG,
100,
&res);
// but it doesn't matter if the caller returns or not
return IDNO;
} catch (const std::exception &e) {
OutputDebugStringA(e.what());
return IDYES;
}
}
22 changes: 22 additions & 0 deletions NanaZip.Extras/CNanaZipCopyHook.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winrt/windows.foundation.h>
#include <ShlObj.h>

struct CNanaZipCopyHook : winrt::implements<CNanaZipCopyHook, ICopyHookW> {
STDMETHOD_(UINT, CopyCallback)(
_In_opt_ HWND hwnd,
UINT wFunc,
UINT wFlags,
_In_ PCWSTR pszSrcFile,
DWORD dwSrcAttribs,
_In_opt_ PCWSTR pszDestFile,
DWORD dwDestAttribs);
};

struct DragNotifierCopyData {
wchar_t filename[MAX_PATH];
};
129 changes: 129 additions & 0 deletions NanaZip.Extras/NanaZip.Extras.ShellExtension.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* PROJECT: NanaZip
* FILE: NanaZip.Extras.ShellExtension.cpp
* PURPOSE: Entry point and self registration code
*
* LICENSE: The MIT License
*
* DEVELOPER: dinhngtu (contact@tudinh.xyz)
*/

#define WIN32_LEAN_AND_MEAN

#include <string>
#include <windows.h>

#include <wil/registry.h>
#include <wil/win32_helpers.h>
#include <wil/stl.h>

#include "CNanaZipCopyHook.hpp"

using namespace std::string_literals;

static HINSTANCE g_hInstance = NULL;

BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
UNREFERENCED_PARAMETER(lpReserved);

switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
g_hInstance = hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

struct DECLSPEC_UUID("{542CE69A-6EA7-4D77-9B8F-8F56CEA2BF16}") CNanaZipLegacyContextMenuFactory
: winrt::implements<CNanaZipLegacyContextMenuFactory, IClassFactory> {
IFACEMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject) WIN_NOEXCEPT {
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;

try {
return winrt::make<CNanaZipCopyHook>()->QueryInterface(riid, ppvObject);
} catch (...) {
return winrt::to_hresult();
}
}

IFACEMETHODIMP LockServer(BOOL fLock) WIN_NOEXCEPT {
if (fLock)
++winrt::get_module_lock();
else
--winrt::get_module_lock();
return S_OK;
}
};

_Use_decl_annotations_ STDAPI DllCanUnloadNow() {
if (winrt::get_module_lock())
return S_FALSE;
winrt::clear_factory_cache();
return S_OK;
}

_Use_decl_annotations_ STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID *ppv) {
try {
*ppv = NULL;
if (rclsid == __uuidof(CNanaZipLegacyContextMenuFactory))
return winrt::make<CNanaZipLegacyContextMenuFactory>()->QueryInterface(riid, ppv);
return E_INVALIDARG;
} catch (...) {
return winrt::to_hresult();
}
}

_Use_decl_annotations_ STDAPI DllRegisterServer() {
try {
wchar_t clsid[wil::guid_string_buffer_length];

if (!StringFromGUID2(__uuidof(CNanaZipLegacyContextMenuFactory), clsid, ARRAYSIZE(clsid)))
winrt::throw_hresult(E_OUTOFMEMORY);

auto clsidKeyName = L"Software\\Classes\\CLSID\\"s + clsid;
auto clsidKey =
wil::reg::create_unique_key(HKEY_CURRENT_USER, clsidKeyName.c_str(), wil::reg::key_access::readwrite);

auto serverKey =
wil::reg::create_unique_key(clsidKey.get(), L"InprocServer32", wil::reg::key_access::readwrite);
auto dllPath = wil::GetModuleFileNameW<std::wstring>(g_hInstance);
wil::reg::set_value_string(serverKey.get(), NULL, dllPath.c_str());
wil::reg::set_value_string(serverKey.get(), L"ThreadingModel", L"Apartment");

auto handlerKeyName = L"Software\\Classes\\Directory\\shellex\\CopyHookHandlers\\"s + clsid;
auto handlerKey =
wil::reg::create_unique_key(HKEY_CURRENT_USER, handlerKeyName.c_str(), wil::reg::key_access::readwrite);
wil::reg::set_value_string(handlerKey.get(), NULL, clsid);

return S_OK;
} catch (...) {
return winrt::to_hresult();
}
}

_Use_decl_annotations_ STDAPI DllUnregisterServer() {
try {
wchar_t clsid[wil::guid_string_buffer_length];

if (!StringFromGUID2(__uuidof(CNanaZipLegacyContextMenuFactory), clsid, ARRAYSIZE(clsid)))
winrt::throw_hresult(E_OUTOFMEMORY);

auto handlerKeyName = L"Software\\Classes\\Directory\\shellex\\CopyHookHandlers\\"s + clsid;
RegDeleteKeyExW(HKEY_CURRENT_USER, handlerKeyName.c_str(), 0, 0);

auto serverKeyName = L"Software\\Classes\\CLSID\\"s + clsid + L"\\InprocServer32";
RegDeleteKeyExW(HKEY_CURRENT_USER, serverKeyName.c_str(), 0, 0);

auto clsidKeyName = L"Software\\Classes\\CLSID\\"s + clsid;
RegDeleteKeyExW(HKEY_CURRENT_USER, clsidKeyName.c_str(), 0, 0);

return S_OK;
} catch (...) {
return winrt::to_hresult();
}
}
8 changes: 8 additions & 0 deletions NanaZip.Extras/NanaZip.Extras.ShellExtension.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
LIBRARY

EXPORTS

DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
14 changes: 14 additions & 0 deletions NanaZip.Extras/NanaZip.Extras.ShellExtension.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"/>
</dependentAssembly>
</dependency>
</assembly>
68 changes: 68 additions & 0 deletions NanaZip.Extras/NanaZip.Extras.ShellExtension.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{C1CBC99A-1225-446F-975D-4158D57BF586}</ProjectGuid>
<RootNamespace>NanaZip</RootNamespace>
<MileProjectType>DynamicLibrary</MileProjectType>
<MileProjectManifestFile>NanaZip.Extras.ShellExtension.manifest</MileProjectManifestFile>
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
<YY_Thunks_File>YY_Thunks_for_Vista.obj</YY_Thunks_File>
<MileUniCrtDisableRuntimeDebuggingFeature>true</MileUniCrtDisableRuntimeDebuggingFeature>
<MileProjectEnableCppWinRTSupport>true</MileProjectEnableCppWinRTSupport>
<MileProjectUseProjectProperties>true</MileProjectUseProjectProperties>
<MileProjectCompanyName>M2-Team</MileProjectCompanyName>
<MileProjectFileDescription>NanaZip Extras Shell Extension</MileProjectFileDescription>
<MileProjectInternalName>NanaZip</MileProjectInternalName>
<MileProjectLegalCopyright>© M2-Team and Contributors. All rights reserved.</MileProjectLegalCopyright>
<MileProjectOriginalFilename>NanaZip.Extras.ShellExtension.dll</MileProjectOriginalFilename>
<MileProjectProductName>NanaZip</MileProjectProductName>
<MileProjectVersion>5.1.$([System.DateTime]::Today.Subtract($([System.DateTime]::Parse('2021-08-31'))).TotalDays).0</MileProjectVersion>
<MileProjectVersionTag>Preview 0</MileProjectVersionTag>
</PropertyGroup>
<Import Sdk="Mile.Project.Configurations" Version="1.0.1426" Project="Mile.Project.Platform.x86.props" />
<Import Sdk="Mile.Project.Configurations" Version="1.0.1426" Project="Mile.Project.Platform.x64.props" />
<Import Sdk="Mile.Project.Configurations" Version="1.0.1426" Project="Mile.Project.Platform.ARM64.props" />
<Import Sdk="Mile.Project.Configurations" Version="1.0.1426" Project="Mile.Project.Cpp.Default.props" />
<Import Sdk="Mile.Project.Configurations" Version="1.0.1426" Project="Mile.Project.Cpp.props" />
<Import Project="..\NanaZip.Frieren\NanaZip.Frieren.props" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalOptions>%(AdditionalOptions) /Wv:18</AdditionalOptions>
<PreprocessorDefinitions>WINRT_NO_SOURCE_LOCATION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<LargeAddressAware>true</LargeAddressAware>
<ModuleDefinitionFile>NanaZip.Extras.ShellExtension.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
<RuntimeLibrary Condition="'$(Configuration)' == 'Debug'">MultiThreadedDebug</RuntimeLibrary>
<RuntimeLibrary Condition="'$(Configuration)' == 'Release'">MultiThreaded</RuntimeLibrary>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="CNanaZipCopyHook.cpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="NanaZip.Extras.ShellExtension.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="CNanaZipCopyHook.hpp" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.ImplementationLibrary">
<Version>1.0.240803.1</Version>
</PackageReference>
<PackageReference Include="Mile.Windows.Helpers">
<Version>1.0.671</Version>
</PackageReference>
<PackageReference Include="Mile.Windows.UniCrt">
<Version>1.1.278</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<None Include="NanaZip.Extras.ShellExtension.def" />
</ItemGroup>
<Import Sdk="Mile.Project.Configurations" Version="1.0.1426" Project="Mile.Project.Cpp.targets" />
</Project>
35 changes: 35 additions & 0 deletions NanaZip.Extras/NanaZip.Extras.ShellExtension.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CNanaZipCopyHook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NanaZip.Extras.ShellExtension.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="CNanaZipCopyHook.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="NanaZip.Extras.ShellExtension.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>
5 changes: 5 additions & 0 deletions NanaZip.Extras/Setup/NanaZip.Extras.Setup.wixproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project Sdk="WixToolset.Sdk/5.0.2">
<ItemGroup>
<ProjectReference Include="..\NanaZip.Extras.ShellExtension.vcxproj" />
</ItemGroup>
</Project>
11 changes: 11 additions & 0 deletions NanaZip.Extras/Setup/Package.en-us.wxl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!--
This file contains the declaration of all the localizable strings.
-->
<WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US">

<String Id="DowngradeError" Value="A newer version of [ProductName] is already installed." />
<String Id="WrongArchError" Value="You must use the [ProductName] installer with the correct CPU architecture." />

<String Id="ShellExtensionFeatureTitle" Value="Shell Extension" />

</WixLocalization>
45 changes: 45 additions & 0 deletions NanaZip.Extras/Setup/Package.wxs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<Wix
xmlns="http://wixtoolset.org/schemas/v4/wxs"
xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
<Package
Name="NanaZip Extras"
Manufacturer="M2-Team"
Version="!(bind.fileVersion.NanaZip.Extras.ShellExtension.dll)"
UpgradeCode="{49A00978-12FB-4443-A816-4F10D29C4B12}"
Scope="perUserOrMachine">
<?if $(Platform) = x86?>
<Launch Condition="NOT VersionNT64" Message="!(loc.WrongArchError)" />
<?endif?>
<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
<MediaTemplate EmbedCab="yes" />
<Property Id="ARPNOMODIFY" Value="1" />
<Feature Id="ShellExtensionFeature" Title="!(loc.ShellExtensionFeatureTitle)">
<ComponentGroupRef Id="ShellExtensionComponents" />
</Feature>
</Package>

<Fragment>
<StandardDirectory Id="ProgramFiles6432Folder">
<Directory Id="INSTALLFOLDER" Name="NanaZip.Extras" />
</StandardDirectory>
</Fragment>

<Fragment>
<ComponentGroup Id="ShellExtensionComponents" Directory="INSTALLFOLDER">
<Component>
<File
Id="NanaZip.Extras.ShellExtension.dll"
Source="$(SolutionDir)Output\Binaries\$(Configuration)\$(Platform)\NanaZip.Extras.ShellExtension.dll">
<Class Id="{542CE69A-6EA7-4D77-9B8F-8F56CEA2BF16}" Context="InprocServer32"
ThreadingModel="apartment" Advertise="no" />
</File>
</Component>
<Component>
<RegistryKey Root="HKCR"
Key="Directory\shellex\CopyHookHandlers\{542CE69A-6EA7-4D77-9B8F-8F56CEA2BF16}">
<RegistryValue Value="{542CE69A-6EA7-4D77-9B8F-8F56CEA2BF16}" />
</RegistryKey>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
1 change: 1 addition & 0 deletions NanaZip.UI.Classic/NanaZip.vcxproj
Original file line number Diff line number Diff line change
@@ -244,6 +244,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="SevenZip\CPP\7zip\Archive\Common\ItemNameUtils.h" />
<ClInclude Include="SevenZip\CPP\7zip\UI\Explorer\CopyHook.h" />
<ClInclude Include="SevenZip\CPP\7zip\UI\Explorer\MyExplorerCommand.h" />
<ClInclude Include="SevenZip\CPP\Common\DynLimBuf.h" />
<ClInclude Include="SevenZip\C\7zTypes.h" />
5 changes: 4 additions & 1 deletion NanaZip.UI.Classic/NanaZip.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -1090,6 +1090,9 @@
<ClInclude Include="AboutDialog.h">
<Filter>AboutDialog</Filter>
</ClInclude>
<ClInclude Include="SevenZip\CPP\7zip\UI\Explorer\CopyHook.h">
<Filter>SevenZip\UI\Explorer</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Manifest Include="NanaZip.manifest" />
@@ -1099,4 +1102,4 @@
<Filter>SevenZip\Spec</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
</Project>
13 changes: 13 additions & 0 deletions NanaZip.UI.Classic/SevenZip/CPP/7zip/UI/Explorer/CopyHook.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef __COPY_HOOK_H
#define __COPY_HOOK_H

#include "../../../Common/MyWindows.h"

#define COPYHOOK_UUID "{7F4FD2EA-8CC8-43C4-8440-CD76805B4E95}"
#define COPYHOOK_COPY 0x7F4FD2EA

struct CopyHookData {
wchar_t filename[MAX_PATH];
};

#endif
28 changes: 28 additions & 0 deletions NanaZip.UI.Classic/SevenZip/CPP/7zip/UI/FileManager/FM.cpp
Original file line number Diff line number Diff line change
@@ -27,6 +27,10 @@

#include "../GUI/ExtractRes.h"

// **************** NanaZip Modification Start ****************
#include "../Explorer/CopyHook.h"
// **************** NanaZip Modification End ****************

#include "resource.h"

#include "App.h"
@@ -1055,7 +1059,31 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
SWP_NOZORDER | SWP_NOACTIVATE);

::UpdateWindow(hWnd);
// **************** NanaZip Modification Start ****************
break;
// **************** NanaZip Modification End ****************
}

// **************** NanaZip Modification Start ****************
case WM_COPYDATA:
{
PCOPYDATASTRUCT lpCds = (PCOPYDATASTRUCT)lParam;
if (lpCds->dwData == COPYHOOK_COPY && lpCds->cbData == sizeof(CopyHookData)) {
CPanel& panel = g_App.Panels[g_App.LastFocusedPanel];
CCopyToOptions options;
CopyHookData* data = static_cast<CopyHookData*>(lpCds->lpData);
options.folder = UString(data->filename);
options.showErrorMessages = true;
CRecordVector<UInt32> indices;
panel.GetOperatedItemIndices(indices);
if (indices.Size() > 0) {
panel.CopyTo(options, indices, NULL);
}
return TRUE;
}
break;
}
// **************** NanaZip Modification End ****************
}
#ifndef _UNICODE
if (g_IsNT)
84 changes: 59 additions & 25 deletions NanaZip.UI.Classic/SevenZip/CPP/7zip/UI/FileManager/PanelDrag.cpp
Original file line number Diff line number Diff line change
@@ -18,6 +18,11 @@
#include "../Common/CompressCall.h"
#include "../Common/ExtractingFilePath.h"

// **************** NanaZip Modification Start ****************
#include "../Explorer/CopyHook.h"
#include "RegistryUtils.h"
// **************** NanaZip Modification End ****************

#include "MessagesDialog.h"

#include "App.h"
@@ -333,6 +338,11 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
FString dirPrefix;
CTempDir tempDirectory;

// **************** NanaZip Modification Start ****************
bool fastDragDrop = WantFastDragDrop();
FString fakeDirPath;
// **************** NanaZip Modification End ****************

bool isFSFolder = IsFSFolder();
if (isFSFolder)
dirPrefix = us2fs(GetFsPath());
@@ -346,6 +356,18 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
dirPrefix = tempDirectory.GetPath();
// dirPrefix2 = dirPrefix;
NFile::NName::NormalizeDirPathPrefix(dirPrefix);
// **************** NanaZip Modification Start ****************
if (fastDragDrop) {
fakeDirPath = dirPrefix;
fakeDirPath += FTEXT(COPYHOOK_UUID) FTEXT(".");
fakeDirPath.Add_UInt64(reinterpret_cast<UInt64>(g_App._window.operator HWND()));
if (!CreateDir(fakeDirPath))
{
MessageBox_Error(L"Can't create fake folder");
return;
}
}
// **************** NanaZip Modification End ****************
}

CDataObject *dataObjectSpec = new CDataObject;
@@ -357,43 +379,55 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
// names variable is USED for drag and drop from NanaZip to Explorer or to NanaZip archive folder.
// names variable is NOT USED for drag and drop from NanaZip to NanaZip File System folder.

FOR_VECTOR (i, indices)
{
UInt32 index = indices[i];
UString s;
if (isFSFolder)
s = GetItemRelPath(index);
else
// **************** NanaZip Modification Start ****************
if (!isFSFolder && fastDragDrop) {
names.Add(fs2us(fakeDirPath));
}
else {
// **************** NanaZip Modification End ****************
FOR_VECTOR(i, indices)
{
s = GetItemName(index);
/*
// We use (keepAndReplaceEmptyPrefixes = true) in CAgentFolder::Extract
// So the following code is not required.
// Maybe we also can change IFolder interface and send some flag also.
if (s.IsEmpty())
UInt32 index = indices[i];
UString s;
if (isFSFolder)
s = GetItemRelPath(index);
else
{
// Correct_FsFile_Name("") returns "_".
// If extracting code removes empty folder prefixes from path (as it was in old version),
// Explorer can't find "_" folder in temp folder.
// We can ask Explorer to copy parent temp folder "7zE" instead.
s = GetItemName(index);
/*
// We use (keepAndReplaceEmptyPrefixes = true) in CAgentFolder::Extract
// So the following code is not required.
// Maybe we also can change IFolder interface and send some flag also.
names.Clear();
names.Add(dirPrefix2);
break;
if (s.IsEmpty())
{
// Correct_FsFile_Name("") returns "_".
// If extracting code removes empty folder prefixes from path (as it was in old version),
// Explorer can't find "_" folder in temp folder.
// We can ask Explorer to copy parent temp folder "7zE" instead.
names.Clear();
names.Add(dirPrefix2);
break;
}
*/
s = Get_Correct_FsFile_Name(s);
}
*/
s = Get_Correct_FsFile_Name(s);
names.Add(fs2us(dirPrefix) + s);
}
names.Add(fs2us(dirPrefix) + s);
// **************** NanaZip Modification Start ****************
}
// **************** NanaZip Modification End ****************
if (!CopyNamesToHGlobal(dataObjectSpec->hGlobal, names))
return;
}

CDropSource *dropSourceSpec = new CDropSource;
CMyComPtr<IDropSource> dropSource = dropSourceSpec;
dropSourceSpec->NeedExtract = !isFSFolder;
// **************** NanaZip Modification Start ****************
// dropSourceSpec->NeedExtract = !isFSFolder;
dropSourceSpec->NeedExtract = !fastDragDrop && !isFSFolder;
// **************** NanaZip Modification End ****************
dropSourceSpec->Panel = this;
dropSourceSpec->Indices = indices;
dropSourceSpec->Folder = fs2us(dirPrefix);
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ static LPCTSTR const kSingleClick = TEXT("SingleClick");
static LPCTSTR const kAlternativeSelection = TEXT("AlternativeSelection");
// **************** NanaZip Modification Start ****************
static LPCTSTR const kOpenFolderAfterExtract = TEXT("OpenFolderAfterExtract");
static LPCTSTR const kFastDragDrop = TEXT("FastDragDrop");
// **************** NanaZip Modification End ****************
// static LPCTSTR const kUnderline = TEXT("Underline");

@@ -157,6 +158,7 @@ void CFmSettings::Save() const
SaveOption(kLowercaseHashes, LowercaseHashes);
// **************** NanaZip Modification Start ****************
SaveOption(kOpenFolderAfterExtract, OpenFolderAfterExtract);
SaveOption(kFastDragDrop, FastDragDrop);
// **************** NanaZip Modification End ****************
// SaveOption(kUnderline, Underline);

@@ -176,7 +178,10 @@ void CFmSettings::Load()
CopyHistory = false;
FolderHistory = false;
LowercaseHashes = false;
// **************** NanaZip Modification Start ****************
OpenFolderAfterExtract = false;
FastDragDrop = false;
// **************** NanaZip Modification End ****************
// Underline = false;

ShowSystemMenu = false;
@@ -197,6 +202,7 @@ void CFmSettings::Load()
ReadOption(key, kLowercaseHashes, LowercaseHashes);
// **************** NanaZip Modification Start ****************
ReadOption(key, kOpenFolderAfterExtract, OpenFolderAfterExtract);
ReadOption(key, kFastDragDrop, FastDragDrop);
// **************** NanaZip Modification End ****************
// ReadOption(key, kUnderline, Underline);

@@ -218,6 +224,7 @@ bool WantFolderHistory() { return ReadFMOption(kFolderHistory); }
bool WantLowercaseHashes() { return ReadFMOption(kLowercaseHashes); }
// **************** NanaZip Modification Start ****************
bool WantOpenFolderAfterExtract() { return ReadFMOption(kOpenFolderAfterExtract); }
bool WantFastDragDrop() { return ReadFMOption(kFastDragDrop); }
// **************** NanaZip Modification End ****************

static CSysString GetFlatViewName(UInt32 panelIndex)
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ struct CFmSettings
bool LowercaseHashes;
// **************** NanaZip Modification Start ****************
bool OpenFolderAfterExtract;
bool FastDragDrop;
// **************** NanaZip Modification End ****************
// bool Underline;

@@ -54,6 +55,7 @@ bool WantFolderHistory();
bool WantLowercaseHashes();
// **************** NanaZip Modification Start ****************
bool WantOpenFolderAfterExtract();
bool WantFastDragDrop();
// **************** NanaZip Modification End ****************

void SaveFlatView(UInt32 panelIndex, bool enable);
Original file line number Diff line number Diff line change
@@ -35,7 +35,8 @@ static const UInt32 kLangIDs[] =
IDX_SETTINGS_WANT_FOLDER_HISTORY,
IDX_SETTINGS_LOWERCASE_HASHES,
// **************** NanaZip Modification Start ****************
IDX_SETTINGS_OPEN_FOLDER_AFTER
IDX_SETTINGS_OPEN_FOLDER_AFTER,
IDX_SETTINGS_FAST_DRAG_DROP,
// **************** NanaZip Modification End ****************
// , IDT_COMPRESS_MEMORY
};
@@ -130,6 +131,7 @@ bool CSettingsPage::OnInit()
CheckButton(IDX_SETTINGS_ALTERNATIVE_SELECTION, st.AlternativeSelection);
// **************** NanaZip Modification Start ****************
CheckButton(IDX_SETTINGS_OPEN_FOLDER_AFTER, st.OpenFolderAfterExtract);
CheckButton(IDX_SETTINGS_FAST_DRAG_DROP, st.FastDragDrop);
// **************** NanaZip Modification End ****************
// CheckButton(IDX_SETTINGS_UNDERLINE, st.Underline);

@@ -232,6 +234,7 @@ LONG CSettingsPage::OnApply()
st.LowercaseHashes = IsButtonCheckedBool(IDX_SETTINGS_LOWERCASE_HASHES);
// **************** NanaZip Modification Start ****************
st.OpenFolderAfterExtract = IsButtonCheckedBool(IDX_SETTINGS_OPEN_FOLDER_AFTER);
st.FastDragDrop = IsButtonCheckedBool(IDX_SETTINGS_FAST_DRAG_DROP);
// **************** NanaZip Modification End ****************
// st.Underline = IsButtonCheckedBool(IDX_SETTINGS_UNDERLINE);

@@ -352,6 +355,7 @@ bool CSettingsPage::OnButtonClicked(int buttonID, HWND buttonHWND)
case IDX_SETTINGS_ALTERNATIVE_SELECTION:
// **************** NanaZip Modification Start ****************
case IDX_SETTINGS_OPEN_FOLDER_AFTER:
case IDX_SETTINGS_FAST_DRAG_DROP:
// **************** NanaZip Modification End ****************
case IDX_SETTINGS_WANT_ARC_HISTORY:
case IDX_SETTINGS_WANT_PATH_HISTORY:
Original file line number Diff line number Diff line change
@@ -31,6 +31,8 @@ BEGIN
CONTROL "Want CopyHistory", IDX_SETTINGS_WANT_COPY_HISTORY, MY_CHECKBOX, m, 182, xc, 10
CONTROL "Want FolderHistory", IDX_SETTINGS_WANT_FOLDER_HISTORY, MY_CHECKBOX, m, 196, xc, 10
CONTROL "Use Lowercase Hashes", IDX_SETTINGS_LOWERCASE_HASHES, MY_CHECKBOX, m, 220, xc, 10

CONTROL "Use fast drag-and-drop (Experimental)", IDX_SETTINGS_FAST_DRAG_DROP, MY_CHECKBOX, m, 234, xc, 10
// **************** NanaZip Modification End ****************

// LTEXT "Memory usage for Compressing:", IDT_COMPRESS_MEMORY, m, 140, xc, 8
Original file line number Diff line number Diff line change
@@ -15,7 +15,8 @@
#define IDX_SETTINGS_WANT_FOLDER_HISTORY 2512
#define IDX_SETTINGS_LOWERCASE_HASHES 2513
// **************** NanaZip Modification Start ****************
#define IDX_SETTINGS_OPEN_FOLDER_AFTER 2514
#define IDX_SETTINGS_OPEN_FOLDER_AFTER 2514
#define IDX_SETTINGS_FAST_DRAG_DROP 2515
// **************** NanaZip Modification End ****************


6 changes: 6 additions & 0 deletions NanaZip.UI.Modern/NanaZip.LegacyShellExtension.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
LIBRARY

EXPORTS

DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
14 changes: 14 additions & 0 deletions NanaZip.UI.Modern/NanaZip.LegacyShellExtension.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"/>
</dependentAssembly>
</dependency>
</assembly>
285 changes: 285 additions & 0 deletions NanaZip.UI.Modern/NanaZip.LegacyShellExtension.vcxproj

Large diffs are not rendered by default.

688 changes: 688 additions & 0 deletions NanaZip.UI.Modern/NanaZip.LegacyShellExtension.vcxproj.filters

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion NanaZip.UI.Modern/NanaZip.Modern.vcxproj
Original file line number Diff line number Diff line change
@@ -224,6 +224,7 @@
</ClInclude>
<ClInclude Include="NanaZip.UI.h" />
<ClInclude Include="SevenZip\CPP\7zip\Archive\Common\ItemNameUtils.h" />
<ClInclude Include="SevenZip\CPP\7zip\UI\Explorer\CopyHook.h" />
<ClInclude Include="SevenZip\CPP\7zip\UI\Explorer\MyExplorerCommand.h" />
<ClInclude Include="SevenZip\CPP\Common\DynLimBuf.h" />
<ClInclude Include="SevenZip\C\7zTypes.h" />
@@ -490,4 +491,4 @@
<PRIResource Include="Strings\zh-Hans\SponsorPage.resw" />
</ItemGroup>
<Import Sdk="Mile.Project.Configurations" Version="1.0.1426" Project="Mile.Project.Cpp.targets" />
</Project>
</Project>
5 changes: 4 additions & 1 deletion NanaZip.UI.Modern/NanaZip.Modern.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -1057,6 +1057,9 @@
<ClInclude Include="SevenZip\CPP\Common\DynLimBuf.h">
<Filter>SevenZip\Common</Filter>
</ClInclude>
<ClInclude Include="SevenZip\CPP\7zip\UI\Explorer\CopyHook.h">
<Filter>SevenZip\UI\Explorer</Filter>
</ClInclude>
<ClInclude Include="pch.h" />
<ClInclude Include="NanaZip.UI.h" />
</ItemGroup>
@@ -1108,4 +1111,4 @@
<Filter>Strings\sq</Filter>
</PRIResource>
</ItemGroup>
</Project>
</Project>
13 changes: 13 additions & 0 deletions NanaZip.UI.Modern/SevenZip/CPP/7zip/UI/Explorer/CopyHook.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef __COPY_HOOK_H
#define __COPY_HOOK_H

#include "../../../Common/MyWindows.h"

#define COPYHOOK_UUID "{7F4FD2EA-8CC8-43C4-8440-CD76805B4E95}"
#define COPYHOOK_COPY 0x7F4FD2EA

struct CopyHookData {
wchar_t filename[MAX_PATH];
};

#endif
270 changes: 270 additions & 0 deletions NanaZip.UI.Modern/SevenZip/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
// DLLExportsExplorer.cpp
//
// Notes:
// Win2000:
// If I register at HKCR\Folder\ShellEx then DLL is locked.
// otherwise it unloads after explorer closing.
// but if I call menu for desktop items it's locked all the time

#include "StdAfx.h"

#include "../../../Common/MyWindows.h"

#if defined(__clang__) && __clang_major__ >= 4
#pragma GCC diagnostic ignored "-Wnonportable-system-include-path"
#endif
// <olectl.h> : in new Windows Kit 10.0.2**** (NTDDI_WIN10_MN is defined)
// <OleCtl.h> : in another Windows Kit versions
#if defined(NTDDI_WIN10_MN) || defined(__MINGW32__) || defined(__MINGW64__)
#include <olectl.h>
#else
#include <OleCtl.h>
#endif

#if defined(__MINGW32__) || defined(__MINGW64__)
#include <shlguid.h>
#else
#include <ShlGuid.h>
#endif

#include "../../../Common/MyInitGuid.h"

#include "../../../Common/ComTry.h"

#include "../../../Windows/DLL.h"
#include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/NtCheck.h"
#include "../../../Windows/Registry.h"

#include "../FileManager/IFolder.h"

#include "ContextMenu.h"

// **************** NanaZip Modification Start ****************
static LPCTSTR const k_ShellExtName = TEXT("NanaZip Legacy Shell Extension");
static LPCTSTR const k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");

// {23170F69-40C1-278A-1000-00FE00020000}
static LPCTSTR const k_Clsid = TEXT("{23170F69-40C1-278A-1000-00FE00020000}");

DEFINE_GUID(CLSID_CZipContextMenu,
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
k_7zip_GUID_Data3_Common,
0x10, 0x00, 0x00, 0xFE, 0x00, 0x02, 0x00, 0x00);
// **************** NanaZip Modification End ****************

using namespace NWindows;

extern
HINSTANCE g_hInstance;
HINSTANCE g_hInstance = NULL;

extern
HWND g_HWND;
HWND g_HWND = NULL;

extern
LONG g_DllRefCount;
LONG g_DllRefCount = 0; // Reference count of this DLL.

extern
bool g_DisableUserQuestions;
bool g_DisableUserQuestions;


// #define ODS(sz) OutputDebugStringW(L#sz)
#define ODS(sz)

class CShellExtClassFactory final:
public IClassFactory,
public CMyUnknownImp
{
MY_UNKNOWN_IMP1(IClassFactory)

STDMETHOD(CreateInstance)(LPUNKNOWN, REFIID, void**) override final;
STDMETHOD(LockServer)(BOOL) override final;
public:
CShellExtClassFactory() { InterlockedIncrement(&g_DllRefCount); }
~CShellExtClassFactory() { InterlockedDecrement(&g_DllRefCount); }
};

STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
REFIID riid, void **ppvObj)
{
ODS("CShellExtClassFactory::CreateInstance()\r\n");
/*
char s[64];
ConvertUInt32ToHex(riid.Data1, s);
OutputDebugStringA(s);
*/
*ppvObj = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;

CZipContextMenu *shellExt;
try
{
shellExt = new CZipContextMenu();
}
catch(...) { return E_OUTOFMEMORY; }
if (!shellExt)
return E_OUTOFMEMORY;

IContextMenu *ctxm = shellExt;
const HRESULT res = ctxm->QueryInterface(riid, ppvObj);
if (res != S_OK)
delete shellExt;
return res;
}


STDMETHODIMP CShellExtClassFactory::LockServer(BOOL /* fLock */)
{
return S_OK; // Check it
}


#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
#define NT_CHECK_FAIL_ACTION return FALSE;
#endif

extern "C"
BOOL WINAPI DllMain(
#ifdef UNDER_CE
HANDLE hInstance
#else
HINSTANCE hInstance
#endif
, DWORD dwReason, LPVOID);

extern "C"
BOOL WINAPI DllMain(
#ifdef UNDER_CE
HANDLE hInstance
#else
HINSTANCE hInstance
#endif
, DWORD dwReason, LPVOID)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
g_hInstance = (HINSTANCE)hInstance;
ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n");
NT_CHECK
}
else if (dwReason == DLL_PROCESS_DETACH)
{
ODS("In DLLMain, DLL_PROCESS_DETACH\r\n");
}
return TRUE;
}


// Used to determine whether the DLL can be unloaded by OLE

STDAPI DllCanUnloadNow(void)
{
ODS("In DLLCanUnloadNow\r\n");
/*
if (g_DllRefCount == 0)
ODS( "g_DllRefCount == 0");
else
ODS( "g_DllRefCount != 0");
*/
return (g_DllRefCount == 0 ? S_OK : S_FALSE);
}

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
ODS("In DllGetClassObject\r\n");
*ppv = NULL;
if (IsEqualIID(rclsid, CLSID_CZipContextMenu))
{
CShellExtClassFactory *cf;
try
{
cf = new CShellExtClassFactory;
}
catch(...) { return E_OUTOFMEMORY; }
if (!cf)
return E_OUTOFMEMORY;
IClassFactory *cf2 = cf;
const HRESULT res = cf2->QueryInterface(riid, ppv);
if (res != S_OK)
delete cf;
return res;
}
return CLASS_E_CLASSNOTAVAILABLE;
// return _Module.GetClassObject(rclsid, riid, ppv);
}


static BOOL RegisterServer()
{
ODS("RegisterServer\r\n");
FString modulePath;
if (!NDLL::MyGetModuleFileName(modulePath))
return FALSE;
const UString modulePathU = fs2us(modulePath);

CSysString s ("CLSID\\");
s += k_Clsid;

{
NRegistry::CKey key;
if (key.Create(HKEY_CLASSES_ROOT, s, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
return FALSE;
key.SetValue(NULL, k_ShellExtName);
NRegistry::CKey keyInproc;
if (keyInproc.Create(key, TEXT("InprocServer32"), NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
return FALSE;
keyInproc.SetValue(NULL, modulePathU);
keyInproc.SetValue(TEXT("ThreadingModel"), TEXT("Apartment"));
}

#if !defined(_WIN64) && !defined(UNDER_CE)
if (IsItWindowsNT())
#endif
{
NRegistry::CKey key;
if (key.Create(HKEY_LOCAL_MACHINE, k_Approved, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR)
key.SetValue(k_Clsid, k_ShellExtName);
}

ODS("RegisterServer :: return TRUE");
return TRUE;
}

STDAPI DllRegisterServer(void)
{
return RegisterServer() ? S_OK: SELFREG_E_CLASS;
}

static BOOL UnregisterServer()
{
CSysString s ("CLSID\\");
s += k_Clsid;

RegDeleteKey(HKEY_CLASSES_ROOT, s + TEXT("\\InprocServer32"));
RegDeleteKey(HKEY_CLASSES_ROOT, s);

#if !defined(_WIN64) && !defined(UNDER_CE)
if (IsItWindowsNT())
#endif
{
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, k_Approved, 0, KEY_SET_VALUE, &hKey) == NOERROR)
{
RegDeleteValue(hKey, k_Clsid);
RegCloseKey(hKey);
}
}

return TRUE;
}

STDAPI DllUnregisterServer(void)
{
return UnregisterServer() ? S_OK: SELFREG_E_CLASS;
}
25 changes: 25 additions & 0 deletions NanaZip.UI.Modern/SevenZip/CPP/7zip/UI/FileManager/FM.cpp
Original file line number Diff line number Diff line change
@@ -27,6 +27,10 @@

#include "../GUI/ExtractRes.h"

// **************** NanaZip Modification Start ****************
#include "../Explorer/CopyHook.h"
// **************** NanaZip Modification End ****************

#include "resource.h"

#include "App.h"
@@ -1065,6 +1069,27 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

break;
}

// **************** NanaZip Modification Start ****************
case WM_COPYDATA:
{
PCOPYDATASTRUCT lpCds = (PCOPYDATASTRUCT)lParam;
if (lpCds->dwData == COPYHOOK_COPY && lpCds->cbData == sizeof(CopyHookData)) {
CPanel& panel = g_App.Panels[g_App.LastFocusedPanel];
CCopyToOptions options;
CopyHookData* data = static_cast<CopyHookData*>(lpCds->lpData);
options.folder = UString(data->filename);
options.showErrorMessages = true;
CRecordVector<UInt32> indices;
panel.GetOperatedItemIndices(indices);
if (indices.Size() > 0) {
panel.CopyTo(options, indices, NULL);
}
return TRUE;
}
break;
}
// **************** NanaZip Modification End ****************
default:
break;
}
84 changes: 59 additions & 25 deletions NanaZip.UI.Modern/SevenZip/CPP/7zip/UI/FileManager/PanelDrag.cpp
Original file line number Diff line number Diff line change
@@ -18,6 +18,11 @@
#include "../Common/CompressCall.h"
#include "../Common/ExtractingFilePath.h"

// **************** NanaZip Modification Start ****************
#include "../Explorer/CopyHook.h"
#include "RegistryUtils.h"
// **************** NanaZip Modification End ****************

#include "MessagesDialog.h"

#include "App.h"
@@ -333,6 +338,11 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
FString dirPrefix;
CTempDir tempDirectory;

// **************** NanaZip Modification Start ****************
bool fastDragDrop = WantFastDragDrop();
FString fakeDirPath;
// **************** NanaZip Modification End ****************

bool isFSFolder = IsFSFolder();
if (isFSFolder)
dirPrefix = us2fs(GetFsPath());
@@ -346,6 +356,18 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
dirPrefix = tempDirectory.GetPath();
// dirPrefix2 = dirPrefix;
NFile::NName::NormalizeDirPathPrefix(dirPrefix);
// **************** NanaZip Modification Start ****************
if (fastDragDrop) {
fakeDirPath = dirPrefix;
fakeDirPath += FTEXT(COPYHOOK_UUID) FTEXT(".");
fakeDirPath.Add_UInt64(reinterpret_cast<UInt64>(g_App._window.operator HWND()));
if (!CreateDir(fakeDirPath))
{
MessageBox_Error(L"Can't create fake folder");
return;
}
}
// **************** NanaZip Modification End ****************
}

CDataObject *dataObjectSpec = new CDataObject;
@@ -357,43 +379,55 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
// names variable is USED for drag and drop from NanaZip to Explorer or to NanaZip archive folder.
// names variable is NOT USED for drag and drop from NanaZip to NanaZip File System folder.

FOR_VECTOR (i, indices)
{
UInt32 index = indices[i];
UString s;
if (isFSFolder)
s = GetItemRelPath(index);
else
// **************** NanaZip Modification Start ****************
if (!isFSFolder && fastDragDrop) {
names.Add(fs2us(fakeDirPath));
}
else {
// **************** NanaZip Modification End ****************
FOR_VECTOR(i, indices)
{
s = GetItemName(index);
/*
// We use (keepAndReplaceEmptyPrefixes = true) in CAgentFolder::Extract
// So the following code is not required.
// Maybe we also can change IFolder interface and send some flag also.
if (s.IsEmpty())
UInt32 index = indices[i];
UString s;
if (isFSFolder)
s = GetItemRelPath(index);
else
{
// Correct_FsFile_Name("") returns "_".
// If extracting code removes empty folder prefixes from path (as it was in old version),
// Explorer can't find "_" folder in temp folder.
// We can ask Explorer to copy parent temp folder "7zE" instead.
s = GetItemName(index);
/*
// We use (keepAndReplaceEmptyPrefixes = true) in CAgentFolder::Extract
// So the following code is not required.
// Maybe we also can change IFolder interface and send some flag also.
names.Clear();
names.Add(dirPrefix2);
break;
if (s.IsEmpty())
{
// Correct_FsFile_Name("") returns "_".
// If extracting code removes empty folder prefixes from path (as it was in old version),
// Explorer can't find "_" folder in temp folder.
// We can ask Explorer to copy parent temp folder "7zE" instead.
names.Clear();
names.Add(dirPrefix2);
break;
}
*/
s = Get_Correct_FsFile_Name(s);
}
*/
s = Get_Correct_FsFile_Name(s);
names.Add(fs2us(dirPrefix) + s);
}
names.Add(fs2us(dirPrefix) + s);
// **************** NanaZip Modification Start ****************
}
// **************** NanaZip Modification End ****************
if (!CopyNamesToHGlobal(dataObjectSpec->hGlobal, names))
return;
}

CDropSource *dropSourceSpec = new CDropSource;
CMyComPtr<IDropSource> dropSource = dropSourceSpec;
dropSourceSpec->NeedExtract = !isFSFolder;
// **************** NanaZip Modification Start ****************
// dropSourceSpec->NeedExtract = !isFSFolder;
dropSourceSpec->NeedExtract = !fastDragDrop && !isFSFolder;
// **************** NanaZip Modification End ****************
dropSourceSpec->Panel = this;
dropSourceSpec->Indices = indices;
dropSourceSpec->Folder = fs2us(dirPrefix);
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ static LPCTSTR const kSingleClick = TEXT("SingleClick");
static LPCTSTR const kAlternativeSelection = TEXT("AlternativeSelection");
// **************** NanaZip Modification Start ****************
static LPCTSTR const kOpenFolderAfterExtract = TEXT("OpenFolderAfterExtract");
static LPCTSTR const kFastDragDrop = TEXT("FastDragDrop");
// **************** NanaZip Modification End ****************
// static LPCTSTR const kUnderline = TEXT("Underline");

@@ -157,6 +158,7 @@ void CFmSettings::Save() const
SaveOption(kLowercaseHashes, LowercaseHashes);
// **************** NanaZip Modification Start ****************
SaveOption(kOpenFolderAfterExtract, OpenFolderAfterExtract);
SaveOption(kFastDragDrop, FastDragDrop);
// **************** NanaZip Modification End ****************
// SaveOption(kUnderline, Underline);

@@ -176,7 +178,10 @@ void CFmSettings::Load()
CopyHistory = false;
FolderHistory = false;
LowercaseHashes = false;
// **************** NanaZip Modification Start ****************
OpenFolderAfterExtract = false;
FastDragDrop = false;
// **************** NanaZip Modification End ****************
// Underline = false;

ShowSystemMenu = false;
@@ -197,6 +202,7 @@ void CFmSettings::Load()
ReadOption(key, kLowercaseHashes, LowercaseHashes);
// **************** NanaZip Modification Start ****************
ReadOption(key, kOpenFolderAfterExtract, OpenFolderAfterExtract);
ReadOption(key, kFastDragDrop, FastDragDrop);
// **************** NanaZip Modification End ****************
// ReadOption(key, kUnderline, Underline);

@@ -218,6 +224,7 @@ bool WantFolderHistory() { return ReadFMOption(kFolderHistory); }
bool WantLowercaseHashes() { return ReadFMOption(kLowercaseHashes); }
// **************** NanaZip Modification Start ****************
bool WantOpenFolderAfterExtract() { return ReadFMOption(kOpenFolderAfterExtract); }
bool WantFastDragDrop() { return ReadFMOption(kFastDragDrop); }
// **************** NanaZip Modification End ****************

static CSysString GetFlatViewName(UInt32 panelIndex)
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ struct CFmSettings
bool LowercaseHashes;
// **************** NanaZip Modification Start ****************
bool OpenFolderAfterExtract;
bool FastDragDrop;
// **************** NanaZip Modification End ****************
// bool Underline;

@@ -54,6 +55,7 @@ bool WantFolderHistory();
bool WantLowercaseHashes();
// **************** NanaZip Modification Start ****************
bool WantOpenFolderAfterExtract();
bool WantFastDragDrop();
// **************** NanaZip Modification End ****************

void SaveFlatView(UInt32 panelIndex, bool enable);
Original file line number Diff line number Diff line change
@@ -130,6 +130,7 @@ bool CSettingsPage::OnInit()
CheckButton(IDX_SETTINGS_ALTERNATIVE_SELECTION, st.AlternativeSelection);
// **************** NanaZip Modification Start ****************
CheckButton(IDX_SETTINGS_OPEN_FOLDER_AFTER, st.OpenFolderAfterExtract);
CheckButton(IDX_SETTINGS_FAST_DRAG_DROP, st.FastDragDrop);
// **************** NanaZip Modification End ****************
// CheckButton(IDX_SETTINGS_UNDERLINE, st.Underline);

@@ -232,6 +233,7 @@ LONG CSettingsPage::OnApply()
st.LowercaseHashes = IsButtonCheckedBool(IDX_SETTINGS_LOWERCASE_HASHES);
// **************** NanaZip Modification Start ****************
st.OpenFolderAfterExtract = IsButtonCheckedBool(IDX_SETTINGS_OPEN_FOLDER_AFTER);
st.FastDragDrop = IsButtonCheckedBool(IDX_SETTINGS_FAST_DRAG_DROP);
// **************** NanaZip Modification End ****************
// st.Underline = IsButtonCheckedBool(IDX_SETTINGS_UNDERLINE);

@@ -352,6 +354,7 @@ bool CSettingsPage::OnButtonClicked(int buttonID, HWND buttonHWND)
case IDX_SETTINGS_ALTERNATIVE_SELECTION:
// **************** NanaZip Modification Start ****************
case IDX_SETTINGS_OPEN_FOLDER_AFTER:
case IDX_SETTINGS_FAST_DRAG_DROP:
// **************** NanaZip Modification End ****************
case IDX_SETTINGS_WANT_ARC_HISTORY:
case IDX_SETTINGS_WANT_PATH_HISTORY:
Original file line number Diff line number Diff line change
@@ -31,6 +31,8 @@ BEGIN
CONTROL "Want CopyHistory", IDX_SETTINGS_WANT_COPY_HISTORY, MY_CHECKBOX, m, 182, xc, 10
CONTROL "Want FolderHistory", IDX_SETTINGS_WANT_FOLDER_HISTORY, MY_CHECKBOX, m, 196, xc, 10
CONTROL "Use Lowercase Hashes", IDX_SETTINGS_LOWERCASE_HASHES, MY_CHECKBOX, m, 220, xc, 10

CONTROL "Use fast drag-and-drop (Experimental)", IDX_SETTINGS_FAST_DRAG_DROP, MY_CHECKBOX, m, 234, xc, 10
// **************** NanaZip Modification End ****************

// LTEXT "Memory usage for Compressing:", IDT_COMPRESS_MEMORY, m, 140, xc, 8
Original file line number Diff line number Diff line change
@@ -15,7 +15,8 @@
#define IDX_SETTINGS_WANT_FOLDER_HISTORY 2512
#define IDX_SETTINGS_LOWERCASE_HASHES 2513
// **************** NanaZip Modification Start ****************
#define IDX_SETTINGS_OPEN_FOLDER_AFTER 2514
#define IDX_SETTINGS_OPEN_FOLDER_AFTER 2514
#define IDX_SETTINGS_FAST_DRAG_DROP 2515
// **************** NanaZip Modification End ****************


47 changes: 47 additions & 0 deletions NanaZip.sln
Original file line number Diff line number Diff line change
@@ -51,6 +51,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "K7PalStatic", "K7Pal\K7PalS
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "K7Pal", "K7Pal\K7Pal.vcxproj", "{279F7FA5-7DDC-4635-99B0-3C7F2179DAE0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extras", "Extras", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NanaZip.Extras.ShellExtension", "NanaZip.Extras\NanaZip.Extras.ShellExtension.vcxproj", "{C1CBC99A-1225-446F-975D-4158D57BF586}"
EndProject
Project("{B7DD6F7E-DEF8-4E67-B5B7-07EF123DB6F0}") = "NanaZip.Extras.Setup", "NanaZip.Extras\Setup\NanaZip.Extras.Setup.wixproj", "{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NanaZip.LegacyShellExtension", "NanaZip.UI.Modern\NanaZip.LegacyShellExtension.vcxproj", "{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
@@ -257,6 +265,42 @@ Global
{279F7FA5-7DDC-4635-99B0-3C7F2179DAE0}.Release|x64.Build.0 = Release|x64
{279F7FA5-7DDC-4635-99B0-3C7F2179DAE0}.Release|x86.ActiveCfg = Release|Win32
{279F7FA5-7DDC-4635-99B0-3C7F2179DAE0}.Release|x86.Build.0 = Release|Win32
{C1CBC99A-1225-446F-975D-4158D57BF586}.Debug|ARM64.ActiveCfg = Debug|ARM64
{C1CBC99A-1225-446F-975D-4158D57BF586}.Debug|ARM64.Build.0 = Debug|ARM64
{C1CBC99A-1225-446F-975D-4158D57BF586}.Debug|x64.ActiveCfg = Debug|x64
{C1CBC99A-1225-446F-975D-4158D57BF586}.Debug|x64.Build.0 = Debug|x64
{C1CBC99A-1225-446F-975D-4158D57BF586}.Debug|x86.ActiveCfg = Debug|Win32
{C1CBC99A-1225-446F-975D-4158D57BF586}.Debug|x86.Build.0 = Debug|Win32
{C1CBC99A-1225-446F-975D-4158D57BF586}.Release|ARM64.ActiveCfg = Release|ARM64
{C1CBC99A-1225-446F-975D-4158D57BF586}.Release|ARM64.Build.0 = Release|ARM64
{C1CBC99A-1225-446F-975D-4158D57BF586}.Release|x64.ActiveCfg = Release|x64
{C1CBC99A-1225-446F-975D-4158D57BF586}.Release|x64.Build.0 = Release|x64
{C1CBC99A-1225-446F-975D-4158D57BF586}.Release|x86.ActiveCfg = Release|Win32
{C1CBC99A-1225-446F-975D-4158D57BF586}.Release|x86.Build.0 = Release|Win32
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Debug|ARM64.ActiveCfg = Debug|ARM64
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Debug|ARM64.Build.0 = Debug|ARM64
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Debug|x64.ActiveCfg = Debug|x64
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Debug|x64.Build.0 = Debug|x64
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Debug|x86.ActiveCfg = Debug|x86
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Debug|x86.Build.0 = Debug|x86
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Release|ARM64.ActiveCfg = Release|ARM64
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Release|ARM64.Build.0 = Release|ARM64
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Release|x64.ActiveCfg = Release|x64
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Release|x64.Build.0 = Release|x64
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Release|x86.ActiveCfg = Release|x86
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05}.Release|x86.Build.0 = Release|x86
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Debug|ARM64.ActiveCfg = Debug|ARM64
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Debug|ARM64.Build.0 = Debug|ARM64
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Debug|x64.ActiveCfg = Debug|x64
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Debug|x64.Build.0 = Debug|x64
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Debug|x86.ActiveCfg = Debug|Win32
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Debug|x86.Build.0 = Debug|Win32
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Release|ARM64.ActiveCfg = Release|ARM64
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Release|ARM64.Build.0 = Release|ARM64
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Release|x64.ActiveCfg = Release|x64
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Release|x64.Build.0 = Release|x64
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Release|x86.ActiveCfg = Release|Win32
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -282,6 +326,9 @@ Global
{1B20CAF2-FCA3-490D-BDD7-2D7DD439787A} = {94A1E11C-B722-4BAE-9B12-1495F5EF3CC9}
{249B9FCE-0114-4EE9-A31E-C8A36EEA2279} = {1B20CAF2-FCA3-490D-BDD7-2D7DD439787A}
{279F7FA5-7DDC-4635-99B0-3C7F2179DAE0} = {1B20CAF2-FCA3-490D-BDD7-2D7DD439787A}
{C1CBC99A-1225-446F-975D-4158D57BF586} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{4A3279F7-FFC6-2AF5-339C-1CFE16D49E05} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2} = {B954CA12-11FE-45D8-A4D2-562560E1CD4D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DE2C16C4-5306-4103-9C2A-749DC32B5CA6}
5 changes: 4 additions & 1 deletion NanaZipPackage/NanaZipPackage.wapproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Sdk="Mile.Project.Configurations" Version="1.0.1426" Project="Mile.Project.Platform.x64.props" />
<Import Sdk="Mile.Project.Configurations" Version="1.0.1426" Project="Mile.Project.Platform.ARM64.props" />
@@ -66,6 +66,9 @@
<ProjectReference Include="..\NanaZip.UI.Modern\NanaZip.Windows.vcxproj">
<Project>{3E5B58DE-4FDC-4F45-93A4-8AA3D61C614D}</Project>
</ProjectReference>
<ProjectReference Include="..\NanaZip.UI.Modern\NanaZip.LegacyShellExtension.vcxproj">
<Project>{F5C18E0D-AE2D-494D-9D28-0C435C8ED5C2}</Project>
</ProjectReference>
</ItemGroup>
<Import Sdk="Mile.Project.Configurations" Version="1.0.1426" Project="Mile.Project.Wap.targets" />
</Project>
14 changes: 12 additions & 2 deletions NanaZipPackage/Package.appxmanifest
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>

<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
@@ -10,13 +10,14 @@
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
xmlns:desktop9="http://schemas.microsoft.com/appx/manifest/desktop/windows10/9"
xmlns:desktop10="http://schemas.microsoft.com/appx/manifest/desktop/windows10/10"
xmlns:uap8="http://schemas.microsoft.com/appx/manifest/uap/windows10/8"
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
xmlns:virtualization="http://schemas.microsoft.com/appx/manifest/virtualization/windows10"
xmlns:uap16="http://schemas.microsoft.com/appx/manifest/uap/windows10/16"
xmlns:uap17="http://schemas.microsoft.com/appx/manifest/uap/windows10/17"
IgnorableNamespaces="uap rescap desktop uap2 uap3 com desktop4 desktop5 desktop10 uap8 uap10 virtualization uap16 uap17">
IgnorableNamespaces="uap rescap desktop uap2 uap3 com desktop4 desktop5 desktop9 desktop10 uap8 uap10 virtualization uap16 uap17">

<Identity
Name="40174MouriNaruto.NanaZipPreview"
@@ -289,11 +290,20 @@
</desktop10:ItemType>
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>
<desktop9:Extension Category="windows.fileExplorerClassicDragDropContextMenuHandler">
<desktop9:FileExplorerClassicDragDropContextMenuHandler>
<desktop9:ExtensionHandler Type="Directory" Clsid="23170F69-40C1-278A-1000-00FE00020000" />
<desktop9:ExtensionHandler Type="Drive" Clsid="23170F69-40C1-278A-1000-00FE00020000" />
</desktop9:FileExplorerClassicDragDropContextMenuHandler>
</desktop9:Extension>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:SurrogateServer DisplayName="NanaZip Shell Extension">
<com:Class Id="469D94E9-6AF4-4395-B396-99B1308F8CE5" Path="NanaZip.ShellExtension.dll" ThreadingModel="STA"/>
</com:SurrogateServer>
<com:SurrogateServer DisplayName="NanaZip Legacy Shell Extension">
<com:Class Id="23170F69-40C1-278A-1000-00FE00020000" Path="NanaZip.LegacyShellExtension.dll" ThreadingModel="STA"/>
</com:SurrogateServer>
</com:ComServer>
</com:Extension>
</Extensions>