📄 panel.cpp
字号:
// Panel.cpp
#include "StdAfx.h"
#include <Windowsx.h>
#include "Common/Defs.h"
#include "Common/StringConvert.h"
#include "Common/IntToString.h"
#include "Windows/Error.h"
#include "Windows/PropVariant.h"
#include "Windows/Thread.h"
#include "../../PropID.h"
#include "Panel.h"
#include "RootFolder.h"
#include "FSFolder.h"
#include "FormatUtils.h"
#include "App.h"
#include "ExtractCallback.h"
#include "resource.h"
#include "..\GUI\ExtractRes.h"
#include "../Agent/IFolderArchive.h"
#include "../Common/CompressCall.h"
#include "../Common/ArchiveName.h"
using namespace NWindows;
using namespace NControl;
#ifndef _UNICODE
extern bool g_IsNT;
#endif
static const UINT_PTR kTimerID = 1;
static const UINT kTimerElapse = 1000;
static DWORD kStyles[4] = { LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT };
// static const int kCreateFolderID = 101;
// static const UINT kFileChangeNotifyMessage = WM_APP;
extern HINSTANCE g_hInstance;
extern DWORD g_ComCtl32Version;
void CPanel::Release()
{
// It's for unloading COM dll's: don't change it.
CloseOpenFolders();
_sevenZipContextMenu.Release();
_systemContextMenu.Release();
}
CPanel::~CPanel()
{
CloseOpenFolders();
}
HWND CPanel::GetParent()
{
HWND h = CWindow2::GetParent();
return (h == 0) ? _mainWindow : h;
}
static LPCWSTR kClassName = L"7-Zip::Panel";
HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
const UString ¤tFolderPrefix, CPanelCallback *panelCallback, CAppState *appState,
bool &archiveIsOpened, bool &encrypted)
{
_mainWindow = mainWindow;
_processTimer = true;
_processNotify = true;
_panelCallback = panelCallback;
_appState = appState;
// _index = index;
_baseID = id;
_comboBoxID = _baseID + 3;
_statusBarID = _comboBoxID + 1;
UString cfp = currentFolderPrefix;
if (!currentFolderPrefix.IsEmpty())
if (currentFolderPrefix[0] == L'.')
if (!NFile::NDirectory::MyGetFullPathName(currentFolderPrefix, cfp))
cfp = currentFolderPrefix;
RINOK(BindToPath(cfp, archiveIsOpened, encrypted));
if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE,
0, 0, _xSize, 260,
parentWindow, (HMENU)(UINT_PTR)id, g_hInstance))
return E_FAIL;
return S_OK;
}
LRESULT CPanel::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case kShiftSelectMessage:
OnShiftSelectMessage();
return 0;
case kReLoadMessage:
RefreshListCtrl(_selectedState);
return 0;
case kSetFocusToListView:
_listView.SetFocus();
return 0;
case kOpenItemChanged:
return OnOpenItemChanged(lParam);
case kRefreshStatusBar:
OnRefreshStatusBar();
return 0;
case WM_TIMER:
OnTimer();
return 0;
case WM_CONTEXTMENU:
if (OnContextMenu(HANDLE(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)))
return 0;
break;
/*
case WM_DROPFILES:
CompressDropFiles(HDROP(wParam));
return 0;
*/
}
return CWindow2::OnMessage(message, wParam, lParam);
}
static LRESULT APIENTRY ListViewSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
CWindow tempDialog(hwnd);
CMyListView *w = (CMyListView *)(tempDialog.GetUserDataLongPtr());
if (w == NULL)
return 0;
return w->OnMessage(message, wParam, lParam);
}
LRESULT CMyListView::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_CHAR)
{
UINT scanCode = (UINT)((lParam >> 16) & 0xFF);
bool extended = ((lParam & 0x1000000) != 0);
UINT virtualKey = MapVirtualKey(scanCode, 1);
if (virtualKey == VK_MULTIPLY || virtualKey == VK_ADD ||
virtualKey == VK_SUBTRACT)
return 0;
if ((wParam == '/' && extended)
|| wParam == '\\' || wParam == '/')
{
_panel->OpenDrivesFolder();
return 0;
}
}
else if (message == WM_SYSCHAR)
{
// For Alt+Enter Beep disabling
UINT scanCode = (UINT)(lParam >> 16) & 0xFF;
UINT virtualKey = MapVirtualKey(scanCode, 1);
if (virtualKey == VK_RETURN || virtualKey == VK_MULTIPLY ||
virtualKey == VK_ADD || virtualKey == VK_SUBTRACT)
return 0;
}
/*
else if (message == WM_SYSKEYDOWN)
{
// return 0;
}
*/
else if (message == WM_KEYDOWN)
{
bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
// bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0;
// bool RightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0;
bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
switch(wParam)
{
case VK_RETURN:
{
if (shift && !alt && !ctrl)
{
_panel->OpenSelectedItems(false);
return 0;
}
break;
}
case VK_NEXT:
{
if (ctrl && !alt && !shift)
{
_panel->OpenFocusedItemAsInternal();
return 0;
}
break;
}
case VK_PRIOR:
if (ctrl && !alt && !shift)
{
_panel->OpenParentFolder();
return 0;
}
}
}
else if (message == WM_SETFOCUS)
{
_panel->_lastFocusedIsList = true;
_panel->_panelCallback->PanelWasFocused();
}
#ifndef _UNICODE
if (g_IsNT)
return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam);
else
#endif
return CallWindowProc(_origWindowProc, *this, message, wParam, lParam);
}
/*
static LRESULT APIENTRY ComboBoxSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
CWindow tempDialog(hwnd);
CMyComboBox *w = (CMyComboBox *)(tempDialog.GetUserDataLongPtr());
if (w == NULL)
return 0;
return w->OnMessage(message, wParam, lParam);
}
LRESULT CMyComboBox::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
return CallWindowProc(_origWindowProc, *this, message, wParam, lParam);
}
*/
static LRESULT APIENTRY ComboBoxEditSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
CWindow tempDialog(hwnd);
CMyComboBoxEdit *w = (CMyComboBoxEdit *)(tempDialog.GetUserDataLongPtr());
if (w == NULL)
return 0;
return w->OnMessage(message, wParam, lParam);
}
LRESULT CMyComboBoxEdit::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
// See MSDN / Subclassing a Combo Box / Creating a Combo-box Toolbar
switch (message)
{
case WM_SYSKEYDOWN:
switch (wParam)
{
case VK_F1:
case VK_F2:
{
// check ALT
if ((lParam & (1<<29)) == 0)
break;
bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
if (alt && !ctrl && !shift)
{
_panel->_panelCallback->SetFocusToPath(wParam == VK_F1 ? 0 : 1);
return 0;
}
break;
}
}
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_TAB:
// SendMessage(hwndMain, WM_ENTER, 0, 0);
_panel->SetFocusToList();
return 0;
case VK_F9:
{
bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
if (!alt && !ctrl && !shift)
{
g_App.SwitchOnOffOnePanel();;
return 0;
}
break;
}
}
break;
case WM_CHAR:
switch (wParam)
{
case VK_TAB:
case VK_ESCAPE:
return 0;
}
}
#ifndef _UNICODE
if (g_IsNT)
return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam);
else
#endif
return CallWindowProc(_origWindowProc, *this, message, wParam, lParam);
}
static HIMAGELIST GetSysImageList(bool smallIcons)
{
SHFILEINFO shellInfo;
return (HIMAGELIST)SHGetFileInfo(TEXT(""),
FILE_ATTRIBUTE_NORMAL |FILE_ATTRIBUTE_DIRECTORY,
&shellInfo, sizeof(shellInfo),
SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | (smallIcons ? SHGFI_SMALLICON : SHGFI_ICON));
}
bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */)
{
// _virtualMode = false;
// _sortIndex = 0;
_sortID = kpidName;
_ascending = true;
_lastFocusedIsList = true;
DWORD style = WS_CHILD | WS_VISIBLE; // | WS_BORDER ; // | LVS_SHAREIMAGELISTS; // | LVS_SHOWSELALWAYS;;
style |= LVS_SHAREIMAGELISTS;
// style |= LVS_AUTOARRANGE;
style |= WS_CLIPCHILDREN;
style |= WS_CLIPSIBLINGS;
const UInt32 kNumListModes = sizeof(kStyles) / sizeof(kStyles[0]);
if (_ListViewMode >= kNumListModes)
_ListViewMode = kNumListModes - 1;
style |= kStyles[_ListViewMode]
| WS_TABSTOP
| LVS_EDITLABELS;
if (_mySelectMode)
style |= LVS_SINGLESEL;
/*
if (_virtualMode)
style |= LVS_OWNERDATA;
*/
DWORD exStyle;
exStyle = WS_EX_CLIENTEDGE;
if (!_listView.CreateEx(exStyle, style, 0, 0, 116, 260,
HWND(*this), (HMENU)(UINT_PTR)(_baseID + 1), g_hInstance, NULL))
return false;
_listView.SetUnicodeFormat(true);
_listView.SetUserDataLongPtr(LONG_PTR(&_listView));
_listView._panel = this;
#ifndef _UNICODE
if(g_IsNT)
_listView._origWindowProc =
(WNDPROC)_listView.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ListViewSubclassProc));
else
#endif
_listView._origWindowProc =
(WNDPROC)_listView.SetLongPtr(GWLP_WNDPROC, LONG_PTR(ListViewSubclassProc));
_listView.SetImageList(GetSysImageList(true), LVSIL_SMALL);
_listView.SetImageList(GetSysImageList(false), LVSIL_NORMAL);
// _exStyle |= LVS_EX_HEADERDRAGDROP;
// DWORD extendedStyle = _listView.GetExtendedListViewStyle();
// extendedStyle |= _exStyle;
// _listView.SetExtendedListViewStyle(extendedStyle);
SetExtendedStyle();
_listView.Show(SW_SHOW);
_listView.InvalidateRect(NULL, true);
_listView.Update();
// Ensure that the common control DLL is loaded.
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_BAR_CLASSES;
InitCommonControlsEx(&icex);
TBBUTTON tbb [ ] =
{
// {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0},
{VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0},
// {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0},
// {VIEW_NEWFOLDER, kCreateFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0},
};
if (g_ComCtl32Version >= MAKELONG(71, 4))
{
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES;
InitCommonControlsEx(&icex);
_headerReBar.Attach(::CreateWindowEx(WS_EX_TOOLWINDOW,
REBARCLASSNAME,
NULL, WS_VISIBLE | WS_BORDER | WS_CHILD |
WS_CLIPCHILDREN | WS_CLIPSIBLINGS
| CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_TOP
| RBS_VARHEIGHT
| RBS_BANDBORDERS
,0,0,0,0, HWND(*this), NULL, g_hInstance, NULL));
}
DWORD toolbarStyle = WS_CHILD | WS_VISIBLE ;
if (_headerReBar)
{
toolbarStyle |= 0
// | WS_CLIPCHILDREN
// | WS_CLIPSIBLINGS
| TBSTYLE_TOOLTIPS
| CCS_NODIVIDER
| CCS_NORESIZE
| TBSTYLE_FLAT
;
}
_headerToolBar.Attach(::CreateToolbarEx ((*this), toolbarStyle,
_baseID + 2, 11,
(HINSTANCE)HINST_COMMCTRL,
IDB_VIEW_SMALL_COLOR,
(LPCTBBUTTON)&tbb, sizeof(tbb) / sizeof(tbb[0]),
0, 0, 0, 0, sizeof (TBBUTTON)));
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_USEREX_CLASSES;
InitCommonControlsEx(&icex);
_headerComboBox.CreateEx(0, WC_COMBOBOXEXW, NULL,
WS_BORDER | WS_VISIBLE |WS_CHILD | CBS_DROPDOWN | CBS_AUTOHSCROLL,
0, 0, 100, 520,
((_headerReBar == 0) ? HWND(*this) : _headerToolBar),
(HMENU)(UINT_PTR)(_comboBoxID),
g_hInstance, NULL);
_headerComboBox.SendMessage(CBEM_SETUNICODEFORMAT, (WPARAM)(BOOL)TRUE, 0);
_headerComboBox.SetImageList(GetSysImageList(true));
_headerComboBox.SetExtendedStyle(CBES_EX_PATHWORDBREAKPROC, CBES_EX_PATHWORDBREAKPROC);
/*
_headerComboBox.SetUserDataLongPtr(LONG_PTR(&_headerComboBox));
_headerComboBox._panel = this;
_headerComboBox._origWindowProc =
(WNDPROC)_headerComboBox.SetLongPtr(GWLP_WNDPROC,
LONG_PTR(ComboBoxSubclassProc));
*/
_comboBoxEdit.Attach(_headerComboBox.GetEditControl());
// _comboBoxEdit.SendMessage(CCM_SETUNICODEFORMAT, (WPARAM)(BOOL)TRUE, 0);
_comboBoxEdit.SetUserDataLongPtr(LONG_PTR(&_comboBoxEdit));
_comboBoxEdit._panel = this;
#ifndef _UNICODE
if(g_IsNT)
_comboBoxEdit._origWindowProc =
(WNDPROC)_comboBoxEdit.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc));
else
#endif
_comboBoxEdit._origWindowProc =
(WNDPROC)_comboBoxEdit.SetLongPtr(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc));
if (_headerReBar)
{
REBARINFO rbi;
rbi.cbSize = sizeof(REBARINFO); // Required when using this struct.
rbi.fMask = 0;
rbi.himl = (HIMAGELIST)NULL;
_headerReBar.SetBarInfo(&rbi);
// Send the TB_BUTTONSTRUCTSIZE message, which is required for
// backward compatibility.
// _headerToolBar.SendMessage(TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
SIZE size;
_headerToolBar.GetMaxSize(&size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -