Improve: Showing file transmit progress dialog

This commit is contained in:
yuanyuanxiang
2026-01-06 16:22:54 +01:00
parent 49373a1137
commit e0239dce8d
7 changed files with 197 additions and 14 deletions

Binary file not shown.

View File

@@ -46,6 +46,7 @@
#include "common/file_upload.h"
#include "SplashDlg.h"
#include <ServerServiceWrapper.h>
#include "CDlgFileSend.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@@ -2313,18 +2314,21 @@ bool SendData(void* user, FileChunkPacket* chunk, BYTE* data, int size)
if (!ctx->Send2Client(data, size)) {
return false;
}
return true;
}
CDlgFileSend* dlg = (CDlgFileSend*)ctx->hDlg;
BYTE* name = data + sizeof(FileChunkPacket);
dlg->UpdateProgress(CString((char*)name, chunk->nameLength), chunk);
void RecvData(void* ptr)
{
FileChunkPacket* pkt = (FileChunkPacket*)ptr;
return true;
}
void delay_cancel(CONTEXT_OBJECT* ctx, int sec)
{
if (!ctx) return;
CDlgFileSend* dlg = (CDlgFileSend*)ctx->hDlg;
dlg->FinishFileSend(TRUE);
Sleep(sec*1000);
dlg->PostMessageA(WM_CLOSE);
ctx->hDlg = NULL;
ctx->CancelIO();
}
@@ -2432,6 +2436,10 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
}
auto files = *ptr ? ParseMultiStringPath(ptr, len - 2 - dir.length()) : std::vector<std::string>{};
if (!files.empty()) {
CDlgFileSend* dlg = new CDlgFileSend(this, ContextObject->GetServer(), ContextObject, TRUE);
dlg->Create(IDD_DIALOG_FILESEND, GetDesktopWindow());
dlg->ShowWindow(SW_HIDE);
ContextObject->hDlg = dlg;
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
std::thread(FileBatchTransferWorker, files, dir, ContextObject, SendData, FinishSend,
hash, hmac).detach();
@@ -2442,13 +2450,15 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
}
case COMMAND_SEND_FILE: {
// 接收文件
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
CONNECT_ADDRESS addr;
memcpy(addr.pwdHash, hash.c_str(), min(hash.length(), sizeof(addr.pwdHash)));
int n = RecvFileChunk((char*)szBuffer, len, &addr, RecvData, hash, hmac);
if (n) {
Mprintf("RecvFileChunk failed: %d. hash: %s, hmac: %s\n", n, hash.c_str(), hmac.c_str());
if (ContextObject->hDlg == NULL) {
CDlgFileSend* dlg = new CDlgFileSend(this, ContextObject->GetServer(), ContextObject, FALSE);
dlg->Create(IDD_DIALOG_FILESEND, GetDesktopWindow());
dlg->ShowWindow(SW_HIDE);
ContextObject->hDlg = dlg;
}
DialogBase* dlg = (DialogBase*)ContextObject->hDlg;
dlg->OnReceiveComplete();
break;
}
case TOKEN_GETVERSION: { // 获取版本【L】

View File

@@ -275,6 +275,7 @@
<ClInclude Include="Bmp2Video.h" />
<ClInclude Include="Buffer.h" />
<ClInclude Include="BuildDlg.h" />
<ClInclude Include="CDlgFileSend.h" />
<ClInclude Include="CDrawingBoard.h" />
<ClInclude Include="CGridDialog.h" />
<ClInclude Include="Chat.h" />
@@ -353,6 +354,7 @@
<ClCompile Include="Bmp2Video.cpp" />
<ClCompile Include="Buffer.cpp" />
<ClCompile Include="BuildDlg.cpp" />
<ClCompile Include="CDlgFileSend.cpp" />
<ClCompile Include="CDrawingBoard.cpp" />
<ClCompile Include="CGridDialog.cpp" />
<ClCompile Include="Chat.cpp" />

View File

@@ -61,6 +61,7 @@
<ClCompile Include="ServerSessionMonitor.cpp" />
<ClCompile Include="SplashDlg.cpp" />
<ClCompile Include="ToolbarDlg.cpp" />
<ClCompile Include="CDlgFileSend.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\client\Audio.h" />
@@ -135,6 +136,7 @@
<ClInclude Include="ServerSessionMonitor.h" />
<ClInclude Include="SplashDlg.h" />
<ClInclude Include="ToolbarDlg.h" />
<ClInclude Include="CDlgFileSend.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="2015Remote.rc" />

View File

@@ -0,0 +1,124 @@
// CDlgFileSend.cpp: 实现文件
//
#include "stdafx.h"
#include "CDlgFileSend.h"
// CDlgFileSend 对话框
IMPLEMENT_DYNAMIC(CDlgFileSend, CDialog)
CDlgFileSend::CDlgFileSend(CWnd* pParent, Server* IOCPServer, CONTEXT_OBJECT* ContextObject, BOOL sendFile)
: DialogBase(CDlgFileSend::IDD, pParent, IOCPServer, ContextObject, IDI_File), m_bIsSending(sendFile)
{
}
CDlgFileSend::~CDlgFileSend()
{
}
void CDlgFileSend::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PROGRESS_FILESEND, m_Progress);
}
BEGIN_MESSAGE_MAP(CDlgFileSend, CDialog)
ON_WM_CLOSE()
ON_MESSAGE(WM_UPDATEFILEPROGRESS, &CDlgFileSend::OnUpdateFileProgress)
ON_MESSAGE(WM_FINISHFILESEND, &CDlgFileSend::OnFinishFileSend)
END_MESSAGE_MAP()
// CDlgFileSend 消息处理程序
std::string GetPwdHash();
std::string GetHMAC(int offset);
void RecvData(void* ptr)
{
FileChunkPacket* pkt = (FileChunkPacket*)ptr;
}
void CDlgFileSend::OnReceiveComplete(void) {
LPBYTE szBuffer = m_ContextObject->InDeCompressedBuffer.GetBuffer();
unsigned len = m_ContextObject->InDeCompressedBuffer.GetBufferLen();
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
CONNECT_ADDRESS addr = { 0 };
memcpy(addr.pwdHash, hash.c_str(), min(hash.length(), sizeof(addr.pwdHash)));
int n = RecvFileChunk((char*)szBuffer, len, &addr, RecvData, hash, hmac);
if (n) {
Mprintf("RecvFileChunk failed: %d. hash: %s, hmac: %s\n", n, hash.c_str(), hmac.c_str());
}
BYTE* name = szBuffer + sizeof(FileChunkPacket);
FileChunkPacket* chunk = (FileChunkPacket*)szBuffer;
UpdateProgress(CString((char*)name, chunk->nameLength), chunk);
}
void CDlgFileSend::UpdateProgress(CString file, const FileChunkPacket *chunk) {
PostMessageA(WM_UPDATEFILEPROGRESS, (WPARAM)new CString(file), (LPARAM)new FileChunkPacket(*chunk));
}
void CDlgFileSend::FinishFileSend(BOOL succeed) {
PostMessageA(WM_FINISHFILESEND, NULL, (LPARAM)succeed);
}
LRESULT CDlgFileSend::OnUpdateFileProgress(WPARAM wParam, LPARAM lParam) {
CString* pFile = (CString*)wParam;
FileChunkPacket* pChunk = (FileChunkPacket*)lParam;
CString status;
double percent = pChunk->fileSize > 0 ? double(pChunk->offset) / pChunk->fileSize * 100.0 : 100.0;
m_bIsSending ?
status.Format("发送文件(%d/%d): %.2f%%", 1 + pChunk->fileIndex, pChunk->totalNum, percent):
status.Format("接收文件(%d/%d): %.2f%%", 1 + pChunk->fileIndex, pChunk->totalNum, percent);
SetDlgItemTextA(IDC_STATIC_CURRENTINDEX, status);
SetDlgItemTextA(IDC_STATIC_CURRENT_FILE, *pFile);
m_Progress.SetPos(percent);
ShowWindow(SW_SHOW);
delete pChunk;
delete pFile;
return 0;
}
LRESULT CDlgFileSend::OnFinishFileSend(WPARAM wParam, LPARAM lParam) {
BOOL success = (BOOL)lParam;
m_bIsSending ?
SetDlgItemTextA(IDC_STATIC_CURRENTINDEX, success ? "文件发送完成" : "文件发送失败"):
SetDlgItemTextA(IDC_STATIC_CURRENTINDEX, success ? "文件接收完成" : "文件接收失败");
if (success)
m_Progress.SetPos(100);
ShowWindow(SW_SHOW);
return 0;
}
BOOL CDlgFileSend::OnInitDialog()
{
DialogBase::OnInitDialog();
SetIcon(m_hIcon, FALSE);
SetWindowTextA(m_bIsSending ? "发送文件" : "接收文件");
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
pSysMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
}
return TRUE;
}
void CDlgFileSend::OnClose()
{
CancelIO();
// 等待数据处理完毕
if (IsProcessing()) {
ShowWindow(SW_HIDE);
return;
}
DialogBase::OnClose();
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include "IOCPServer.h"
#include "afxdialogex.h"
#include <resource.h>
#include"file_upload.h"
#define WM_UPDATEFILEPROGRESS (WM_USER + 0x100)
#define WM_FINISHFILESEND (WM_USER + 0x101)
// CDlgFileSend 对话框
class CDlgFileSend : public DialogBase
{
DECLARE_DYNAMIC(CDlgFileSend)
public:
CDlgFileSend(CWnd* pParent = NULL, Server* IOCPServer = NULL,
CONTEXT_OBJECT* ContextObject = NULL, BOOL sendFile = TRUE);
virtual ~CDlgFileSend();
void OnReceiveComplete(void);
void UpdateProgress(CString file, const FileChunkPacket *chunk);
void FinishFileSend(BOOL succeed);
BOOL m_bIsSending;
enum { IDD = IDD_DIALOG_FILESEND };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
afx_msg LRESULT OnUpdateFileProgress(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnFinishFileSend(WPARAM wParam, LPARAM lParam);
public:
CProgressCtrl m_Progress;
virtual BOOL OnInitDialog();
afx_msg void OnClose();
};

View File

@@ -194,6 +194,7 @@
#define IDB_BITMAP_INJECT 316
#define IDB_BITMAP_PORTPROXY 317
#define IDD_TOOLBAR_DLG 318
#define IDD_DIALOG_FILESEND 320
#define IDC_MESSAGE 1000
#define IDC_ONLINE 1001
#define IDC_STATIC_TIPS 1002
@@ -425,6 +426,10 @@
#define IDC_COMBO_PAYLOAD 2210
#define IDC_STATIC_PAYLOAD 2211
#define IDC_SLIDER_CLIENT_SIZE 2212
#define IDC_STATIC_CURRENT_FILE 2213
#define IDC_PROGRESS_FILESEND 2214
#define IDC_STATIC_CURRENTINDEX 2215
#define IDC_STATIC_CURRENTPERCENT 2216
#define ID_ONLINE_UPDATE 32772
#define ID_ONLINE_MESSAGE 32773
#define ID_ONLINE_DELETE 32775
@@ -607,9 +612,9 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 320
#define _APS_NEXT_RESOURCE_VALUE 322
#define _APS_NEXT_COMMAND_VALUE 32993
#define _APS_NEXT_CONTROL_VALUE 2213
#define _APS_NEXT_SYMED_VALUE 101
#define _APS_NEXT_CONTROL_VALUE 2216
#define _APS_NEXT_SYMED_VALUE 105
#endif
#endif