From 269412b371830c932fe16b7ecda85eb0a3c1511f Mon Sep 17 00:00:00 2001 From: anry Date: Thu, 26 Feb 2026 10:12:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AE=9E=E4=BE=8B=EF=BC=9A?= =?UTF-8?q?=E5=B0=86hp-socket=E9=80=9A=E8=AE=AF=E6=A1=86=E6=9E=B6=E9=9B=86?= =?UTF-8?q?=E4=B8=AD=E5=88=B0UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 7 ++ .gitignore | 12 +- CLAUDE.md | 27 +++- demoEx/Adminstor/Adminstor/Adminstor.vcxproj | 41 ++++--- demoEx/Adminstor/Adminstor/Main.cpp | 2 +- demoEx/Adminstor/Adminstor/NetworkClient.h | 103 ++++++++++++++++ demoEx/Adminstor/Adminstor/Resource.h | 2 +- demoEx/Adminstor/Adminstor/framework.h | 48 +++++++- demoEx/Adminstor/Adminstor/mainForm.cpp | 123 +++++++++++++++++-- demoEx/Adminstor/Adminstor/mainForm.h | 27 +++- demoEx/Adminstor/Adminstor/pch.cpp | 2 +- demoEx/Adminstor/Adminstor/pch.h | 2 +- demoEx/Adminstor/_bin/res/mainForm.htm | 4 +- 13 files changed, 356 insertions(+), 44 deletions(-) create mode 100644 .claude/settings.local.json create mode 100644 demoEx/Adminstor/Adminstor/NetworkClient.h 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 @@