Feature: Add a startup progress display to the program

This commit is contained in:
yuanyuanxiang
2025-11-29 14:13:34 +01:00
parent f891b1a585
commit 9e4aeab1c7
8 changed files with 436 additions and 46 deletions

View File

@@ -1,9 +1,10 @@

// 2015Remote.cpp : 定义应用程序的类行为。 // 2015Remote.cpp : 定义应用程序的类行为。
// //
#include "stdafx.h" #include "stdafx.h"
#include "2015Remote.h" #include "2015Remote.h"
#include "SplashDlg.h"
#include "2015RemoteDlg.h" #include "2015RemoteDlg.h"
#ifdef _DEBUG #ifdef _DEBUG
@@ -245,12 +246,19 @@ BOOL CMy2015RemoteApp::InitInstance()
SetUnhandledExceptionFilter(&whenbuged); SetUnhandledExceptionFilter(&whenbuged);
// 创建并显示启动画面
CSplashDlg* pSplash = new CSplashDlg();
pSplash->Create(NULL);
pSplash->UpdateProgressDirect(5, _T("正在初始化系统图标..."));
SHFILEINFO sfi = {}; SHFILEINFO sfi = {};
HIMAGELIST hImageList = (HIMAGELIST)SHGetFileInfo((LPCTSTR)_T(""), 0, &sfi, sizeof(SHFILEINFO), SHGFI_LARGEICON | SHGFI_SYSICONINDEX); HIMAGELIST hImageList = (HIMAGELIST)SHGetFileInfo((LPCTSTR)_T(""), 0, &sfi, sizeof(SHFILEINFO), SHGFI_LARGEICON | SHGFI_SYSICONINDEX);
m_pImageList_Large.Attach(hImageList); m_pImageList_Large.Attach(hImageList);
hImageList = (HIMAGELIST)SHGetFileInfo((LPCTSTR)_T(""), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SMALLICON | SHGFI_SYSICONINDEX); hImageList = (HIMAGELIST)SHGetFileInfo((LPCTSTR)_T(""), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SMALLICON | SHGFI_SYSICONINDEX);
m_pImageList_Small.Attach(hImageList); m_pImageList_Small.Attach(hImageList);
pSplash->UpdateProgressDirect(10, _T("正在初始化公共控件..."));
// 如果一个运行在 Windows XP 上的应用程序清单指定要 // 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。否则,将无法创建窗口。 //则需要 InitCommonControlsEx()。否则,将无法创建窗口。

View File

@@ -1,25 +1,25 @@

// 2015Remote.h : PROJECT_NAME Ӧ<EFBFBD>ó<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>ļ<EFBFBD> // 2015Remote.h : PROJECT_NAME 应用程序的主头文件
// //
#pragma once #pragma once
#ifndef __AFXWIN_H__ #ifndef __AFXWIN_H__
#error "<EFBFBD>ڰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>֮ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>stdafx.h<><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> PCH <EFBFBD>ļ<EFBFBD>" #error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif #endif
#include "resource.h" // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> #include "resource.h" // 主符号
#include "common/iniFile.h" #include "common/iniFile.h"
#include "IOCPServer.h" #include "IOCPServer.h"
#include "IOCPUDPServer.h" #include "IOCPUDPServer.h"
#include "IOCPKCPServer.h" #include "IOCPKCPServer.h"
// CMy2015RemoteApp: // CMy2015RemoteApp:
// <EFBFBD>йش<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>֣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2015Remote.cpp // 有关此类的实现,请参阅 2015Remote.cpp
// //
// ServerPair: // ServerPair:
// һ<EFBFBD><EFBFBD>SOCKET<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿<EFBFBD>: ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD>TCP<EFBFBD><EFBFBD>UDP. // 一对SOCKET服务端,监听端口: 同时监听TCPUDP.
class ServerPair class ServerPair
{ {
private: private:
@@ -38,11 +38,11 @@ public:
BOOL StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort) BOOL StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort)
{ {
UINT ret1 = m_tcpServer->StartServer(NotifyProc, OffProc, uPort); UINT ret1 = m_tcpServer->StartServer(NotifyProc, OffProc, uPort);
if (ret1) MessageBox(NULL, CString("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>TCP<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>: ") + std::to_string(uPort).c_str() if (ret1) MessageBox(NULL, CString("启动TCP服务失败: ") + std::to_string(uPort).c_str()
+ CString("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ") + std::to_string(ret1).c_str(), "<EFBFBD><EFBFBD>ʾ", MB_ICONINFORMATION); + CString("。错误码: ") + std::to_string(ret1).c_str(), "提示", MB_ICONINFORMATION);
UINT ret2 = m_udpServer->StartServer(NotifyProc, OffProc, uPort); UINT ret2 = m_udpServer->StartServer(NotifyProc, OffProc, uPort);
if (ret2) MessageBox(NULL, CString("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>UDP<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>: ") + std::to_string(uPort).c_str() if (ret2) MessageBox(NULL, CString("启动UDP服务失败: ") + std::to_string(uPort).c_str()
+ CString("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ") + std::to_string(ret2).c_str(), "<EFBFBD><EFBFBD>ʾ", MB_ICONINFORMATION); + CString("。错误码: ") + std::to_string(ret2).c_str(), "提示", MB_ICONINFORMATION);
return (ret1 == 0 || ret2 == 0); return (ret1 == 0 || ret2 == 0);
} }
@@ -65,21 +65,29 @@ public:
} }
}; };
class CSplashDlg; // 前向声明
class CMy2015RemoteApp : public CWinApp class CMy2015RemoteApp : public CWinApp
{ {
private: private:
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD> // 配置文件读取器
config* m_iniFile = nullptr; config* m_iniFile = nullptr;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD> // 服务端对象列表
std::vector<ServerPair*> m_iocpServer; std::vector<ServerPair*> m_iocpServer;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 互斥量
HANDLE m_Mutex = nullptr; HANDLE m_Mutex = nullptr;
// 启动画面
CSplashDlg* m_pSplash = nullptr;
public: public:
CMy2015RemoteApp(); CMy2015RemoteApp();
CImageList m_pImageList_Large; //ϵͳ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD> CImageList m_pImageList_Large; // 系统大图标
CImageList m_pImageList_Small; //ϵͳСͼ<EFBFBD><EFBFBD> CImageList m_pImageList_Small; // 系统小图标
// 获取启动画面指针
CSplashDlg* GetSplash() const { return m_pSplash; }
void SetSplash(CSplashDlg* pSplash) { m_pSplash = pSplash; }
virtual BOOL InitInstance(); virtual BOOL InitInstance();
@@ -88,8 +96,8 @@ public:
return m_iniFile; return m_iniFile;
} }
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0 // 启动多个服务端,成功返回0
// nPortʾ<EFBFBD><EFBFBD>: 6543;7543 // nPort示例: 6543;7543
UINT StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, const std::string& uPort, int maxConn, const std::string& method) UINT StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, const std::string& uPort, int maxConn, const std::string& method)
{ {
bool succeed = false; bool succeed = false;
@@ -111,7 +119,7 @@ public:
return succeed ? 0 : -1; return succeed ? 0 : -1;
} }
// <EFBFBD>ͷŷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SOCKET // 释放服务端 SOCKET
void Destroy() void Destroy()
{ {
for (int i=0; i<m_iocpServer.size(); ++i) { for (int i=0; i<m_iocpServer.size(); ++i) {
@@ -119,7 +127,7 @@ public:
} }
} }
// <EFBFBD>ͷŷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD> // 释放服务端指针
void Delete() void Delete()
{ {
for (int i = 0; i < m_iocpServer.size(); ++i) { for (int i = 0; i < m_iocpServer.size(); ++i) {
@@ -128,7 +136,7 @@ public:
m_iocpServer.clear(); m_iocpServer.clear();
} }
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 更新最大连接数
void UpdateMaxConnection(int maxConn) void UpdateMaxConnection(int maxConn)
{ {
for (int i = 0; i < m_iocpServer.size(); ++i) { for (int i = 0; i < m_iocpServer.size(); ++i) {

View File

@@ -44,6 +44,7 @@
#include "CRcEditDlg.h" #include "CRcEditDlg.h"
#include <thread> #include <thread>
#include "common/file_upload.h" #include "common/file_upload.h"
#include "SplashDlg.h"
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
@@ -1000,13 +1001,37 @@ bool IsFunctionReallyHooked(const char* dllName, const char* funcName)
return false; // 未发现 Hook return false; // 未发现 Hook
} }
// 关闭启动画面的辅助函数
static void CloseSplash()
{
CSplashDlg* pSplash = THIS_APP->GetSplash();
if (pSplash) {
THIS_APP->SetSplash(nullptr);
if (pSplash->GetSafeHwnd()) {
pSplash->DestroyWindow();
}
delete pSplash;
}
}
BOOL CMy2015RemoteDlg::OnInitDialog() BOOL CMy2015RemoteDlg::OnInitDialog()
{ {
#define UPDATE_SPLASH(percent, text) \
do { \
CSplashDlg* pSplash = THIS_APP->GetSplash(); \
if (pSplash && pSplash->GetSafeHwnd()) { \
pSplash->UpdateProgressDirect(percent, _T(text)); \
} \
} while(0)
AUTO_TICK(500); AUTO_TICK(500);
CDialogEx::OnInitDialog(); CDialogEx::OnInitDialog();
UPDATE_SPLASH(20, "正在初始化文件上传模块...");
int ret = InitFileUpload(GetHMAC()); int ret = InitFileUpload(GetHMAC());
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, AfxGetInstanceHandle(), 0); g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, AfxGetInstanceHandle(), 0);
UPDATE_SPLASH(25, "正在初始化视频墙...");
m_GroupList = {"default"}; m_GroupList = {"default"};
// Grid 容器 // Grid 容器
int size = THIS_CFG.GetInt("settings", "VideoWallSize"); int size = THIS_CFG.GetInt("settings", "VideoWallSize");
@@ -1018,6 +1043,7 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
m_gridDlg->SetGrid(size, size); m_gridDlg->SetGrid(size, size);
} }
UPDATE_SPLASH(30, "正在验证配置...");
if (!IsPwdHashValid()) { if (!IsPwdHashValid()) {
THIS_CFG.SetStr("settings", "superAdmin", ""); THIS_CFG.SetStr("settings", "superAdmin", "");
THIS_CFG.SetStr("settings", "Password", ""); THIS_CFG.SetStr("settings", "Password", "");
@@ -1033,7 +1059,8 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
} }
} }
// 将“关于...”菜单项添加到系统菜单中。 UPDATE_SPLASH(35, "正在加载客户端数据库...");
// 将"关于..."菜单项添加到系统菜单中。
SetWindowText(_T("Yama")); SetWindowText(_T("Yama"));
LoadFromFile(m_ClientMap, GetDbPath()); LoadFromFile(m_ClientMap, GetDbPath());
@@ -1052,6 +1079,8 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
} }
} }
UPDATE_SPLASH(40, "正在加载授权模块...");
// 主控程序公网IP // 主控程序公网IP
std::string ip = THIS_CFG.GetStr("settings", "master", ""); std::string ip = THIS_CFG.GetStr("settings", "master", "");
int port = THIS_CFG.Get1Int("settings", "ghost", ';', 6543); int port = THIS_CFG.Get1Int("settings", "ghost", ';', 6543);
@@ -1084,10 +1113,18 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
SAFE_DELETE_ARRAY(data); SAFE_DELETE_ARRAY(data);
} }
} }
UPDATE_SPLASH(50, "正在加载内核模块 (x86 DLL)...");
g_2015RemoteDlg = this; g_2015RemoteDlg = this;
m_ServerDLL[PAYLOAD_DLL_X86] = ReadKernelDll(false, true, master); m_ServerDLL[PAYLOAD_DLL_X86] = ReadKernelDll(false, true, master);
UPDATE_SPLASH(55, "正在加载内核模块 (x64 DLL)...");
m_ServerDLL[PAYLOAD_DLL_X64] = ReadKernelDll(true, true, master); m_ServerDLL[PAYLOAD_DLL_X64] = ReadKernelDll(true, true, master);
UPDATE_SPLASH(60, "正在加载内核模块 (x86 Bin)...");
m_ServerBin[PAYLOAD_DLL_X86] = ReadKernelDll(false, false, master); m_ServerBin[PAYLOAD_DLL_X86] = ReadKernelDll(false, false, master);
UPDATE_SPLASH(65, "正在加载内核模块 (x64 Bin)...");
m_ServerBin[PAYLOAD_DLL_X64] = ReadKernelDll(true, false, master); m_ServerBin[PAYLOAD_DLL_X64] = ReadKernelDll(true, false, master);
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
@@ -1095,18 +1132,19 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 SetIcon(m_hIcon, FALSE); // 设置小图标
UPDATE_SPLASH(70, "正在创建工具栏...");
// TODO: 在此添加额外的初始化代码 // TODO: 在此添加额外的初始化代码
isClosed = FALSE; isClosed = FALSE;
CreateToolBar(); CreateToolBar();
InitControl(); InitControl();
UPDATE_SPLASH(75, "正在创建界面组件...");
CreatStatusBar(); CreatStatusBar();
CreateNotifyBar(); CreateNotifyBar();
CreateSolidMenu(); CreateSolidMenu();
UPDATE_SPLASH(80, "正在加载配置...");
std::string nPort = THIS_CFG.GetStr("settings", "ghost", "6543"); std::string nPort = THIS_CFG.GetStr("settings", "ghost", "6543");
m_nMaxConnection = 2; m_nMaxConnection = 2;
std::string pwd = THIS_CFG.GetStr("settings", "Password"); std::string pwd = THIS_CFG.GetStr("settings", "Password");
@@ -1148,10 +1186,13 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
SetTimer(TIMER_CHECK, max(1, tm) * 60 * 1000, NULL); SetTimer(TIMER_CHECK, max(1, tm) * 60 * 1000, NULL);
#endif #endif
UPDATE_SPLASH(85, "正在启动FRP代理...");
m_hFRPThread = CreateThread(NULL, 0, StartFrpClient, this, NULL, NULL); m_hFRPThread = CreateThread(NULL, 0, StartFrpClient, this, NULL, NULL);
UPDATE_SPLASH(90, "正在启动网络服务...");
// 最后启动SOCKET // 最后启动SOCKET
if (!Activate(nPort, m_nMaxConnection, method)) { if (!Activate(nPort, m_nMaxConnection, method)) {
CloseSplash();
OnCancel(); OnCancel();
return FALSE; return FALSE;
} }
@@ -1160,6 +1201,9 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
THIS_CFG.SetStr("settings", "PwdHash", GetPwdHash()); THIS_CFG.SetStr("settings", "PwdHash", GetPwdHash());
THIS_CFG.SetStr("settings", "MasterHash", GetMasterHash()); THIS_CFG.SetStr("settings", "MasterHash", GetMasterHash());
UPDATE_SPLASH(100, "启动完成!");
CloseSplash();
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
} }

View File

@@ -1,5 +1,5 @@

// 2015RemoteDlg.h : ͷ<EFBFBD>ļ<EFBFBD> // 2015RemoteDlg.h : 头文件
// //
#pragma once #pragma once
@@ -8,9 +8,9 @@
#include "IOCPServer.h" #include "IOCPServer.h"
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD> // 以下为特殊需求使用
// <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD>ʱҲ<EFBFBD>˳<EFBFBD><EFBFBD>ͻ<EFBFBD><EFBFBD><EFBFBD> // 是否在退出主控端时也退出客户端
#define CLIENT_EXIT_WITH_SERVER 0 #define CLIENT_EXIT_WITH_SERVER 0
typedef struct DllInfo { typedef struct DllInfo {
@@ -40,7 +40,7 @@ struct _ClientValue {
char Note[64]; char Note[64];
char Location[64]; char Location[64];
char Level; char Level;
char Reserved[127]; // Ԥ<EFBFBD><EFBFBD> char Reserved[127]; // 预留
_ClientValue() _ClientValue()
{ {
memset(this, 0, sizeof(_ClientValue)); memset(this, 0, sizeof(_ClientValue));
@@ -87,21 +87,23 @@ typedef _ClientValue ClientValue;
typedef std::unordered_map<ClientKey, ClientValue> ComputerNoteMap; typedef std::unordered_map<ClientKey, ClientValue> ComputerNoteMap;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> unordered_map <EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD> // 保存 unordered_map 到文件
void SaveToFile(const ComputerNoteMap& data, const std::string& filename); void SaveToFile(const ComputerNoteMap& data, const std::string& filename);
// <EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>ȡ unordered_map <EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 从文件读取 unordered_map 数据
void LoadFromFile(ComputerNoteMap& data, const std::string& filename); void LoadFromFile(ComputerNoteMap& data, const std::string& filename);
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
enum { enum {
PAYLOAD_DLL_X86 = 0, // 32λ DLL PAYLOAD_DLL_X86 = 0, // 32 DLL
PAYLOAD_DLL_X64 = 1, // 64λ DLL PAYLOAD_DLL_X64 = 1, // 64 DLL
PAYLOAD_MAXTYPE PAYLOAD_MAXTYPE
}; };
// CMy2015RemoteDlg <20>Ի<EFBFBD><D4BB><EFBFBD> class CSplashDlg; // 前向声明
// CMy2015RemoteDlg 对话框
class CMy2015RemoteDlg : public CDialogEx class CMy2015RemoteDlg : public CDialogEx
{ {
protected: protected:
@@ -141,21 +143,21 @@ protected:
} }
LeaveCriticalSection(&m_cs); LeaveCriticalSection(&m_cs);
} }
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 构造
public: public:
CMy2015RemoteDlg(CWnd* pParent = NULL); // <EFBFBD><EFBFBD>׼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CMy2015RemoteDlg(CWnd* pParent = NULL); // 标准构造函数
~CMy2015RemoteDlg(); ~CMy2015RemoteDlg();
// <EFBFBD>Ի<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 对话框数据
enum { IDD = IDD_MY2015REMOTE_DIALOG }; enum { IDD = IDD_MY2015REMOTE_DIALOG };
protected: protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV ֧<EFBFBD><EFBFBD> virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// ʵ<EFBFBD><EFBFBD> // 实现
protected: protected:
HICON m_hIcon; HICON m_hIcon;
void* m_tinyDLL; void* m_tinyDLL;
std::string m_superPass; std::string m_superPass;
// <EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><EFBFBD><EFBFBD>Ϣӳ<EFBFBD><EFBFBD><EFBFBD> // 生成的消息映射函数
virtual BOOL OnInitDialog(); virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint(); afx_msg void OnPaint();
@@ -176,7 +178,7 @@ public:
if (ok) { if (ok) {
m_gridDlg->AddChild((CDialog*)Dlg); m_gridDlg->AddChild((CDialog*)Dlg);
LONG style = ::GetWindowLong(Dlg->GetSafeHwnd(), GWL_STYLE); LONG style = ::GetWindowLong(Dlg->GetSafeHwnd(), GWL_STYLE);
style &= ~(WS_CAPTION | WS_SIZEBOX); // ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С style &= ~(WS_CAPTION | WS_SIZEBOX); // 去掉标题栏和调整大小
::SetWindowLong(Dlg->GetSafeHwnd(), GWL_STYLE, style); ::SetWindowLong(Dlg->GetSafeHwnd(), GWL_STYLE, style);
::SetWindowPos(Dlg->GetSafeHwnd(), nullptr, 0, 0, 0, 0, ::SetWindowPos(Dlg->GetSafeHwnd(), nullptr, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
@@ -190,8 +192,8 @@ public:
return 0; return 0;
} }
VOID InitControl(); //<EFBFBD><EFBFBD>ʼ<EFBFBD>ؼ<EFBFBD> VOID InitControl(); //初始控件
VOID TestOnline(); //<EFBFBD><EFBFBD><EFBFBD>Ժ<EFBFBD><EFBFBD><EFBFBD> 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, const std::vector<std::string>& v, CONTEXT_OBJECT* ContextObject);
VOID ShowMessage(CString strType, CString strMsg); VOID ShowMessage(CString strType, CString strMsg);
@@ -212,7 +214,7 @@ public:
VOID MessageHandle(CONTEXT_OBJECT* ContextObject); VOID MessageHandle(CONTEXT_OBJECT* ContextObject);
VOID SendSelectedCommand(PBYTE szBuffer, ULONG ulLength); VOID SendSelectedCommand(PBYTE szBuffer, ULONG ulLength);
VOID SendAllCommand(PBYTE szBuffer, ULONG ulLength); VOID SendAllCommand(PBYTE szBuffer, ULONG ulLength);
// <EFBFBD><EFBFBD>ʾ<EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ // 显示用户上线信息
CWnd* m_pFloatingTip = nullptr; CWnd* m_pFloatingTip = nullptr;
CListCtrl m_CList_Online; CListCtrl m_CList_Online;
CListCtrl m_CList_Message; CListCtrl m_CList_Message;
@@ -222,7 +224,7 @@ public:
void LoadListData(const std::string& group); void LoadListData(const std::string& group);
void DeletePopupWindow(); void DeletePopupWindow();
CStatusBar m_StatusBar; //״̬<EFBFBD><EFBFBD> CStatusBar m_StatusBar; //状态条
CTrueColorToolBar m_ToolBar; CTrueColorToolBar m_ToolBar;
CGridDialog * m_gridDlg = NULL; CGridDialog * m_gridDlg = NULL;
std::vector<DllInfo*> m_DllList; std::vector<DllInfo*> m_DllList;
@@ -238,7 +240,7 @@ public:
std::map<HWND, CDialogBase *> m_RemoteWnds; std::map<HWND, CDialogBase *> m_RemoteWnds;
CDialogBase* GetRemoteWindow(HWND hWnd); CDialogBase* GetRemoteWindow(HWND hWnd);
void RemoveRemoteWindow(HWND wnd); void RemoveRemoteWindow(HWND wnd);
CDialogBase* m_pActiveSession = nullptr; // <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD> / NULL <EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD> CDialogBase* m_pActiveSession = nullptr; // 当前活动会话窗口指针 / NULL 表示无
afx_msg LRESULT OnSessionActivatedMsg(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnSessionActivatedMsg(WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
HHOOK g_hKeyboardHook = NULL; HHOOK g_hKeyboardHook = NULL;

View File

@@ -304,6 +304,7 @@
<ClInclude Include="SettingDlg.h" /> <ClInclude Include="SettingDlg.h" />
<ClInclude Include="ShellDlg.h" /> <ClInclude Include="ShellDlg.h" />
<ClInclude Include="SortListCtrl.h" /> <ClInclude Include="SortListCtrl.h" />
<ClInclude Include="SplashDlg.h" />
<ClInclude Include="stdafx.h" /> <ClInclude Include="stdafx.h" />
<ClInclude Include="SystemDlg.h" /> <ClInclude Include="SystemDlg.h" />
<ClInclude Include="sys\CCreateTaskDlg.h" /> <ClInclude Include="sys\CCreateTaskDlg.h" />
@@ -386,6 +387,7 @@
<ClCompile Include="SettingDlg.cpp" /> <ClCompile Include="SettingDlg.cpp" />
<ClCompile Include="ShellDlg.cpp" /> <ClCompile Include="ShellDlg.cpp" />
<ClCompile Include="SortListCtrl.cpp" /> <ClCompile Include="SortListCtrl.cpp" />
<ClCompile Include="SplashDlg.cpp" />
<ClCompile Include="stdafx.cpp"> <ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>

View File

@@ -57,6 +57,9 @@
<ClCompile Include="CRcEditDlg.cpp" /> <ClCompile Include="CRcEditDlg.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="Bmp2Video.cpp" /> <ClCompile Include="Bmp2Video.cpp" />
<ClCompile Include="ServerServiceWrapper.cpp" />
<ClCompile Include="ServerSessionMonitor.cpp" />
<ClCompile Include="SplashDlg.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\client\Audio.h" /> <ClInclude Include="..\..\client\Audio.h" />
@@ -127,6 +130,9 @@
<ClInclude Include="..\..\common\obfs.h" /> <ClInclude Include="..\..\common\obfs.h" />
<ClInclude Include="..\..\common\file_upload.h" /> <ClInclude Include="..\..\common\file_upload.h" />
<ClInclude Include="Bmp2Video.h" /> <ClInclude Include="Bmp2Video.h" />
<ClInclude Include="ServerServiceWrapper.h" />
<ClInclude Include="ServerSessionMonitor.h" />
<ClInclude Include="SplashDlg.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="2015Remote.rc" /> <ResourceCompile Include="2015Remote.rc" />

View File

@@ -0,0 +1,267 @@
#include "stdafx.h"
#include "SplashDlg.h"
#include "resource.h"
#include "2015Remote.h"
BEGIN_MESSAGE_MAP(CSplashDlg, CWnd)
ON_WM_PAINT()
ON_MESSAGE(WM_USER + 5000, OnUpdateProgress) // WM_SPLASH_PROGRESS
ON_MESSAGE(WM_USER + 5001, OnUpdateStatus) // WM_SPLASH_STATUS
ON_MESSAGE(WM_USER + 5002, OnCloseSplash) // WM_SPLASH_CLOSE
END_MESSAGE_MAP()
CSplashDlg::CSplashDlg()
: m_nProgress(0)
, m_strStatus(_T("正在初始化..."))
, m_hIcon(NULL)
{
}
CSplashDlg::~CSplashDlg()
{
if (m_fontTitle.m_hObject)
m_fontTitle.DeleteObject();
if (m_fontStatus.m_hObject)
m_fontStatus.DeleteObject();
}
BOOL CSplashDlg::Create(CWnd* pParent)
{
// 注册窗口类
CString strClassName = AfxRegisterWndClass(
CS_HREDRAW | CS_VREDRAW,
::LoadCursor(NULL, IDC_ARROW),
(HBRUSH)(COLOR_WINDOW + 1),
NULL);
// 计算居中位置
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
int x = (screenWidth - SPLASH_WIDTH) / 2;
int y = (screenHeight - SPLASH_HEIGHT) / 2;
// 创建无边框窗口
DWORD dwStyle = WS_POPUP | WS_VISIBLE;
DWORD dwExStyle = WS_EX_TOPMOST | WS_EX_TOOLWINDOW;
if (!CreateEx(dwExStyle, strClassName, _T(""), dwStyle,
x, y, SPLASH_WIDTH, SPLASH_HEIGHT,
pParent ? pParent->GetSafeHwnd() : NULL, NULL))
{
return FALSE;
}
// 创建字体
m_fontTitle.CreateFont(
28, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_SWISS, _T("Microsoft YaHei"));
m_fontStatus.CreateFont(
14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_SWISS, _T("Microsoft YaHei"));
// 加载图标
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
// 注册到应用程序
THIS_APP->SetSplash(this);
ShowWindow(SW_SHOW);
UpdateWindow();
return TRUE;
}
void CSplashDlg::SetProgress(int nPercent)
{
if (nPercent < 0) nPercent = 0;
if (nPercent > 100) nPercent = 100;
if (GetSafeHwnd())
{
PostMessage(WM_SPLASH_PROGRESS, nPercent, 0);
}
}
void CSplashDlg::SetStatusText(const CString& strText)
{
if (GetSafeHwnd())
{
CString* pText = new CString(strText);
PostMessage(WM_SPLASH_STATUS, (WPARAM)pText, 0);
}
}
void CSplashDlg::UpdateProgressDirect(int nPercent, const CString& strText)
{
if (nPercent < 0) nPercent = 0;
if (nPercent > 100) nPercent = 100;
m_nProgress = nPercent;
m_strStatus = strText;
if (GetSafeHwnd())
{
InvalidateRect(NULL, FALSE);
UpdateWindow();
// 处理待处理的消息,确保界面响应
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
void CSplashDlg::Close()
{
if (GetSafeHwnd())
{
PostMessage(WM_SPLASH_CLOSE, 0, 0);
}
}
LRESULT CSplashDlg::OnUpdateProgress(WPARAM wParam, LPARAM lParam)
{
m_nProgress = (int)wParam;
InvalidateRect(NULL, FALSE);
UpdateWindow();
return 0;
}
LRESULT CSplashDlg::OnUpdateStatus(WPARAM wParam, LPARAM lParam)
{
CString* pText = (CString*)wParam;
if (pText)
{
m_strStatus = *pText;
delete pText;
InvalidateRect(NULL, FALSE);
UpdateWindow();
}
return 0;
}
LRESULT CSplashDlg::OnCloseSplash(WPARAM wParam, LPARAM lParam)
{
THIS_APP->SetSplash(nullptr);
DestroyWindow();
return 0;
}
void CSplashDlg::OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
// 双缓冲绘制
CDC memDC;
memDC.CreateCompatibleDC(&dc);
CBitmap memBitmap;
memBitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
CBitmap* pOldBitmap = memDC.SelectObject(&memBitmap);
// 绘制背景 - 渐变效果
for (int y = 0; y < rect.Height(); y++)
{
int r = 45 + (y * 20 / rect.Height());
int g = 45 + (y * 20 / rect.Height());
int b = 55 + (y * 25 / rect.Height());
CPen pen(PS_SOLID, 1, RGB(r, g, b));
CPen* pOldPen = memDC.SelectObject(&pen);
memDC.MoveTo(0, y);
memDC.LineTo(rect.Width(), y);
memDC.SelectObject(pOldPen);
}
// 绘制边框
CPen borderPen(PS_SOLID, 2, RGB(100, 100, 120));
CPen* pOldPen = memDC.SelectObject(&borderPen);
memDC.SelectStockObject(NULL_BRUSH);
memDC.Rectangle(rect);
memDC.SelectObject(pOldPen);
// 绘制图标
if (m_hIcon)
{
DrawIconEx(memDC.GetSafeHdc(), 30, 30, m_hIcon, 48, 48, 0, NULL, DI_NORMAL);
}
// 绘制标题
memDC.SetBkMode(TRANSPARENT);
memDC.SetTextColor(RGB(255, 255, 255));
CFont* pOldFont = memDC.SelectObject(&m_fontTitle);
memDC.TextOut(95, 35, _T("YAMA"));
memDC.SelectObject(pOldFont);
// 绘制副标题
memDC.SetTextColor(RGB(180, 180, 190));
pOldFont = memDC.SelectObject(&m_fontStatus);
memDC.TextOut(95, 70, _T("Remote Administration Tool"));
memDC.SelectObject(pOldFont);
// 绘制进度条背景
CRect progressRect(30, 120, rect.Width() - 30, 140);
DrawProgressBar(&memDC, progressRect);
// 绘制状态文本
memDC.SetTextColor(RGB(200, 200, 210));
pOldFont = memDC.SelectObject(&m_fontStatus);
CRect textRect(30, 150, rect.Width() - 30, 180);
memDC.DrawText(m_strStatus, textRect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
memDC.SelectObject(pOldFont);
// 绘制进度百分比
CString strPercent;
strPercent.Format(_T("%d%%"), m_nProgress);
memDC.SetTextColor(RGB(100, 200, 255));
textRect = CRect(rect.Width() - 80, 150, rect.Width() - 30, 180);
memDC.DrawText(strPercent, textRect, DT_RIGHT | DT_SINGLELINE | DT_VCENTER);
// 复制到屏幕
dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
memDC.SelectObject(pOldBitmap);
}
void CSplashDlg::DrawProgressBar(CDC* pDC, const CRect& rect)
{
// 进度条背景
CBrush bgBrush(RGB(30, 30, 40));
pDC->FillRect(rect, &bgBrush);
// 进度条边框
CPen borderPen(PS_SOLID, 1, RGB(80, 80, 100));
CPen* pOldPen = pDC->SelectObject(&borderPen);
pDC->SelectStockObject(NULL_BRUSH);
pDC->Rectangle(rect);
pDC->SelectObject(pOldPen);
// 计算进度条填充区域
if (m_nProgress > 0)
{
CRect fillRect = rect;
fillRect.DeflateRect(2, 2);
fillRect.right = fillRect.left + (fillRect.Width() * m_nProgress / 100);
// 渐变填充
for (int x = fillRect.left; x < fillRect.right; x++)
{
float ratio = (float)(x - fillRect.left) / (float)fillRect.Width();
int r = (int)(50 + ratio * 50);
int g = (int)(150 + ratio * 50);
int b = (int)(200 + ratio * 55);
CPen pen(PS_SOLID, 1, RGB(r, g, b));
CPen* pOld = pDC->SelectObject(&pen);
pDC->MoveTo(x, fillRect.top);
pDC->LineTo(x, fillRect.bottom);
pDC->SelectObject(pOld);
}
}
}

View File

@@ -0,0 +1,53 @@
#pragma once
#include <afxwin.h>
// 启动画面对话框 - 显示加载进度
class CSplashDlg : public CWnd
{
public:
CSplashDlg();
virtual ~CSplashDlg();
// 创建并显示启动画面
BOOL Create(CWnd* pParent = NULL);
// 更新进度 (0-100) - 通过消息队列(用于跨线程)
void SetProgress(int nPercent);
// 更新状态文本 - 通过消息队列(用于跨线程)
void SetStatusText(const CString& strText);
// 直接更新进度和状态(同一线程使用,立即刷新)
void UpdateProgressDirect(int nPercent, const CString& strText);
// 关闭启动画面
void Close();
protected:
DECLARE_MESSAGE_MAP()
afx_msg void OnPaint();
afx_msg LRESULT OnUpdateProgress(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnUpdateStatus(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnCloseSplash(WPARAM wParam, LPARAM lParam);
private:
int m_nProgress; // 当前进度 0-100
CString m_strStatus; // 状态文本
CFont m_fontTitle; // 标题字体
CFont m_fontStatus; // 状态文本字体
HICON m_hIcon; // 图标
// 窗口尺寸
static const int SPLASH_WIDTH = 400;
static const int SPLASH_HEIGHT = 200;
// 自定义消息 (使用较大的偏移避免与其他消息冲突)
static const UINT WM_SPLASH_PROGRESS = WM_USER + 5000;
static const UINT WM_SPLASH_STATUS = WM_USER + 5001;
static const UINT WM_SPLASH_CLOSE = WM_USER + 5002;
// 绘制相关
void DrawProgressBar(CDC* pDC, const CRect& rect);
};