diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 0000000..87e97b8
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,7 @@
+{
+ "permissions": {
+ "allow": [
+ "mcp__ide__getDiagnostics"
+ ]
+ }
+}
diff --git a/.gitignore b/.gitignore
index 831c33f..0544d7b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/CLAUDE.md b/CLAUDE.md
index 95f74f9..a3c61a7 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -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 驱动视觉,结构与样式分离
- 中文注释,中文沟通
+- 每次编码完毕无需编译,让用户自行编译验证
diff --git a/demoEx/Adminstor/Adminstor/Adminstor.vcxproj b/demoEx/Adminstor/Adminstor/Adminstor.vcxproj
index 23b0de5..8412c08 100644
--- a/demoEx/Adminstor/Adminstor/Adminstor.vcxproj
+++ b/demoEx/Adminstor/Adminstor/Adminstor.vcxproj
@@ -73,47 +73,47 @@
..\_bin\
..\_temp\$(Platform)$(Configuration)$(ProjectName)\
- ..\..\..\include;$(IncludePath)
- ..\..\..\lib;$(LibraryPath)
+ ..\ThirdParty\hp-socket-6.0.7\Include;..\ThirdParty\sqlite3mc\include;..\ThirdParty\openssl\14x\x86\include;..\ThirdParty;..\..\..\include;$(IncludePath)
+ ..\ThirdParty\hp-socket-6.0.7\lib;..\ThirdParty\sqlite3mc\lib;..\ThirdParty\openssl\14x\x86\lib;..\..\..\lib;$(LibraryPath)
$(ProjectName)_$(Configuration)_$(Platform)
..\_bin\
..\_temp\$(Platform)$(Configuration)$(ProjectName)\
- ..\..\..\include;$(IncludePath)
- ..\..\..\lib;$(LibraryPath)
+ ..\ThirdParty\hp-socket-6.0.7\Include;..\ThirdParty\sqlite3mc\include;..\ThirdParty\openssl\14x\x86\include;..\ThirdParty;..\..\..\include;$(IncludePath)
+ ..\ThirdParty\hp-socket-6.0.7\lib;..\ThirdParty\sqlite3mc\lib;..\ThirdParty\openssl\14x\x86\lib;..\..\..\lib;$(LibraryPath)
$(ProjectName)_$(Configuration)_$(Platform)
..\_bin\
..\_temp\$(Platform)$(Configuration)$(ProjectName)\
- ..\..\..\include;$(IncludePath)
- ..\..\..\lib;$(LibraryPath)
+ ..\ThirdParty\hp-socket-6.0.7\Include;..\ThirdParty\sqlite3mc\include;..\ThirdParty\openssl\14x\x64\include;..\ThirdParty;..\..\..\include;$(IncludePath)
+ ..\ThirdParty\hp-socket-6.0.7\lib;..\ThirdParty\sqlite3mc\lib;..\ThirdParty\openssl\14x\x64\lib;..\..\..\lib;$(LibraryPath)
$(ProjectName)_$(Configuration)_$(Platform)
..\_bin\
..\_temp\$(Platform)$(Configuration)$(ProjectName)\
- ..\..\..\include;$(IncludePath)
- ..\..\..\lib;$(LibraryPath)
+ ..\ThirdParty\hp-socket-6.0.7\Include;..\ThirdParty\sqlite3mc\include;..\ThirdParty\openssl\14x\x64\include;..\ThirdParty;..\..\..\include;$(IncludePath)
+ ..\ThirdParty\hp-socket-6.0.7\lib;..\ThirdParty\sqlite3mc\lib;..\ThirdParty\openssl\14x\x64\lib;..\..\..\lib;$(LibraryPath)
$(ProjectName)_$(Configuration)_$(Platform)
Level3
true
-
-
+ HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)
true
stdcpp17
MultiThreadedDebug
Use
pch.h
+ /utf-8 %(AdditionalOptions)
Windows
true
- EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)
+ EzUI_$(Configuration)_$(Platform).lib;HPSocket_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)
@@ -122,36 +122,36 @@
true
true
true
-
-
+ HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)
true
stdcpp17
MultiThreaded
Use
pch.h
+ /utf-8 %(AdditionalOptions)
Windows
false
- EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)
+ EzUI_$(Configuration)_$(Platform).lib;HPSocket_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)
Level3
true
-
-
+ HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)
true
stdcpp17
MultiThreadedDebug
Use
pch.h
+ /utf-8 %(AdditionalOptions)
Windows
true
- EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)
+ EzUI_$(Configuration)_$(Platform).lib;HPSocket_$(Configuration)_$(Platform).lib;sqlite3mc_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)
@@ -160,23 +160,24 @@
true
true
true
-
-
+ HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)
true
stdcpp17
MultiThreaded
Use
pch.h
+ /utf-8 %(AdditionalOptions)
Windows
false
- EzUI_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)
+ EzUI_$(Configuration)_$(Platform).lib;HPSocket_$(Configuration)_$(Platform).lib;sqlite3mc_$(Configuration)_$(Platform).lib;%(AdditionalDependencies)
+
diff --git a/demoEx/Adminstor/Adminstor/Main.cpp b/demoEx/Adminstor/Adminstor/Main.cpp
index 2945f89..d2e12d6 100644
--- a/demoEx/Adminstor/Adminstor/Main.cpp
+++ b/demoEx/Adminstor/Adminstor/Main.cpp
@@ -10,6 +10,6 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
//创建
mainForm nainFrm;
nainFrm.Show();
-
+
return app.Exec();//进行消息循环
}
\ No newline at end of file
diff --git a/demoEx/Adminstor/Adminstor/NetworkClient.h b/demoEx/Adminstor/Adminstor/NetworkClient.h
new file mode 100644
index 0000000..0dd7b1f
--- /dev/null
+++ b/demoEx/Adminstor/Adminstor/NetworkClient.h
@@ -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";
diff --git a/demoEx/Adminstor/Adminstor/Resource.h b/demoEx/Adminstor/Adminstor/Resource.h
index 1b03dee..fe8cb68 100644
--- a/demoEx/Adminstor/Adminstor/Resource.h
+++ b/demoEx/Adminstor/Adminstor/Resource.h
@@ -1,4 +1,4 @@
-//{{NO_DEPENDENCIES}}
+//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 DemoUi.rc 使用
//
diff --git a/demoEx/Adminstor/Adminstor/framework.h b/demoEx/Adminstor/Adminstor/framework.h
index c420462..e120226 100644
--- a/demoEx/Adminstor/Adminstor/framework.h
+++ b/demoEx/Adminstor/Adminstor/framework.h
@@ -1,7 +1,24 @@
-#pragma once
+#pragma once
#include "resource.h"
+// 注意顺序:winsock2.h -> ws2tcpip.h -> iphlpapi.h -> windows.h
+#include
+#include
+#include
#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#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
+#include
+
+#include
+#include
+
+// 包含 nlohmann 库
+#include
+
+// OpenSSL Headers
+#include
+#include
+#include
+#include
+#include
+#include
+
+// 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")
\ No newline at end of file
diff --git a/demoEx/Adminstor/Adminstor/mainForm.cpp b/demoEx/Adminstor/Adminstor/mainForm.cpp
index 920fbec..1008da6 100644
--- a/demoEx/Adminstor/Adminstor/mainForm.cpp
+++ b/demoEx/Adminstor/Adminstor/mainForm.cpp
@@ -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(strData.data()), static_cast(strData.size()));
+}
+// 发送二进制数据
+bool mainForm::sendData(const std::vector& sendData)
+{
+ if (!m_Connected.load(std::memory_order_acquire)) return false;
+
+ return m_Client->Send(sendData.data(), static_cast(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);
diff --git a/demoEx/Adminstor/Adminstor/mainForm.h b/demoEx/Adminstor/Adminstor/mainForm.h
index ca6af80..1d588da 100644
--- a/demoEx/Adminstor/Adminstor/mainForm.h
+++ b/demoEx/Adminstor/Adminstor/mainForm.h
@@ -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& sendData);
+
+ //
+ CSSLClientPtr m_Client; // SSL客户端对象
+ std::atomic m_Connected{ false }; // 是否已连接服务器
+ bool isInitSSLContext = false; // 是否已初始化SSL上下文
protected:
virtual void OnNotify(Control* sender, EventArgs& args)override;//重载事件通知
virtual void OnClose(bool& close)override;//当窗口关闭的时候
diff --git a/demoEx/Adminstor/Adminstor/pch.cpp b/demoEx/Adminstor/Adminstor/pch.cpp
index 331e647..1730571 100644
--- a/demoEx/Adminstor/Adminstor/pch.cpp
+++ b/demoEx/Adminstor/Adminstor/pch.cpp
@@ -1 +1 @@
-#include "pch.h"
\ No newline at end of file
+#include "pch.h"
\ No newline at end of file
diff --git a/demoEx/Adminstor/Adminstor/pch.h b/demoEx/Adminstor/Adminstor/pch.h
index bfcd21d..c9c7883 100644
--- a/demoEx/Adminstor/Adminstor/pch.h
+++ b/demoEx/Adminstor/Adminstor/pch.h
@@ -1,2 +1,2 @@
-#pragma once
+#pragma once
#include "framework.h"
diff --git a/demoEx/Adminstor/_bin/res/mainForm.htm b/demoEx/Adminstor/_bin/res/mainForm.htm
index 206c17c..0314aa5 100644
--- a/demoEx/Adminstor/_bin/res/mainForm.htm
+++ b/demoEx/Adminstor/_bin/res/mainForm.htm
@@ -1,4 +1,4 @@
-
+
@@ -34,7 +34,7 @@
-
+