📄 app.cpp
字号:
// App.cpp
#include "StdAfx.h"
#include "resource.h"
#include "OverwriteDialogRes.h"
#include "Common/IntToString.h"
#include "Common/StringConvert.h"
#include "Windows/COM.h"
#include "Windows/Error.h"
#include "Windows/FileDir.h"
#include "Windows/PropVariant.h"
#include "Windows/PropVariantConversions.h"
#include "Windows/Thread.h"
#include "App.h"
#include "CopyDialog.h"
#include "ExtractCallback.h"
#include "FormatUtils.h"
#include "IFolder.h"
#include "LangUtils.h"
#include "RegistryUtils.h"
#include "ViewSettings.h"
using namespace NWindows;
using namespace NFile;
using namespace NFind;
extern DWORD g_ComCtl32Version;
extern HINSTANCE g_hInstance;
static LPCWSTR kTempDirPrefix = L"7zE";
void CPanelCallbackImp::OnTab()
{
if (g_App.NumPanels != 1)
_app->Panels[1 - _index].SetFocusToList();
_app->RefreshTitle();
}
void CPanelCallbackImp::SetFocusToPath(int index)
{
int newPanelIndex = index;
if (g_App.NumPanels == 1)
newPanelIndex = g_App.LastFocusedPanel;
_app->RefreshTitle();
_app->Panels[newPanelIndex]._headerComboBox.SetFocus();
_app->Panels[newPanelIndex]._headerComboBox.ShowDropDown();
}
void CPanelCallbackImp::OnCopy(bool move, bool copyToSame) { _app->OnCopy(move, copyToSame, _index); }
void CPanelCallbackImp::OnSetSameFolder() { _app->OnSetSameFolder(_index); }
void CPanelCallbackImp::OnSetSubFolder() { _app->OnSetSubFolder(_index); }
void CPanelCallbackImp::PanelWasFocused() { _app->SetFocusedPanel(_index); _app->RefreshTitle(_index); }
void CPanelCallbackImp::DragBegin() { _app->DragBegin(_index); }
void CPanelCallbackImp::DragEnd() { _app->DragEnd(); }
void CPanelCallbackImp::RefreshTitle(bool always) { _app->RefreshTitle(_index, always); }
void CApp::SetListSettings()
{
bool showDots = ReadShowDots();
bool showRealFileIcons = ReadShowRealFileIcons();
DWORD extendedStyle = LVS_EX_HEADERDRAGDROP;
if (ReadFullRow())
extendedStyle |= LVS_EX_FULLROWSELECT;
if (ReadShowGrid())
extendedStyle |= LVS_EX_GRIDLINES;
bool mySelectionMode = ReadAlternativeSelection();
/*
if (ReadSingleClick())
{
extendedStyle |= LVS_EX_ONECLICKACTIVATE
| LVS_EX_TRACKSELECT;
if (ReadUnderline())
extendedStyle |= LVS_EX_UNDERLINEHOT;
}
*/
for (int i = 0; i < kNumPanelsMax; i++)
{
CPanel &panel = Panels[i];
panel._mySelectMode = mySelectionMode;
panel._showDots = showDots;
panel._showRealFileIcons = showRealFileIcons;
panel._exStyle = extendedStyle;
DWORD style = (DWORD)panel._listView.GetStyle();
if (mySelectionMode)
style |= LVS_SINGLESEL;
else
style &= ~LVS_SINGLESEL;
panel._listView.SetStyle(style);
panel.SetExtendedStyle();
}
}
void CApp::SetShowSystemMenu()
{
ShowSystemMenu = ReadShowSystemMenu();
}
HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, bool &archiveIsOpened, bool &encrypted)
{
if (PanelsCreated[panelIndex])
return S_OK;
m_PanelCallbackImp[panelIndex].Init(this, panelIndex);
UString path;
if (mainPath.IsEmpty())
{
if (!::ReadPanelPath(panelIndex, path))
path.Empty();
}
else
path = mainPath;
int id = 1000 + 100 * panelIndex;
RINOK(Panels[panelIndex].Create(_window, _window,
id, path, &m_PanelCallbackImp[panelIndex], &AppState, archiveIsOpened, encrypted));
PanelsCreated[panelIndex] = true;
return S_OK;
}
static void CreateToolbar(
HWND parent,
NWindows::NControl::CImageList &imageList,
NWindows::NControl::CToolBar &toolBar,
bool LargeButtons)
{
toolBar.Attach(::CreateWindowEx(0,
TOOLBARCLASSNAME,
NULL, 0
| WS_VISIBLE
| TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
| WS_CHILD
| CCS_NOPARENTALIGN
| CCS_NORESIZE
| CCS_NODIVIDER
// | TBSTYLE_AUTOSIZE
// | CCS_ADJUSTABLE
,0,0,0,0, parent, NULL, g_hInstance, NULL));
// TB_BUTTONSTRUCTSIZE message, which is required for
// backward compatibility.
toolBar.ButtonStructSize();
imageList.Create(
LargeButtons ? 48: 24,
LargeButtons ? 36: 24,
ILC_MASK | ILC_COLOR32, 0, 0);
toolBar.SetImageList(0, imageList);
}
struct CButtonInfo
{
UINT commandID;
UINT BitmapResID;
UINT Bitmap2ResID;
UINT StringResID;
UINT32 LangID;
UString GetText()const { return LangString(StringResID, LangID); };
};
static CButtonInfo g_StandardButtons[] =
{
{ IDM_COPY_TO, IDB_COPY, IDB_COPY2, IDS_BUTTON_COPY, 0x03020420},
{ IDM_MOVE_TO, IDB_MOVE, IDB_MOVE2, IDS_BUTTON_MOVE, 0x03020421},
{ IDM_DELETE, IDB_DELETE, IDB_DELETE2, IDS_BUTTON_DELETE, 0x03020422} ,
{ IDM_FILE_PROPERTIES, IDB_INFO, IDB_INFO2, IDS_BUTTON_INFO, 0x03020423}
};
static CButtonInfo g_ArchiveButtons[] =
{
{ kAddCommand, IDB_ADD, IDB_ADD2, IDS_ADD, 0x03020400},
{ kExtractCommand, IDB_EXTRACT, IDB_EXTRACT2, IDS_EXTRACT, 0x03020401},
{ kTestCommand , IDB_TEST, IDB_TEST2, IDS_TEST, 0x03020402}
};
bool SetButtonText(UINT32 commandID, CButtonInfo *buttons, int numButtons, UString &s)
{
for (int i = 0; i < numButtons; i++)
{
const CButtonInfo &b = buttons[i];
if (b.commandID == commandID)
{
s = b.GetText();
return true;
}
}
return false;
}
void SetButtonText(UINT32 commandID, UString &s)
{
if (SetButtonText(commandID, g_StandardButtons,
sizeof(g_StandardButtons) / sizeof(g_StandardButtons[0]), s))
return;
SetButtonText(commandID, g_ArchiveButtons,
sizeof(g_ArchiveButtons) / sizeof(g_ArchiveButtons[0]), s);
}
static void AddButton(
NControl::CImageList &imageList,
NControl::CToolBar &toolBar,
CButtonInfo &butInfo,
bool showText,
bool large)
{
TBBUTTON but;
but.iBitmap = 0;
but.idCommand = butInfo.commandID;
but.fsState = TBSTATE_ENABLED;
but.fsStyle = BTNS_BUTTON
// | BTNS_AUTOSIZE
;
but.dwData = 0;
UString s = butInfo.GetText();
but.iString = 0;
if (showText)
but.iString = (INT_PTR)(LPCWSTR)s;
but.iBitmap = imageList.GetImageCount();
HBITMAP b = ::LoadBitmap(g_hInstance,
large ?
MAKEINTRESOURCE(butInfo.BitmapResID):
MAKEINTRESOURCE(butInfo.Bitmap2ResID));
if (b != 0)
{
imageList.AddMasked(b, RGB(255, 0, 255));
::DeleteObject(b);
}
#ifdef _UNICODE
toolBar.AddButton(1, &but);
#else
toolBar.AddButtonW(1, &but);
#endif
}
static void AddBand(NControl::CReBar &reBar, NControl::CToolBar &toolBar)
{
SIZE size;
toolBar.GetMaxSize(&size);
RECT rect;
toolBar.GetWindowRect(&rect);
REBARBANDINFO rbBand;
rbBand.cbSize = sizeof(REBARBANDINFO); // Required
rbBand.fMask = RBBIM_STYLE
| RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE;
rbBand.fStyle = RBBS_CHILDEDGE; // RBBS_NOGRIPPER;
rbBand.cxMinChild = size.cx; // rect.right - rect.left;
rbBand.cyMinChild = size.cy; // rect.bottom - rect.top;
rbBand.cyChild = rbBand.cyMinChild;
rbBand.cx = rbBand.cxMinChild;
rbBand.cxIdeal = rbBand.cxMinChild;
rbBand.hwndChild = toolBar;
reBar.InsertBand(-1, &rbBand);
}
void CApp::ReloadToolbars()
{
if (!_rebar)
return;
HWND parent = _rebar;
while (_rebar.GetBandCount() > 0)
_rebar.DeleteBand(0);
_archiveToolBar.Destroy();
_archiveButtonsImageList.Destroy();
_standardButtonsImageList.Destroy();
_standardToolBar.Destroy();
if (ShowArchiveToolbar)
{
CreateToolbar(parent, _archiveButtonsImageList, _archiveToolBar, LargeButtons);
for (int i = 0; i < sizeof(g_ArchiveButtons) / sizeof(g_ArchiveButtons[0]); i++)
AddButton(_archiveButtonsImageList, _archiveToolBar, g_ArchiveButtons[i],
ShowButtonsLables, LargeButtons);
AddBand(_rebar, _archiveToolBar);
}
if (ShowStandardToolbar)
{
CreateToolbar(parent, _standardButtonsImageList, _standardToolBar, LargeButtons);
for (int i = 0; i < sizeof(g_StandardButtons) / sizeof(g_StandardButtons[0]); i++)
AddButton(_standardButtonsImageList, _standardToolBar, g_StandardButtons[i],
ShowButtonsLables, LargeButtons);
AddBand(_rebar, _standardToolBar);
}
}
void CApp::ReloadRebar(HWND hwnd)
{
_rebar.Destroy();
if (!ShowArchiveToolbar && !ShowStandardToolbar)
return;
if (g_ComCtl32Version >= MAKELONG(71, 4))
{
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES;
InitCommonControlsEx(&icex);
_rebar.Attach(::CreateWindowEx(WS_EX_TOOLWINDOW,
REBARCLASSNAME,
NULL,
WS_VISIBLE
| WS_BORDER
| WS_CHILD
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
// | CCS_NODIVIDER
// | CCS_NOPARENTALIGN // it's bead for moveing of two bands
// | CCS_TOP
| RBS_VARHEIGHT
| RBS_BANDBORDERS
// | RBS_AUTOSIZE
,0,0,0,0, hwnd, NULL, g_hInstance, NULL));
}
if (_rebar == 0)
return;
REBARINFO rbi;
rbi.cbSize = sizeof(REBARINFO); // Required when using this struct.
rbi.fMask = 0;
rbi.himl = (HIMAGELIST)NULL;
_rebar.SetBarInfo(&rbi);
ReloadToolbars();
}
HRESULT CApp::Create(HWND hwnd, const UString &mainPath, int xSizes[2], bool &archiveIsOpened, bool &encrypted)
{
ReadToolbar();
ReloadRebar(hwnd);
int i;
for (i = 0; i < kNumPanelsMax; i++)
PanelsCreated[i] = false;
_window.Attach(hwnd);
AppState.Read();
SetListSettings();
SetShowSystemMenu();
if (LastFocusedPanel >= kNumPanelsMax)
LastFocusedPanel = 0;
CListMode listMode;
ReadListMode(listMode);
for (i = 0; i < kNumPanelsMax; i++)
{
CPanel &panel = Panels[i];
panel._ListViewMode = listMode.Panels[i];
panel._xSize = xSizes[i];
panel._flatModeForArc = ReadFlatView(i);
}
for (i = 0; i < kNumPanelsMax; i++)
if (NumPanels > 1 || i == LastFocusedPanel)
{
if (NumPanels == 1)
Panels[i]._xSize = xSizes[0] + xSizes[1];
bool archiveIsOpened2 = false;
bool encrypted2 = false;
bool mainPanel = (i == LastFocusedPanel);
RINOK(CreateOnePanel(i, mainPanel ? mainPath : L"", archiveIsOpened2, encrypted2));
if (mainPanel)
{
archiveIsOpened = archiveIsOpened2;
encrypted = encrypted2;
}
}
SetFocusedPanel(LastFocusedPanel);
Panels[LastFocusedPanel].SetFocusToList();
return S_OK;
}
extern void MoveSubWindows(HWND hWnd);
HRESULT CApp::SwitchOnOffOnePanel()
{
if (NumPanels == 1)
{
NumPanels++;
bool archiveIsOpened, encrypted;
RINOK(CreateOnePanel(1 - LastFocusedPanel, UString(), archiveIsOpened, encrypted));
Panels[1 - LastFocusedPanel].Enable(true);
Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL);
}
else
{
NumPanels--;
Panels[1 - LastFocusedPanel].Enable(false);
Panels[1 - LastFocusedPanel].Show(SW_HIDE);
}
MoveSubWindows(_window);
return S_OK;
}
void CApp::Save()
{
AppState.Save();
CListMode listMode;
for (int i = 0; i < kNumPanelsMax; i++)
{
const CPanel &panel = Panels[i];
UString path;
if (panel._parentFolders.IsEmpty())
path = panel._currentFolderPrefix;
else
path = GetFolderPath(panel._parentFolders[0].ParentFolder);
SavePanelPath(i, path);
listMode.Panels[i] = panel.GetListViewMode();
SaveFlatView(i, panel._flatModeForArc);
}
SaveListMode(listMode);
}
void CApp::Release()
{
// It's for unloading COM dll's: don't change it.
for (int i = 0; i < kNumPanelsMax; i++)
Panels[i].Release();
}
static bool IsThereFolderOfPath(const UString &path)
{
CFileInfoW fi;
if (!FindFile(path, fi))
return false;
return fi.IsDir();
}
// reduces path to part that exists on disk
static void ReducePathToRealFileSystemPath(UString &path)
{
while (!path.IsEmpty())
{
if (IsThereFolderOfPath(path))
{
NName::NormalizeDirPathPrefix(path);
break;
}
int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -