增加实例:将hp-socket通讯框架集中到UI

This commit is contained in:
2026-02-26 10:12:15 +08:00
parent 78fa2665b0
commit 269412b371
13 changed files with 356 additions and 44 deletions

View File

@@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"mcp__ide__getDiagnostics"
]
}
}

12
.gitignore vendored
View File

@@ -1,9 +1,15 @@
################################################################################
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
################################################################################
ThirdParty/
_temp/
_bin/
.vs/
/build
/build_x64
/build_x86
/example
/demo
/_temp
/_bin
/lib
/.vs
/.vscode

View File

@@ -9,8 +9,13 @@ EzUI 是一个基于原生 Win32 消息机制和 Direct2D 的 C++ 桌面 UI 框
## 构建命令
```bash
build.bat # 构建 32 位静态库
build64.bat # 构建 64 位静态库
# 生成 Visual Studio 项目(推荐)
cmake -S . -B build_x86 -A Win32 # 32位 VS 项目
cmake -S . -B build_x64 -A x64 # 64位 VS 项目
# 或使用现有的批处理脚本
build_x86.bat # 生成 32 位项目并打开
build_x64.bat # 生成 64 位项目并打开
```
CMake 构建:
@@ -38,7 +43,7 @@ cmake -B build -DBUILD_SHARED_LIBS=OFF # 静态库(默认)
- 基础控件:`Label`, `Button`, `TextBox`, `PictureBox`
- 选择控件:`CheckBox`, `RadioButton`, `ComboBox`
- 布局容器:`HLayout`, `VLayout`, `HListView`, `VListView`, `TileListView`, `TabLayout`
- 功能控件:`ScrollBar`, `Menu`, `NotifyIcon`, `ProgressBar`, `TreeView`, `Spacer`
- 功能控件:`ScrollBar`, `Menu`, `NotifyIcon`, `ProgressBar`, `TreeView`, `Spacer`, `TableView`, `IFrame`
### 布局系统
- **尺寸优先级**:比例尺寸 (`SetRateWidth/Height`) > 绝对尺寸 (`SetFixedSize`) > 控件内容大小
@@ -63,10 +68,25 @@ cmake -B build -DBUILD_SHARED_LIBS=OFF # 静态库(默认)
- 跨线程调用:`BeginInvoke`(异步)/ `Invoke`(同步)
- 全局隐藏窗口 `__EzUI_MessageWnd` 用于线程通讯
### 动画系统
- `Animation` 类支持类似 Qt 的过渡动画
- 可用于控件属性(位置、大小、透明度等)的平滑过渡
### 资源管理
- 控件树内存由父控件自动管理:`Attach`/`Detach`
- 图片资源通过 `PtrManager` 自动释放
- XML 布局加载后由 `UIManager` 管理生命周期
- `ResPackage.exe` 工具用于打包资源文件
## Demo 示例
Demo 位于 `demo/` 目录:
- `helloWorld` - 基础 HelloWorld 示例
- `QQ` - 仿 QQ 登录界面
- `kugou` - 仿酷狗音乐播放器(需要 VLC 解码库)
Demo 新版位于 `demoEx/` 目录:
- `Adminstor` - 用户管理 界面示例
## 开发约定
@@ -75,3 +95,4 @@ cmake -B build -DBUILD_SHARED_LIBS=OFF # 静态库(默认)
- 一切皆控件,纯代码组合 UI
- 使用 CSS 驱动视觉,结构与样式分离
- 中文注释,中文沟通
- 每次编码完毕无需编译,让用户自行编译验证

View File

@@ -73,47 +73,47 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\_bin\</OutDir>
<IntDir>..\_temp\$(Platform)$(Configuration)$(ProjectName)\</IntDir>
<IncludePath>..\..\..\include;$(IncludePath)</IncludePath>
<LibraryPath>..\..\..\lib;$(LibraryPath)</LibraryPath>
<IncludePath>..\ThirdParty\hp-socket-6.0.7\Include;..\ThirdParty\sqlite3mc\include;..\ThirdParty\openssl\14x\x86\include;..\ThirdParty;..\..\..\include;$(IncludePath)</IncludePath>
<LibraryPath>..\ThirdParty\hp-socket-6.0.7\lib;..\ThirdParty\sqlite3mc\lib;..\ThirdParty\openssl\14x\x86\lib;..\..\..\lib;$(LibraryPath)</LibraryPath>
<TargetName>$(ProjectName)_$(Configuration)_$(Platform)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>..\_bin\</OutDir>
<IntDir>..\_temp\$(Platform)$(Configuration)$(ProjectName)\</IntDir>
<IncludePath>..\..\..\include;$(IncludePath)</IncludePath>
<LibraryPath>..\..\..\lib;$(LibraryPath)</LibraryPath>
<IncludePath>..\ThirdParty\hp-socket-6.0.7\Include;..\ThirdParty\sqlite3mc\include;..\ThirdParty\openssl\14x\x86\include;..\ThirdParty;..\..\..\include;$(IncludePath)</IncludePath>
<LibraryPath>..\ThirdParty\hp-socket-6.0.7\lib;..\ThirdParty\sqlite3mc\lib;..\ThirdParty\openssl\14x\x86\lib;..\..\..\lib;$(LibraryPath)</LibraryPath>
<TargetName>$(ProjectName)_$(Configuration)_$(Platform)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>..\_bin\</OutDir>
<IntDir>..\_temp\$(Platform)$(Configuration)$(ProjectName)\</IntDir>
<IncludePath>..\..\..\include;$(IncludePath)</IncludePath>
<LibraryPath>..\..\..\lib;$(LibraryPath)</LibraryPath>
<IncludePath>..\ThirdParty\hp-socket-6.0.7\Include;..\ThirdParty\sqlite3mc\include;..\ThirdParty\openssl\14x\x64\include;..\ThirdParty;..\..\..\include;$(IncludePath)</IncludePath>
<LibraryPath>..\ThirdParty\hp-socket-6.0.7\lib;..\ThirdParty\sqlite3mc\lib;..\ThirdParty\openssl\14x\x64\lib;..\..\..\lib;$(LibraryPath)</LibraryPath>
<TargetName>$(ProjectName)_$(Configuration)_$(Platform)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>..\_bin\</OutDir>
<IntDir>..\_temp\$(Platform)$(Configuration)$(ProjectName)\</IntDir>
<IncludePath>..\..\..\include;$(IncludePath)</IncludePath>
<LibraryPath>..\..\..\lib;$(LibraryPath)</LibraryPath>
<IncludePath>..\ThirdParty\hp-socket-6.0.7\Include;..\ThirdParty\sqlite3mc\include;..\ThirdParty\openssl\14x\x64\include;..\ThirdParty;..\..\..\include;$(IncludePath)</IncludePath>
<LibraryPath>..\ThirdParty\hp-socket-6.0.7\lib;..\ThirdParty\sqlite3mc\lib;..\ThirdParty\openssl\14x\x64\lib;..\..\..\lib;$(LibraryPath)</LibraryPath>
<TargetName>$(ProjectName)_$(Configuration)_$(Platform)</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>
</PreprocessorDefinitions>
<PreprocessorDefinitions>HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;HPSocket_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -122,36 +122,36 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>
</PreprocessorDefinitions>
<PreprocessorDefinitions>HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;HPSocket_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>
</PreprocessorDefinitions>
<PreprocessorDefinitions>HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;HPSocket_$(Configuration)_$(Platform).lib;sqlite3mc_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -160,23 +160,24 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>
</PreprocessorDefinitions>
<PreprocessorDefinitions>HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>EzUI_$(Configuration)_$(Platform).lib;HPSocket_$(Configuration)_$(Platform).lib;sqlite3mc_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="framework.h" />
<ClInclude Include="mainForm.h" />
<ClInclude Include="NetworkClient.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="Resource.h" />
</ItemGroup>

View File

@@ -10,6 +10,6 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
//创建
mainForm nainFrm;
nainFrm.Show();
return app.Exec();//进行消息循环
}

View File

@@ -0,0 +1,103 @@
#pragma once
#include "pch.h"
#include "HPSocket-SSL.h"
// SSL证书配置
static const char* g_lpszPemCert = R"(-----BEGIN CERTIFICATE-----
MIIElTCCAn2gAwIBAgIUdQCiE198je6YcO36MbHHQJkuvvYwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEDAOBgNVBAgMB0JlaWppbmcxEDAOBgNVBAcMB0Jl
aWppbmcxDzANBgNVBAoMBk15c2VsZjELMAkGA1UECwwCSVQxDTALBgNVBAMMBE15
Q0EwIBcNMjYwMjIzMTIwMzM4WhgPMjA5MzA4MjAxMjAzMzhaMGUxCzAJBgNVBAYT
AkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdCZWlqaW5nMRIwEAYDVQQK
DAlNeUNvbXBhbnkxCzAJBgNVBAsMAklUMREwDwYDVQQDDAhNeUNsaWVudDCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALc43ZqrQkgGZRPfVOCW+wJ1fox9
CiKkmUIWTgRaJTwYy18f4WNjQxB69LBkQXJFeU3M8urM7485iIOyAMgT4hJNu/lm
RgK0b2A6i8INqh0KlgM02fqmpwW+/XPyzR7I0a7/ph9zfzz+hVjm/k8GHnArCwEu
Z0Ii8MH7T0rgzEPZIIKokBb5OeZo3BS8RmE1HemSQGxEHfcRSa1mygW5Kujv9AK5
DQZJ2UgnArGsPawe7sQQFAbV59pThxCb8EFmZ44qfpoPTK7Ki0HiE12cIa4DBKe4
xb2IZOcpE1r94zT9TdXye+VPj9y2lckM8TLSEH7eHr+BNhir9PSRVas6KMcCAwEA
AaNCMEAwHQYDVR0OBBYEFFQndGIMOfspC0uS2AbS69DAelvBMB8GA1UdIwQYMBaA
FOU/8+1LOIrynX9cOJ/MBpuzrkGMMA0GCSqGSIb3DQEBCwUAA4ICAQAGy9ST0Ajt
FzRFT4fX7IXj4gMBWN+GF9yWWCmViEcWdSMQb6A6vwrqhUq2Y/VTbCLI0EZAHC3c
9+HFX24r9qUZvt5yYDQsb/PCBPGTArKd7Nk0wKIsWZp7oJ3I6n71zL4vb/0vSGaX
MQCizQmAziA4QcJOX4MnYnXPbMfEFbFOnIYMV3vjmRMUSqxkLPUMx/xy8vd9Jz9g
ribhd9ChxUXKxilTq2sEgASyFnNIYy0dZUcY272d4sAFRdCwL6B8EkUnqyg8LO4T
rxlr72hrbTUcghuyicYeQrQYHsKF5fn5b88Kj0DlD68S5pSztcCyy+ykmm83dM7F
ytS2VmUIondyApEATp3nkpdWI0M8+CWsdWS09yQuA340qeA3bwrptC6cWuqJSb9N
89MV4Anzx5J1hUIByxhpzZ7vnkogJ8hCHIwom7sLOVnBe8GDrIK3/E6ygs8+uOXY
zPIAdbqX7P4ZykJtHfDaBSyDstT9Y+tLjo1JVwAO5InLYGubb2B6YEJhlymLlx+I
mSA1UwnKHX14onP5hk9FdJKhf0UsL4VbTv/MFuS1/T0ttlCk9hK2WF6loorNqfQe
lMnFCbLM8yPEMj3fztu1rY2aa5hGfydLYdqd/XAn4DzWgrJ9gqgkYWZkeKPBMTob
xY7Di4RK6hKuv1eAWVYaW/0L/dSzoeSVKQ==
-----END CERTIFICATE-----
)";
static const char* g_lpszPemKey = R"(-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQwIT5fQX1UBh87aBm
hS6xvQICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEP7SgX/IZwOWwTFJ
ggNpLRcEggTQuFpDfjY2w2G7ugHJp4yB+ghWM95LCvKwSGZzDJ53YQYL5j0xgeGU
zkyWTqqTF/V71uCnFasJk5H3Mev/tUAZJ4xF7EeD8yJQZpl9inZruahWnpeIWDkY
MPp6rbJs+DtWvTXAUxehAUQ6MlVP1/Q2Jue2k7Y7AQ1G/yWgE16fvCUsRcPwBbtY
Sgf+eqX3p8U+giF31hErjhMktnU2QR9cjpJl2iFXuzoZpR20JT1Mb3WZX+IOhdXZ
7O98aklj0H1vPD/h+gdK4W/pawDNOKi3Ft7mlhcNbsTlS9bumyCGR4wnafx974VV
TMPlJ/mPhfW+GO5qp2lR4KFc5jL2J9Og/REgqpANVvXViurTSbkyekrrC2Vy1eAs
tswm3xntXzS+hxwt+4+F2TyW85m6wMfRHaKvzN9tkR05rCzG4rFfaCdkySTEAoJ/
jlFes7K2+3dDEx/TRwqh6Drxk6hUis3YWKOGPiaEe5Ksxk1AXwnFKvKnGk6kvP9E
Kl4AgwpwXQ1kPj4qeFx5Qq1tN+AE4UnLzIYcpCYdKqGc8V5gXAVLaH37Dy8qqhcz
ysfBoGsFv0jjiImPFcuGePf0AOjq9EDNw14FhWUhe+FI4H8vmGoMsgh4S48bXxsw
hRRJhquAe2TbIhx+e+ZN2SEUoO81oUzIOV/RPSY+cV+SkSJ9T2LWPPM7jTD9XgM0
2/Lz9dk53nr/m4JfYy0HOu15nqOR7pOK5qH8MLYbtiHH7huDgPPCJQgb68cX/xNy
RJcPXEkcti5/aT4dsi1wZb/zpOjJ2DfGFZ9MNQACX+2av/3yxmXspLuJuTHln0Id
xud0QU//Xbh5DV3ZV7zNVFCQNOhRj4p9A/vhCoDvTCvj/p6CvGboMcLXcwD2gI/9
/zXpsUucsVrS+EEIrCRVzb+AqfqM9XCBspVQyeYhaKTRwMgfSGN2P4dkEDBY94LZ
p4QSxgMxyDtH4mZl8pAJaJ6jajF6rqDyV/EnKoKPKDT61+0f3m3aV3MdcKpXKB0z
m3X4TpNzr2jA7rgYmdpR2Aa5xgmYCV5Wi1vKTf9dBShr5xcAltFHc1AtWx5RFOeI
/GBAwtxkpaYSG/TMVyjVLZ0IPxP3U4ugA3iIRMNsx2CiJcekUzFfcIGgwikvI90g
lxX6ASJAnlPJ1PQgF7uMOf5wbwvni7sYNkwxwA02PW5e7uJDIdY4w6DXrMmJdXKw
ONxg3EENgwnleocduJtXYZOQvdL2uiXVG61kSeUjQRgmmWbIfOJxZpejH46/f3bo
a0Kk1IKROOtW8dXTkgvhaL0F7W8l3WnA185ceFxAQQeHUGdqAF3eEiljZrk3T7st
UNcFW1lypNEQ98J9y5N0aCEZA+xJSCnRG3aiGWEsMTGr6RTzlRXLpAWUYD80+tad
S5SqrX3aK1Rgm300kqW0h4Klltz7WGSuNHH+pOoFB++UJPEM46E+HQ1wowaYov72
Pxpz1VlyaX926RTrs1sSrohGfVgANdlG+IxmAJM2SYbBT/dhmYzDZIS8HnNU8QeF
XdA/ONzJOg5CP+K2pvqQQv1yeA7+wBqzbOXDS0yhnQCOE5J7mgjkyUV9THLTBNat
Hgg657X4X3lawUHFt3CbIKTo9WCCQw6xx0QqtwV7riYkdwhHGHgHe/U=
-----END ENCRYPTED PRIVATE KEY-----
)";
static const char* g_lpszCAPemCert = R"(-----BEGIN CERTIFICATE-----
MIIFnzCCA4egAwIBAgIUOyt7hlCJPl9mOO0BMEJd6cI8TiEwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEDAOBgNVBAgMB0JlaWppbmcxEDAOBgNVBAcMB0Jl
aWppbmcxDzANBgNVBAoMBk15c2VsZjELMAkGA1UECwwCSVQxDTALBgNVBAMMBE15
Q0EwIBcNMjYwMjIzMTIwMjAyWhgPMjA5MzA4MjAxMjAyMDJaMF4xCzAJBgNVBAYT
AkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdCZWlqaW5nMQ8wDQYDVQQK
DAZNeXNlbGYxCzAJBgNVBAsMAklUMQ0wCwYDVQQDDARNeUNBMIICIjANBgkqhkiG
9w0BAQEFAAOCAg8AMIICCgKCAgEAsolBAdfumyA8Iwae/LgIrPpZxhUfXVfS9XxV
8l7j5jdNT3A7jtzRqUxDU0dHVW5LPgsgB+bGaecFB97odCQUiM3bUbVNTEqwvtwW
4g7PdcQBVO+MmID1gqkAo49NOJiQWkH5fao0srvGENXN+orwwIeYTVDKwBd0RQ2w
53d22FlJZkYZB43JRVwPDHsWJiFAp7dUNux7HtwKrAUfZWFUwkbGcXqZqFPCw3ol
t11mIjHWMIwhVcozloaIQSQggCETFRGKY1TtfbnoPT4aIcJwTAJv7c9Dd9a7bZkO
+bcTJk0amLrnj051HKpMWofqUETA4GhHCKWxNF+Fbe5hYDxUtmh/2fJo2QCac/tY
6YtBoPEiXMfFGXDAEClr0T5b2AH/7J27xuaRjT5SP+LR+g1gphA/8Fcist8kp8PM
ar5D6S5raAoyTRvVZ0vfYuzm83SeyL3KlRi7idfQHmTqJB3KabuV+bxc3R+oKW6P
yoZBtRAyJU6wPteMSoRjj8Wv92TRf9VDlN/5KgsaYrdQDy0fbHFgUhffOf2+z8l7
FD/fe8S4epAd3HZgz+jymJpRUB/xHeTfs9gzbQxy2JkKgCNGG4nRCtsrKOnMFAhJ
x0d86m4vYin3lRwerI68+uhFc/VETERSDQFgVVXcZ+rxzstbFx8o72Kwg6n4jh3k
rK8cSf0CAwEAAaNTMFEwHQYDVR0OBBYEFOU/8+1LOIrynX9cOJ/MBpuzrkGMMB8G
A1UdIwQYMBaAFOU/8+1LOIrynX9cOJ/MBpuzrkGMMA8GA1UdEwEB/wQFMAMBAf8w
DQYJKoZIhvcNAQELBQADggIBACVBuslKJAdW7UlRGinZXxbrjMTyOzmPR9jqEc9o
51SzE5vX7SZqSdKoogx0T7UlvACSEgfPiz9mhuDxRnssi+gQ537y1dEihzKMReIp
sbL3vO82MtdfViOWi4ezBM+FdgtHn3LpQ9UsJoMyOPFCuOIn0yyp4AhtTO5eeSiF
q15eUZ6tFWNNdIYl6QBSsJG/zwXI92lYqrRPLHvS6A4BUyhdHX0d9L0sr8twRmfx
P3yHBCmRfDs8vE0oSm3+aS+C7g6CVF3qoG0NdOZd4z2JKjNjapPK4v3g0q3itjxt
ZJdC+suQFvMM6wymcXxL4hqE+lV+6E+uwV2+sQxQdS3qUOc81AxSGdfQg+6eZyWM
aeWwjpRGObQFqpcsrVF2mQWXH2Y3ZA9MbPoneej3ruUHM2c6wGhh3V4YF1mcKwaR
hYd+1GI8fAdibN/vWuNqe3iDtHwm3jYcRefIxTc5OXxHrYrS90jSdF3og2Pn1DJY
fSh8XsFLXXe1iY9L1ISzm6AT4/QOQQG6zoIZxNwHpdtH5N/5b5mrhVEYRciv+dn3
3/8du56xMT7oiBv7YR6+Rvv0C1+pu/MKFxxoBKHspt9kjV766yxER1vEepTet7N4
DZvWiYOptU12bP+R8wlwGnmTbhul7TnkQ91LUsCYhCprHKL+JHgeOPEQdpqAjVgq
ik2N
-----END CERTIFICATE-----
)";
static const int g_iVerifyMode = SSL_VM_PEER;
static const char* g_lpszKeyPassword = "151AnryUBW9658Aa7553";

View File

@@ -1,4 +1,4 @@
//{{NO_DEPENDENCIES}}
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 DemoUi.rc 使用
//

View File

@@ -1,7 +1,24 @@
#pragma once
#pragma once
#include "resource.h"
// 注意顺序winsock2.h -> ws2tcpip.h -> iphlpapi.h -> windows.h
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <windows.h>
#include <TlHelp32.h>
#include <shellapi.h>
#include <mutex>
#include <regex>
#include <iostream>
#include <vector>
#include <codecvt>
#include <fstream>
#include <filesystem>
#include <string>
#include <conio.h>
#include <locale>
#include "ezui/Application.h" //app类
#include "EzUI/Window.h" //基础窗口类
@@ -18,4 +35,33 @@
#include "EzUI/LayeredWindow.h"//分层窗口类-可以异型透明窗口
#include "ezui/UIManager.h"//ui管理类(使用xml生成控件)
#include "EzUI/Animation.h"
#include "EzUI/TableView.h"
#include "EzUI/Menu.h"
#include <HPSocket.h>
#include <HPSocket-SSL.h>
#include <sqlite3.h>
#include <sqlite3mc.h>
// 包含 nlohmann 库
#include <nlohmann/json.hpp>
// OpenSSL Headers
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
// Link libraries
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "libssl.lib")
#pragma comment(lib, "libcrypto.lib")
#pragma comment(lib, "crypt32.lib")

View File

@@ -1,6 +1,101 @@
#include "pch.h"
#include "mainForm.h"
// 发送数据成功后的处理
EnHandleResult mainForm::OnSend(ITcpClient* pSender, CONNID dwConnID, const BYTE* pData, int iLength)
{
return HR_OK;
}
// 接收数据后的处理
EnHandleResult mainForm::OnReceive(ITcpClient* pSender, CONNID dwConnID, const BYTE* pData, int iLength)
{
return HR_OK;
}
// 连接关闭后的处理
EnHandleResult mainForm::OnClose(ITcpClient* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode)
{
std::cout << "连接已关闭!" << std::endl;
// 设置连接状态为未连接
m_Connected.store(false, std::memory_order_release);
Button* btnAdminConnect = (Button*)FindControl("btnAdminConnect");
if (btnAdminConnect) {
btnAdminConnect->SetText(L"");
// 设置背景颜色为 #FF7774 (红色)
btnAdminConnect->Style.BackColor = Color(255, 119, 116);
isInitSSLContext = false;
}
return HR_OK;
}
// 连接成功后的处理
EnHandleResult mainForm::OnConnect(ITcpClient* pSender, CONNID dwConnID)
{
TCHAR szAddress[100]; // 存储地址的缓冲区
int iAddressLen = sizeof(szAddress) / sizeof(TCHAR);
USHORT usPort;
pSender->GetLocalAddress(szAddress, iAddressLen, usPort);
// 设置连接状态为已连接
m_Connected.store(true, std::memory_order_release);
Button* btnAdminConnect = (Button*)FindControl("btnAdminConnect");
if (btnAdminConnect) {
btnAdminConnect->SetText(L"🔃");
btnAdminConnect->Style.BackColor = Color(0, 185, 107);
}
return HR_OK;
}
// SSL握手完成后的处理
EnHandleResult mainForm::OnHandShake(ITcpClient* pSender, CONNID dwConnID)
{
std::cout << "SSL握手完成" << std::endl;
return HR_OK;
}
// 开始连接服务器
bool mainForm::startConnection(const LPCTSTR& lpszAddress, USHORT usPort)
{
if (m_Connected.load(std::memory_order_acquire)) return true;
if (!isInitSSLContext) {
// 初始化SSL证书
if (!m_Client->SetupSSLContextByMemory(g_iVerifyMode, g_lpszPemCert, g_lpszPemKey, g_lpszKeyPassword, g_lpszCAPemCert)) {
std::cout << "SSL上下文设置失败" << std::endl;
return false;
}
}
// 启动连接
if (!m_Client->Start(lpszAddress, usPort, FALSE)) {
std::cout << "连接服务器失败!错误码: " << m_Client->GetLastError() << std::endl;
m_Client->CleanupSSLContext();
return false;
}
isInitSSLContext = true;
return true;
}
// 断开连接服务器
void mainForm::stopConnection()
{
if (!m_Connected.load(std::memory_order_acquire) || !m_Client->HasStarted()) return;
m_Client->Stop();
}
// 发送字符串数据
bool mainForm::sendData(const std::string& strData)
{
if (!m_Connected.load(std::memory_order_acquire)) return false;
return m_Client->Send(reinterpret_cast<const BYTE*>(strData.data()), static_cast<int>(strData.size()));
}
// 发送二进制数据
bool mainForm::sendData(const std::vector<uint8_t>& sendData)
{
if (!m_Connected.load(std::memory_order_acquire)) return false;
return m_Client->Send(sendData.data(), static_cast<int>(sendData.size()));
}
void mainForm::OnNotify(Control* sender, EventArgs& args)
{
UIString btnName = sender->Name; // 控件id
@@ -42,17 +137,23 @@ void mainForm::OnNotify(Control* sender, EventArgs& args)
mainTab->SetPageIndex(1);
mainTab->Invalidate();
}
else if (btnName == "btnAdminConnect") { //管理页面的连接按钮按下,先获取 btnAdminConnect 按钮,设置为不可用,修改文字为“连接中...”
else if (btnName == "btnAdminConnect") { //管理页面的连接按钮按下
Button* btnAdminConnect = (Button*)FindControl("btnAdminConnect");
btnAdminConnect->SetText(L"🔄");
btnAdminConnect->Style.BackColor = Color(0, 185, 107);
TextBox* textAdminIP = (TextBox*)FindControl("editAdminIP");
// 先连接
if (!m_Connected.load(std::memory_order_acquire)) {
// 目前未连接,开始连接
if (!isInitSSLContext)
m_Client->CleanupSSLContext();
startConnection(textAdminIP->GetText().unicode().c_str(), 5556);
}
}
else if (btnName == "btnAdminTemp") { //管理页面的测试按钮
TextBox* textAdmin = (TextBox*)FindControl("textAdminOutput"); //获取输出框
//textAdmin->Insert(L"\n测试成功", true);
if (textAdmin) {
textAdmin->Insert(L"\n测试成功!",true);
}
}
}
break;
@@ -73,10 +174,12 @@ void mainForm::OnNotify(Control* sender, EventArgs& args)
void mainForm::OnClose(bool& close)
{
// 断开网络连接
Application::Exit();
}
mainForm::mainForm() :LayeredWindow(1500, 750)
mainForm::mainForm() : LayeredWindow(1500, 750), m_Connected(false), m_Client(this)
{
// 如果是debug模式则创建控制台窗口用于输出调试信息
#ifdef _DEBUG
@@ -84,11 +187,13 @@ mainForm::mainForm() :LayeredWindow(1500, 750)
FILE* fp = nullptr;
freopen_s(&fp, "CONOUT$", "w", stdout);
freopen_s(&fp, "CONOUT$", "w", stderr);
// 设置控制台UTF-8编码
SetConsoleOutputCP(CP_UTF8);
std::cout << "调试模式控制台已启动!" << std::endl;
#endif
SetResizable(true); // 启用窗口大小调整
SetMiniSize(Size(600, 450)); // 设置最小尺寸
SetMiniSize(Size(800, 550)); // 设置最小尺寸
umg.LoadXml("res/mainForm.htm");//加载xml里面的控件与样式
umg.SetupUI(this);

View File

@@ -1,15 +1,38 @@
#pragma once
#include "pch.h"
#include "NetworkClient.h"
using namespace ezui;
// 主窗口
class mainForm :public LayeredWindow
class mainForm : public LayeredWindow, public CTcpClientListener
{
private:
//ui管理类
UIManager umg;
// hp-socket 网络通信类
virtual EnHandleResult OnSend(ITcpClient* pSender, CONNID dwConnID, const BYTE* pData, int iLength);
virtual EnHandleResult OnReceive(ITcpClient* pSender, CONNID dwConnID, const BYTE* pData, int iLength);
virtual EnHandleResult OnClose(ITcpClient* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode);
virtual EnHandleResult OnConnect(ITcpClient* pSender, CONNID dwConnID);
virtual EnHandleResult OnHandShake(ITcpClient* pSender, CONNID dwConnID);
// 开始网络连接
bool startConnection(const LPCTSTR& lpszAddress, USHORT serverPort);
// 断开网络连接
void stopConnection();
// 是否已连接服务器
bool IsConnected() const { return m_Connected.load(std::memory_order_acquire); }
// 发送字符串数据
bool sendData(const std::string& strData);
// 发送二进制数据
bool sendData(const std::vector<uint8_t>& sendData);
//
CSSLClientPtr m_Client; // SSL客户端对象
std::atomic<bool> m_Connected{ false }; // 是否已连接服务器
bool isInitSSLContext = false; // 是否已初始化SSL上下文
protected:
virtual void OnNotify(Control* sender, EventArgs& args)override;//重载事件通知
virtual void OnClose(bool& close)override;//当窗口关闭的时候

View File

@@ -1 +1 @@
#include "pch.h"
#include "pch.h"

View File

@@ -1,2 +1,2 @@
#pragma once
#pragma once
#include "framework.h"

View File

@@ -1,4 +1,4 @@
<vlayout id="mainLayout" action="move">
<vlayout id="mainLayout" action="move">
<!-- 标题栏 -->
<hbox id="titleMain" height="30" margin-top="1" action="title">
<label margin-left="5" id="userImg" size="35,35" style="background-image: url(res/head.png); border-radius: 20px; border: 2px solid white; "></label>
@@ -34,7 +34,7 @@
<!-- 连接按钮 -->
<button id="btnAdminConnect" size="25,25" text="❌" style="color: #FFFFFF; background-color: #FF7774; border-radius: 3px; " />
<!-- IP输入框 -->
<textbox class="adminEdit" margin-left="5" height="30" halign="center" id="servIP" placeholder="服务器地址" width="130" />
<textbox class="adminEdit" id="editAdminIP" text="127.0.0.1" margin-left="5" height="30" halign="center" placeholder="服务器地址" width="130" />
<spacer width="10"></spacer>
<!-- 测试按钮 -->
<button class="adminButtons" id="btnAdminTemp" size="60,30" text="测试" />