Improve: GetForegroundSelectedFiles if GetClipboardFiles failed

This commit is contained in:
yuanyuanxiang
2026-01-10 23:45:00 +01:00
parent c75b45507c
commit 7c6ee74574
14 changed files with 279 additions and 70 deletions

View File

@@ -167,6 +167,7 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\common\file_upload.cpp" />
<ClCompile Include="..\common\ikcp.c" /> <ClCompile Include="..\common\ikcp.c" />
<ClCompile Include="..\common\zstd_wrapper.c" /> <ClCompile Include="..\common\zstd_wrapper.c" />
<ClCompile Include="..\server\2015Remote\pwd_gen.cpp" /> <ClCompile Include="..\server\2015Remote\pwd_gen.cpp" />

View File

@@ -5,6 +5,7 @@
#include "FileManager.h" #include "FileManager.h"
#include <shellapi.h> #include <shellapi.h>
#include "ZstdArchive.h" #include "ZstdArchive.h"
#include "file_upload.h"
typedef struct { typedef struct {
DWORD dwSizeHigh; DWORD dwSizeHigh;
@@ -27,23 +28,6 @@ CFileManager::~CFileManager()
m_UploadList.clear(); m_UploadList.clear();
} }
std::vector<std::string> ParseMultiStringPath(const char* buffer, size_t size)
{
std::vector<std::string> paths;
const char* p = buffer;
const char* end = buffer + size;
while (p < end) {
size_t len = strlen(p);
if (len > 0) {
paths.emplace_back(p, len);
}
p += len + 1;
}
return paths;
}
std::string GetExtractDir(const std::string& archivePath) std::string GetExtractDir(const std::string& archivePath)
{ {

View File

@@ -569,11 +569,29 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
memcpy(h, szBuffer + 1, ulLength - 1); memcpy(h, szBuffer + 1, ulLength - 1);
m_hash = std::string(h, h + 64); m_hash = std::string(h, h + 64);
m_hmac = std::string(h + 64, h + 80); m_hmac = std::string(h + 64, h + 80);
BYTE szBuffer[1] = { COMMAND_GET_FOLDER }; auto str = BuildMultiStringPath(files);
SendData(szBuffer, sizeof(szBuffer)); BYTE* szBuffer = new BYTE[1 + str.size()];
szBuffer[0] = { COMMAND_GET_FOLDER };
memcpy(szBuffer + 1, str.data(), str.size());
SendData(szBuffer, 1 + str.size());
SAFE_DELETE_ARRAY(szBuffer);
break; break;
} }
SendClientClipboard(ulLength > 1); if (SendClientClipboard(ulLength > 1))
break;
files = GetForegroundSelectedFiles();
if (!files.empty()) {
char h[100] = {};
memcpy(h, szBuffer + 1, ulLength - 1);
m_hash = std::string(h, h + 64);
m_hmac = std::string(h + 64, h + 80);
auto str = BuildMultiStringPath(files);
BYTE* szBuffer = new BYTE[1 + str.size()];
szBuffer[0] = { COMMAND_GET_FOLDER };
memcpy(szBuffer + 1, str.data(), str.size());
SendData(szBuffer, 1 + str.size());
SAFE_DELETE_ARRAY(szBuffer);
}
break; break;
} }
case COMMAND_SCREEN_SET_CLIPBOARD: { case COMMAND_SCREEN_SET_CLIPBOARD: {
@@ -599,9 +617,13 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
} }
case COMMAND_GET_FILE: { case COMMAND_GET_FILE: {
// 发送文件 // 发送文件
int result = 0;
auto files = GetClipboardFiles(result);
std::string dir = (char*)(szBuffer + 1); std::string dir = (char*)(szBuffer + 1);
char* ptr = (char*)szBuffer + 1 + dir.length() + 1;
auto files = *ptr ? ParseMultiStringPath(ptr, ulLength - 2 - dir.length()) : std::vector<std::string>{};
if (files.empty()) {
BOOL result = 0;
files = GetClipboardFiles(result);
}
if (!files.empty() && !dir.empty()) { if (!files.empty() && !dir.empty()) {
IOCPClient* pClient = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn->GetHeaderEncType()); IOCPClient* pClient = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn->GetHeaderEncType());
if (pClient->ConnectServer(m_ClientObject->ServerIP().c_str(), m_ClientObject->ServerPort())) { if (pClient->ConnectServer(m_ClientObject->ServerIP().c_str(), m_ClientObject->ServerPort())) {
@@ -648,22 +670,22 @@ VOID CScreenManager::UpdateClientClipboard(char *szBuffer, ULONG ulLength)
CloseClipboard(); CloseClipboard();
} }
VOID CScreenManager::SendClientClipboard(BOOL fast) BOOL CScreenManager::SendClientClipboard(BOOL fast)
{ {
if (!::OpenClipboard(NULL)) if (!::OpenClipboard(NULL))
return; return FALSE;
// 改为获取 Unicode 格式 // 改为获取 Unicode 格式
HGLOBAL hGlobal = GetClipboardData(CF_UNICODETEXT); HGLOBAL hGlobal = GetClipboardData(CF_UNICODETEXT);
if (hGlobal == NULL) { if (hGlobal == NULL) {
::CloseClipboard(); ::CloseClipboard();
return; return FALSE;
} }
wchar_t* pWideStr = (wchar_t*)GlobalLock(hGlobal); wchar_t* pWideStr = (wchar_t*)GlobalLock(hGlobal);
if (pWideStr == NULL) { if (pWideStr == NULL) {
::CloseClipboard(); ::CloseClipboard();
return; return FALSE;
} }
// Unicode 转 UTF-8 // Unicode 转 UTF-8
@@ -671,14 +693,14 @@ VOID CScreenManager::SendClientClipboard(BOOL fast)
if (utf8Len <= 0) { if (utf8Len <= 0) {
GlobalUnlock(hGlobal); GlobalUnlock(hGlobal);
::CloseClipboard(); ::CloseClipboard();
return; return TRUE;
} }
if (fast && utf8Len > 200 * 1024) { if (fast && utf8Len > 200 * 1024) {
Mprintf("剪切板文本太长, 无法快速拷贝: %d\n", utf8Len); Mprintf("剪切板文本太长, 无法快速拷贝: %d\n", utf8Len);
GlobalUnlock(hGlobal); GlobalUnlock(hGlobal);
::CloseClipboard(); ::CloseClipboard();
return; return TRUE;
} }
LPBYTE szBuffer = new BYTE[utf8Len + 1]; LPBYTE szBuffer = new BYTE[utf8Len + 1];
@@ -690,6 +712,7 @@ VOID CScreenManager::SendClientClipboard(BOOL fast)
m_ClientObject->Send2Server((char*)szBuffer, utf8Len + 1); m_ClientObject->Send2Server((char*)szBuffer, utf8Len + 1);
delete[] szBuffer; delete[] szBuffer;
return TRUE;
} }

View File

@@ -48,7 +48,7 @@ public:
std::string m_DesktopID; std::string m_DesktopID;
BOOL m_bIsWorking; BOOL m_bIsWorking;
BOOL m_bIsBlockInput; BOOL m_bIsBlockInput;
VOID SendClientClipboard(BOOL fast); BOOL SendClientClipboard(BOOL fast);
VOID UpdateClientClipboard(char *szBuffer, ULONG ulLength); VOID UpdateClientClipboard(char *szBuffer, ULONG ulLength);
std::string m_hash; std::string m_hash;

View File

@@ -177,6 +177,7 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\common\file_upload.cpp" />
<ClCompile Include="..\common\ikcp.c" /> <ClCompile Include="..\common\ikcp.c" />
<ClCompile Include="..\common\zstd_wrapper.c" /> <ClCompile Include="..\common\zstd_wrapper.c" />
<ClCompile Include="..\server\2015Remote\pwd_gen.cpp" /> <ClCompile Include="..\server\2015Remote\pwd_gen.cpp" />

206
common/file_upload.cpp Normal file
View File

@@ -0,0 +1,206 @@
#include "file_upload.h"
#include <Windows.h>
#include <ShlObj.h>
#include <ExDisp.h>
#include <ShlGuid.h>
#include <atlbase.h>
#include <atlcom.h>
#include <string>
#include <vector>
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")
static std::vector<std::string> GetDesktopSelectedFiles()
{
CComPtr<IShellWindows> pShellWindows;
if (FAILED(pShellWindows.CoCreateInstance(CLSID_ShellWindows)))
return {};
CComVariant vLoc(CSIDL_DESKTOP);
CComVariant vEmpty;
long lhwnd;
CComPtr<IDispatch> pDisp;
if (FAILED(pShellWindows->FindWindowSW(&vLoc, &vEmpty, SWC_DESKTOP, &lhwnd, SWFO_NEEDDISPATCH, &pDisp)))
return {};
CComQIPtr<IServiceProvider> pServiceProvider(pDisp);
if (!pServiceProvider)
return {};
CComPtr<IShellBrowser> pShellBrowser;
if (FAILED(pServiceProvider->QueryService(SID_STopLevelBrowser, IID_IShellBrowser, (void**)&pShellBrowser)))
return {};
CComPtr<IShellView> pShellView;
if (FAILED(pShellBrowser->QueryActiveShellView(&pShellView)))
return {};
CComPtr<IDataObject> pDataObject;
if (FAILED(pShellView->GetItemObject(SVGIO_SELECTION, IID_IDataObject, (void**)&pDataObject)))
return {};
FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = {};
if (FAILED(pDataObject->GetData(&fmt, &stg)))
return {};
std::vector<std::string> vecFiles;
HDROP hDrop = (HDROP)GlobalLock(stg.hGlobal);
if (hDrop)
{
UINT nFiles = DragQueryFileA(hDrop, 0xFFFFFFFF, NULL, 0);
for (UINT i = 0; i < nFiles; i++)
{
char szPath[MAX_PATH];
if (DragQueryFileA(hDrop, i, szPath, MAX_PATH))
{
vecFiles.push_back(szPath);
}
}
GlobalUnlock(stg.hGlobal);
}
ReleaseStgMedium(&stg);
return vecFiles;
}
std::vector<std::string> GetForegroundSelectedFiles()
{
HRESULT hrInit = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
bool bNeedUninit = SUCCEEDED(hrInit);
HWND hFore = GetForegroundWindow();
// 检查是否是桌面
HWND hDesktop = FindWindow("Progman", NULL);
HWND hWorkerW = NULL;
EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
if (FindWindowEx(hwnd, NULL, "SHELLDLL_DefView", NULL))
{
*(HWND*)lParam = hwnd;
return FALSE;
}
return TRUE;
}, (LPARAM)&hWorkerW);
if (hFore == hDesktop || hFore == hWorkerW) {
if (bNeedUninit) CoUninitialize();
return GetDesktopSelectedFiles();
}
// 检查是否是资源管理器窗口
char szClass[256] = {};
GetClassNameA(hFore, szClass, 256);
if (strcmp(szClass, "CabinetWClass") != 0 && strcmp(szClass, "ExploreWClass") != 0) {
if (bNeedUninit) CoUninitialize();
return {};
}
// 获取该窗口的选中项
CComPtr<IShellWindows> pShellWindows;
if (FAILED(pShellWindows.CoCreateInstance(CLSID_ShellWindows))) {
if (bNeedUninit) CoUninitialize();
return {};
}
std::vector<std::string> vecFiles;
long nCount = 0;
pShellWindows->get_Count(&nCount);
for (long i = 0; i < nCount; i++)
{
CComVariant vIndex(i);
CComPtr<IDispatch> pDisp;
if (FAILED(pShellWindows->Item(vIndex, &pDisp)) || !pDisp)
continue;
CComQIPtr<IWebBrowserApp> pBrowser(pDisp);
if (!pBrowser)
continue;
SHANDLE_PTR hWnd = 0;
pBrowser->get_HWND(&hWnd);
if ((HWND)hWnd != hFore)
continue;
CComPtr<IDispatch> pDoc;
if (FAILED(pBrowser->get_Document(&pDoc)) || !pDoc)
break;
CComQIPtr<IShellFolderViewDual> pView(pDoc);
if (!pView)
break;
CComPtr<FolderItems> pItems;
if (FAILED(pView->SelectedItems(&pItems)) || !pItems)
break;
long nItems = 0;
pItems->get_Count(&nItems);
for (long j = 0; j < nItems; j++)
{
CComVariant vj(j);
CComPtr<FolderItem> pItem;
if (SUCCEEDED(pItems->Item(vj, &pItem)) && pItem)
{
CComBSTR bstrPath;
if (SUCCEEDED(pItem->get_Path(&bstrPath)))
{
// BSTR (宽字符) 转 多字节
int nLen = WideCharToMultiByte(CP_ACP, 0, bstrPath, -1, NULL, 0, NULL, NULL);
if (nLen > 0)
{
std::string strPath(nLen - 1, '\0');
WideCharToMultiByte(CP_ACP, 0, bstrPath, -1, &strPath[0], nLen, NULL, NULL);
vecFiles.push_back(strPath);
}
}
}
}
break;
}
if (bNeedUninit) CoUninitialize();
return vecFiles;
}
// 将多个路径组合成单\0分隔的char数组
// 格式: "path1\0path2\0path3\0"
std::vector<char> BuildMultiStringPath(const std::vector<std::string>& paths)
{
std::vector<char> result;
for (const auto& path : paths) {
result.insert(result.end(), path.begin(), path.end());
result.push_back('\0');
}
return result;
}
// 从char数组解析出多个路径
std::vector<std::string> ParseMultiStringPath(const char* buffer, size_t size)
{
std::vector<std::string> paths;
const char* p = buffer;
const char* end = buffer + size;
while (p < end) {
size_t len = strlen(p);
if (len > 0) {
paths.emplace_back(p, len);
}
p += len + 1;
}
return paths;
}

View File

@@ -39,3 +39,7 @@ uint8_t* ScaleBitmap(uint8_t* dst, const uint8_t* src, int srcW, int srcH, int d
std::vector<std::string> PreprocessFilesSimple(const std::vector<std::string>& inputFiles); std::vector<std::string> PreprocessFilesSimple(const std::vector<std::string>& inputFiles);
std::vector<char> BuildMultiStringPath(const std::vector<std::string>& paths); std::vector<char> BuildMultiStringPath(const std::vector<std::string>& paths);
std::vector<std::string> ParseMultiStringPath(const char* buffer, size_t size);
std::vector<std::string> GetForegroundSelectedFiles();

View File

@@ -777,7 +777,7 @@ std::vector<CString> SplitCString(CString strData)
VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName, CString strOS, VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName, CString strOS,
CString strCPU, CString strVideo, CString strPing, CString ver, CString strCPU, CString strVideo, CString strPing, CString ver,
CString startTime, const std::vector<std::string>& v, CONTEXT_OBJECT * ContextObject) CString startTime, std::vector<std::string>& v, CONTEXT_OBJECT * ContextObject)
{ {
auto arr = StringToVector(strPCName.GetString(), '/', 2); auto arr = StringToVector(strPCName.GetString(), '/', 2);
strPCName = arr[0].c_str(); strPCName = arr[0].c_str();
@@ -790,9 +790,12 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
v[RES_CLIENT_PUBIP].empty() ? strIP : v[RES_CLIENT_PUBIP].c_str(), v[RES_CLIENT_PUBIP].empty() ? strIP : v[RES_CLIENT_PUBIP].c_str(),
}; };
auto id = CONTEXT_OBJECT::CalculateID(data); auto id = CONTEXT_OBJECT::CalculateID(data);
if (std::to_string(id) != v[RES_CLIENT_ID]) { auto id_str = std::to_string(id);
if (v[RES_CLIENT_ID].empty()) {
v[RES_CLIENT_ID] = id_str;
}else if (id_str != v[RES_CLIENT_ID]) {
Mprintf("上线消息 - 主机ID错误: calc=%llu, recv=%s, IP=%s, Path=%s\n", Mprintf("上线消息 - 主机ID错误: calc=%llu, recv=%s, IP=%s, Path=%s\n",
id, v[RES_CLIENT_ID].c_str(), strIP.GetString(), path.GetString()); id, v[RES_CLIENT_ID].c_str(), strIP.GetString(), path.GetString());
} }
bool modify = false; bool modify = false;
CString loc = GetClientMapData(id, MAP_LOCATION); CString loc = GetClientMapData(id, MAP_LOCATION);
@@ -2369,25 +2372,6 @@ BOOL CMy2015RemoteDlg::AuthorizeClient(const std::string& sn, const std::string&
return VerifyMessage(pwd, (BYTE*)passcode.c_str(), passcode.length(), hmac); return VerifyMessage(pwd, (BYTE*)passcode.c_str(), passcode.length(), hmac);
} }
// 从char数组解析出多个路径
std::vector<std::string> ParseMultiStringPath(const char* buffer, size_t size)
{
std::vector<std::string> paths;
const char* p = buffer;
const char* end = buffer + size;
while (p < end) {
size_t len = strlen(p);
if (len > 0) {
paths.emplace_back(p, len);
}
p += len + 1;
}
return paths;
}
VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject) VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
{ {
if (isClosed) { if (isClosed) {

View File

@@ -227,7 +227,7 @@ public:
VOID InitControl(); //初始控件 VOID InitControl(); //初始控件
VOID TestOnline(); //测试函数 VOID TestOnline(); //测试函数
VOID AddList(CString strIP, CString strAddr, CString strPCName, CString strOS, CString strCPU, CString strVideo, CString strPing, VOID AddList(CString strIP, CString strAddr, CString strPCName, CString strOS, CString strCPU, CString strVideo, CString strPing,
CString ver, CString startTime, const std::vector<std::string>& v, CONTEXT_OBJECT* ContextObject); CString ver, CString startTime, std::vector<std::string>& v, CONTEXT_OBJECT* ContextObject);
VOID ShowMessage(CString strType, CString strMsg); VOID ShowMessage(CString strType, CString strMsg);
VOID CreatStatusBar(); VOID CreatStatusBar();
VOID CreateToolBar(); VOID CreateToolBar();

View File

@@ -342,6 +342,12 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\common\file_upload.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\common\ikcp.c"> <ClCompile Include="..\..\common\ikcp.c">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>

View File

@@ -62,6 +62,7 @@
<ClCompile Include="SplashDlg.cpp" /> <ClCompile Include="SplashDlg.cpp" />
<ClCompile Include="ToolbarDlg.cpp" /> <ClCompile Include="ToolbarDlg.cpp" />
<ClCompile Include="CDlgFileSend.cpp" /> <ClCompile Include="CDlgFileSend.cpp" />
<ClCompile Include="..\..\common\file_upload.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\client\Audio.h" /> <ClInclude Include="..\..\client\Audio.h" />

View File

@@ -73,7 +73,7 @@ LRESULT CDlgFileSend::OnUpdateFileProgress(WPARAM wParam, LPARAM lParam)
FileChunkPacket* pChunk = (FileChunkPacket*)lParam; FileChunkPacket* pChunk = (FileChunkPacket*)lParam;
CString status; CString status;
double percent = pChunk->fileSize > 0 ? double(pChunk->offset) / pChunk->fileSize * 100.0 : 100.0; double percent = pChunk->fileSize ? (pChunk->offset + pChunk->dataLength) * 100. / pChunk->fileSize : 100.;
m_bIsSending ? m_bIsSending ?
status.Format("发送文件(%d/%d): %.2f%%", 1 + pChunk->fileIndex, pChunk->totalNum, percent): status.Format("发送文件(%d/%d): %.2f%%", 1 + pChunk->fileIndex, pChunk->totalNum, percent):
status.Format("接收文件(%d/%d): %.2f%%", 1 + pChunk->fileIndex, pChunk->totalNum, percent); status.Format("接收文件(%d/%d): %.2f%%", 1 + pChunk->fileIndex, pChunk->totalNum, percent);

View File

@@ -340,9 +340,16 @@ VOID CScreenSpyDlg::OnReceiveComplete()
std::string folder; std::string folder;
if (GetCurrentFolderPath(folder)) { if (GetCurrentFolderPath(folder)) {
// 发送目录并准备接收文件 // 发送目录并准备接收文件
BYTE cmd[300] = { COMMAND_GET_FILE }; std::string files(szBuffer + 1, szBuffer + len);
int len = 1 + folder.length() + files.length() + 1;
BYTE* cmd = new BYTE[len];
cmd[0] = COMMAND_GET_FILE;
memcpy(cmd + 1, folder.c_str(), folder.length()); memcpy(cmd + 1, folder.c_str(), folder.length());
m_ContextObject->Send2Client(cmd, sizeof(cmd)); cmd[1 + folder.length()] = 0;
memcpy(cmd + 1 + folder.length() + 1, files.data(), files.length());
cmd[1 + folder.length() + files.length()] = 0;
m_ContextObject->Send2Client(cmd, len);
SAFE_DELETE_ARRAY(cmd);
} }
break; break;
} }
@@ -1161,20 +1168,6 @@ void CScreenSpyDlg::UpdateCtrlStatus(BOOL ctrl)
SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO)); SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO));
} }
// 将多个路径组合成单\0分隔的char数组
// 格式: "path1\0path2\0path3\0"
std::vector<char> BuildMultiStringPath(const std::vector<std::string>& paths)
{
std::vector<char> result;
for (const auto& path : paths) {
result.insert(result.end(), path.begin(), path.end());
result.push_back('\0');
}
return result;
}
void CScreenSpyDlg::OnDropFiles(HDROP hDropInfo) void CScreenSpyDlg::OnDropFiles(HDROP hDropInfo)
{ {
if (m_bIsCtrl && m_bConnected) { if (m_bIsCtrl && m_bConnected) {

View File

@@ -511,7 +511,7 @@ public:
for (int i = 0; i < ONLINELIST_MAX; i++) { for (int i = 0; i < ONLINELIST_MAX; i++) {
sClientInfo[i] = s[i]; sClientInfo[i] = s[i];
} }
for (int i = 0; i < a.size(); i++) { for (int i = 0; i < a.size() && i < RES_MAX; i++) {
additonalInfo[i] = a[i].c_str(); additonalInfo[i] = a[i].c_str();
} }
} }
@@ -549,6 +549,12 @@ public:
{ {
return additonalInfo[index]; return additonalInfo[index];
} }
void SetAdditionalData(int index, const std::string &value)
{
if (index >= 0 && index < RES_MAX) {
additonalInfo[index] = value.c_str();
}
}
std::string GetGroupName() const override std::string GetGroupName() const override
{ {
return GroupName; return GroupName;