📄 panelitemopen.cpp
字号:
// PanelItemOpen.cpp
#include "StdAfx.h"
#include "resource.h"
#include "Common/StringConvert.h"
#include "Common/Random.h"
#include "Common/StringConvert.h"
#include "Common/AutoPtr.h"
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
#include "Windows/Thread.h"
#include "Windows/Synchronization.h"
#include "Windows/Error.h"
#include "ExtractCallback.h"
#include "UpdateCallback100.h"
#include "IFolder.h"
#include "FileFolderPluginOpen.h"
#include "FormatUtils.h"
#include "Panel.h"
#include "RegistryUtils.h"
#include "LangUtils.h"
using namespace NWindows;
using namespace NSynchronization;
using namespace NFile;
using namespace NDirectory;
extern HWND g_HWND;
#ifndef _UNICODE
extern bool g_IsNT;
#endif
static wchar_t *kTempDirPrefix = L"7zO";
static bool IsNameVirus(const UString &name)
{
return (name.Find(L" ") >= 0);
}
struct CTmpProcessInfo: public CTempFileInfo
{
HANDLE ProcessHandle;
HWND Window;
UString FullPathFolderPrefix;
bool UsePassword;
UString Password;
CTmpProcessInfo(): UsePassword(false) {}
};
class CTmpProcessInfoRelease
{
CTmpProcessInfo *_tmpProcessInfo;
public:
bool _needDelete;
CTmpProcessInfoRelease(CTmpProcessInfo &tmpProcessInfo):
_tmpProcessInfo(&tmpProcessInfo), _needDelete(true) {}
~CTmpProcessInfoRelease()
{
if (_needDelete)
_tmpProcessInfo->DeleteDirAndFile();
}
};
HRESULT CPanel::OpenItemAsArchive(const UString &name,
const UString &folderPath, const UString &filePath,
const UString &virtualFilePath,
bool &encrypted)
{
encrypted = false;
CFolderLink folderLink;
if (!NFile::NFind::FindFile(filePath, folderLink.FileInfo))
return E_FAIL;
if (folderLink.FileInfo.IsDir())
return S_FALSE;
folderLink.FilePath = filePath;
folderLink.FolderPath = folderPath;
folderLink.VirtualPath = virtualFilePath;
CMyComPtr<IFolderFolder> newFolder;
// _passwordIsDefined = false;
// _password.Empty();
NDLL::CLibrary library;
UString password;
RINOK(OpenFileFolderPlugin(filePath, &library, &newFolder, GetParent(), encrypted, password));
folderLink.Password = password;
folderLink.UsePassword = encrypted;
folderLink.ParentFolder = _folder;
folderLink.ItemName = name;
_parentFolders.Add(folderLink);
_parentFolders.Back().Library.Attach(_library.Detach());
_folder.Release();
_library.Free();
_folder = newFolder;
_library.Attach(library.Detach());
_flatMode = _flatModeForArc;
return S_OK;
}
HRESULT CPanel::OpenItemAsArchive(const UString &name)
{
bool encrypted;
return OpenItemAsArchive(name, _currentFolderPrefix,
_currentFolderPrefix + name,
_currentFolderPrefix + name,
encrypted);
}
HRESULT CPanel::OpenItemAsArchive(int index)
{
CDisableTimerProcessing disableTimerProcessing1(*this);
RINOK(OpenItemAsArchive(GetItemRelPath(index)));
RefreshListCtrl();
return S_OK;
}
HRESULT CPanel::OpenParentArchiveFolder()
{
CDisableTimerProcessing disableTimerProcessing1(*this);
if (_parentFolders.Size() < 2)
return S_OK;
CFolderLink &folderLink = _parentFolders.Back();
NFind::CFileInfoW newFileInfo;
if (NFind::FindFile(folderLink.FilePath, newFileInfo))
{
if (newFileInfo.Size != folderLink.FileInfo.Size ||
CompareFileTime(&newFileInfo.MTime, &folderLink.FileInfo.MTime) != 0)
{
UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE,
0x03020280, folderLink.ItemName);
if (::MessageBoxW(HWND(*this), message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
{
if (OnOpenItemChanged(folderLink.FolderPath, folderLink.ItemName,
folderLink.UsePassword, folderLink.Password) != S_OK)
{
::MessageBoxW(HWND(*this), MyFormatNew(IDS_CANNOT_UPDATE_FILE,
0x03020281, folderLink.FilePath), L"7-Zip", MB_OK | MB_ICONSTOP);
return S_OK;
}
}
}
}
folderLink.DeleteDirAndFile();
return S_OK;
}
static const wchar_t *kStartExtensions[] =
{
L"exe", L"bat", L"com",
L"chm",
L"msi", L"doc", L"xls", L"ppt", L"pps", L"wps", L"wpt", L"wks", L"xlr", L"wdb",
L"docx", L"docm", L"dotx", L"dotm", L"xlsx", L"xlsm", L"xltx", L"xltm", L"xlsb",
L"xlam", L"pptx", L"pptm", L"potx", L"potm", L"ppam", L"ppsx", L"ppsm", L"xsn",
L"dwf",
L"odt", L"ods",
L"wb3",
L"pdf"
};
static bool DoItemAlwaysStart(const UString &name)
{
int extPos = name.ReverseFind('.');
if (extPos < 0)
return false;
UString ext = name.Mid(extPos + 1);
ext.MakeLower();
for (int i = 0; i < sizeof(kStartExtensions) / sizeof(kStartExtensions[0]); i++)
if (ext.Compare(kStartExtensions[i]) == 0)
return true;
return false;
}
static HANDLE StartEditApplication(const UString &path, HWND window)
{
UString command;
ReadRegEditor(command);
if (command.IsEmpty())
{
if (!MyGetWindowsDirectory(command))
return 0;
NFile::NName::NormalizeDirPathPrefix(command);
command += L"notepad.exe";
}
command = UString(L"\"") + command + UString(L"\"");
command += L" \"";
command += UString(path);
command += L"\"";
PROCESS_INFORMATION processInformation;
BOOL result;
#ifndef _UNICODE
if (!g_IsNT)
{
STARTUPINFOA startupInfo;
startupInfo.cb = sizeof(startupInfo);
startupInfo.lpReserved = 0;
startupInfo.lpDesktop = 0;
startupInfo.lpTitle = 0;
startupInfo.dwFlags = 0;
startupInfo.cbReserved2 = 0;
startupInfo.lpReserved2 = 0;
result = ::CreateProcessA(NULL, (CHAR *)(const CHAR *)GetSystemString(command),
NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation);
}
else
#endif
{
STARTUPINFOW startupInfo;
startupInfo.cb = sizeof(startupInfo);
startupInfo.lpReserved = 0;
startupInfo.lpDesktop = 0;
startupInfo.lpTitle = 0;
startupInfo.dwFlags = 0;
startupInfo.cbReserved2 = 0;
startupInfo.lpReserved2 = 0;
result = ::CreateProcessW(NULL, (WCHAR *)(const WCHAR *)command,
NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation);
}
if (result != FALSE)
{
::CloseHandle(processInformation.hThread);
return processInformation.hProcess;
}
::MessageBoxW(window, LangString(IDS_CANNOT_START_EDITOR, 0x03020282),
L"7-Zip", MB_OK | MB_ICONSTOP);
return 0;
}
#ifndef _UNICODE
typedef BOOL (WINAPI * ShellExecuteExWP)(LPSHELLEXECUTEINFOW lpExecInfo);
#endif
static HANDLE StartApplication(const UString &dir, const UString &path, HWND window)
{
UINT32 result;
HANDLE hProcess;
#ifndef _UNICODE
if (g_IsNT)
{
SHELLEXECUTEINFOW execInfo;
execInfo.cbSize = sizeof(execInfo);
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
execInfo.hwnd = NULL;
execInfo.lpVerb = NULL;
execInfo.lpFile = path;
execInfo.lpParameters = NULL;
execInfo.lpDirectory = dir.IsEmpty() ? NULL : (LPCWSTR)dir;
execInfo.nShow = SW_SHOWNORMAL;
execInfo.hProcess = 0;
ShellExecuteExWP shellExecuteExW = (ShellExecuteExWP)
::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "ShellExecuteExW");
if (shellExecuteExW == 0)
return 0;
shellExecuteExW(&execInfo);
result = (UINT32)(UINT_PTR)execInfo.hInstApp;
hProcess = execInfo.hProcess;
}
else
#endif
{
SHELLEXECUTEINFO execInfo;
execInfo.cbSize = sizeof(execInfo);
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
execInfo.hwnd = NULL;
execInfo.lpVerb = NULL;
const CSysString sysPath = GetSystemString(path);
const CSysString sysDir = GetSystemString(dir);
execInfo.lpFile = sysPath;
execInfo.lpParameters = NULL;
execInfo.lpDirectory = sysDir.IsEmpty() ? NULL : (LPCTSTR)sysDir;
execInfo.nShow = SW_SHOWNORMAL;
execInfo.hProcess = 0;
::ShellExecuteEx(&execInfo);
result = (UINT32)(UINT_PTR)execInfo.hInstApp;
hProcess = execInfo.hProcess;
}
if(result <= 32)
{
switch(result)
{
case SE_ERR_NOASSOC:
::MessageBoxW(window,
NError::MyFormatMessageW(::GetLastError()),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -