From deecdbeeab891383755f97ec0521f027065280bc Mon Sep 17 00:00:00 2001 From: JiXieShi Date: Fri, 12 Sep 2025 20:51:47 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E6=96=B0=E5=A2=9E:=20=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=E6=89=98=E7=9B=98=E5=9B=BE=E6=A0=87=E3=80=81=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 3 ++- app/inc/TrayIcon.h | 14 ++++++++++---- app/src/CLIProcess.cpp | 1 - app/src/Manager.cpp | 18 +++++++++++++++--- app/src/TrayIcon.cpp | 8 ++++---- logo.ico | Bin 0 -> 15406 bytes logo.rc | 2 ++ 7 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 logo.ico create mode 100644 logo.rc diff --git a/CMakeLists.txt b/CMakeLists.txt index 4338301..d486685 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ file(GLOB SRC ${IMGUI_DIR}/misc/cpp/*.cpp app/src/*.* main.cpp + ) @@ -63,7 +64,7 @@ if(IMGUI_BACKENDS STREQUAL "win32_dx11") endif() # generate binary -add_executable(${PROJECT_NAME} WIN32 ${SRC} ${PLATFORM_SRC}) +add_executable(${PROJECT_NAME} WIN32 ${SRC} ${PLATFORM_SRC} logo.rc) if(IMGUI_BACKENDS STREQUAL "glfw_opengl") target_link_libraries(${PROJECT_NAME} diff --git a/app/inc/TrayIcon.h b/app/inc/TrayIcon.h index f4286d5..6bc6b66 100644 --- a/app/inc/TrayIcon.h +++ b/app/inc/TrayIcon.h @@ -35,12 +35,18 @@ public: // 设置回调函数 void SetShowWindowCallback(const ShowWindowCallback &callback); void SetExitCallback(const ExitCallback &callback); + enum class NotifyAction { + Notify_NONE, + Notify_INFO, + Notify_WARNING, + Notify_ERROR, + Notify_USER + }; + #ifdef _WIN32 - void ShowWindowsNotification(const std::wstring& title, const std::wstring& message); -#elif __APPLE__ - void ShowMacNotification(const std::string& title, const std::string& message); + void ShowNotification(const std::wstring &title, const std::wstring &message, NotifyAction notify= NotifyAction::Notify_INFO) const; #else - void ShowLinuxNotification(const std::string& title, const std::string& message); + void ShowNotification(const std::string& title, const std::string& message, NotifyAction notify= NotifyAction::Notify_INFO); #endif private: void CreateMenu(); diff --git a/app/src/CLIProcess.cpp b/app/src/CLIProcess.cpp index 90abb12..def8da0 100644 --- a/app/src/CLIProcess.cpp +++ b/app/src/CLIProcess.cpp @@ -503,7 +503,6 @@ void CLIProcess::Start(const std::string& command) { if (result) { AddLog("进程已启动: " + command + " PID: " + std::to_string(pi_.dwProcessId)); - CloseHandle(hWritePipe_); CloseHandle(hReadPipe_stdin_); hWritePipe_ = nullptr; diff --git a/app/src/Manager.cpp b/app/src/Manager.cpp index 5852bf4..4728f2c 100644 --- a/app/src/Manager.cpp +++ b/app/src/Manager.cpp @@ -6,6 +6,7 @@ #include "imgui_internal.h" +#include "resource.h" #include "Units.h" Manager::Manager() = default; @@ -126,6 +127,7 @@ bool Manager::Initialize() { m_app_state.cli_process.Start(m_app_state.command_input); m_app_state.show_main_window = false; HideMainWindow(); + m_tray->ShowNotification(L"CLI自启动",StringToWide(m_app_state.command_input) + L"\n当前状态:" + (m_app_state.cli_process.IsRunning() ? L"运行中" : L"已停止")); } m_tray->UpdateStatus(m_app_state.cli_process.IsRunning() ? L"运行中" : L"已停止", m_app_state.cli_process.GetPid()); m_initialized = true; @@ -487,9 +489,11 @@ void Manager::RenderStatusMessages() { } ImGui::End(); + m_save_success_timer -= ImGui::GetIO().DeltaTime; if (m_save_success_timer <= 0.0f) { m_show_save_success = false; + m_tray->ShowNotification(L"CLI_Manager",L"当前布局保存成功!"); } } @@ -503,13 +507,14 @@ void Manager::RenderStatusMessages() { ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "布局已加载"); + } ImGui::End(); m_load_success_timer -= ImGui::GetIO().DeltaTime; if (m_load_success_timer <= 0.0f) { m_show_load_success = false; + ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "布局已加载"); } } @@ -529,6 +534,7 @@ void Manager::RenderStatusMessages() { m_theme_save_success_timer -= ImGui::GetIO().DeltaTime; if (m_theme_save_success_timer <= 0.0f) { m_show_theme_save_success = false; + m_tray->ShowNotification(L"CLI_Manager",L"当前主题保存成功!"); } } @@ -836,6 +842,7 @@ void Manager::RenderControlPanel(float buttonWidth, float buttonHeight, float in m_app_state.AddCommandToHistory(m_app_state.command_input); m_tray->UpdateStatus(m_app_state.cli_process.IsRunning() ? L"运行中" : L"已停止", m_app_state.cli_process.GetPid()); + m_tray->ShowNotification(L"CLI_Manager",m_app_state.cli_process.IsRunning() ? L"重启成功!" : L"重启失败!"); } } @@ -868,7 +875,7 @@ void Manager::RenderCommandPanel(float buttonWidth, float inputWidth) { // 显示发送状态 if (!m_app_state.cli_process.IsRunning()) { - ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "提示: 程序未运行,无法发送命令"); + ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 0.6f), "提示: 程序未运行,无法发送命令"); } } @@ -1096,7 +1103,12 @@ bool Manager::InitializeTray() { return false; } - HICON trayIcon = LoadIcon(NULL, IDI_APPLICATION); + // 加载自定义图标 + HICON trayIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1)); + if (!trayIcon) { + // 如果加载失败,使用默认图标 + trayIcon = LoadIcon(NULL, IDI_APPLICATION); + } m_tray = std::make_unique(m_tray_hwnd, trayIcon); // 设置托盘窗口的用户数据,指向TrayIcon实例 diff --git a/app/src/TrayIcon.cpp b/app/src/TrayIcon.cpp index 9202d24..2275113 100644 --- a/app/src/TrayIcon.cpp +++ b/app/src/TrayIcon.cpp @@ -77,16 +77,16 @@ void TrayIcon::SetExitCallback(const ExitCallback &callback) { } #ifdef _WIN32 -void TrayIcon::ShowWindowsNotification(const std::wstring &title, const std::wstring &message) { +void TrayIcon::ShowNotification(const std::wstring &title, const std::wstring &message, NotifyAction notify) const { NOTIFYICONDATA nid = m_nid; nid.uFlags |= NIF_INFO; wcsncpy_s(nid.szInfoTitle, title.c_str(), _TRUNCATE); wcsncpy_s(nid.szInfo, message.c_str(), _TRUNCATE); - nid.dwInfoFlags = NIIF_INFO; // 信息图标,可选 NIIF_WARNING, NIIF_ERROR + nid.dwInfoFlags = static_cast(notify); // 信息图标,可选 NIIF_WARNING, NIIF_ERROR Shell_NotifyIcon(NIM_MODIFY, &nid); } #elif __APPLE__ -void TrayIcon::ShowMacNotification(const std::string &title, const std::string &message) +void TrayIcon::ShowNotification(const std::string &title, const std::string &message) { // 通过 AppleScript 或 Objective-C 桥接 std::string script = "display notification \"" + message + "\" with title \"" + title + "\""; @@ -94,7 +94,7 @@ void TrayIcon::ShowMacNotification(const std::string &title, const std::string & system(cmd.c_str()); } #else -void TrayIcon::ShowLinuxNotification(const std::string &title, const std::string &message) +void TrayIcon::ShowNotification(const std::string &title, const std::string &message) { // 使用 notify-send 命令 std::string cmd = "notify-send \"" + title + "\" \"" + message + "\""; diff --git a/logo.ico b/logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..363af4c196968c30f07bad94fd3bd35e4aa58e1a GIT binary patch literal 15406 zcmeHOd7MsV`#;Y)&oi5uF~cmFF~*GXiZJ$UMH`|>i#=PGC}Qke2q_YhtsV7NC@E?4 zz9OZPq{S9xm!+s==A84)_xHW-bIvo5sg&w{|M|Vo=W{z}&biNZUH7%$*LBl0pJr$Y z2^z1NT7SQ$)z>sFGt>FIN}{Gc!DqR-?)%D`_Fl54RpA_d!Y`cXy!_E$P0cXoYr4Ku z(~W#*_;;#jnpX1yK%zN!5$6Rp!w+6@eI*^8tLn&3)Yad7&Uc)nY0<^tMDzJOv5`7T zMRTrhAU)oP{F(J(E$fOGdRBpt@Z@<(dC$4$!O)Gx)sl7W?B&Pt!SPtr-iLFe5@D^p z3-(w8*2}}Nzkd`~wI5gf<)V>Ij;pkdZE8b&wL z@KhTOKMdpZu^i(A`0R-xi14d*%-8+;u1=Te*xb7`?B{x@IWw;GAv(g3n5aku0s;7R z9U0`u?!NqfQY`j8+8g&a_8}@l-&L!OufST=3f61m2s;YvyJ)gDluIs!e!aS*dE*AC zSF;+*lup3tT7qALz2qj?&-X#2%$S14>HPkMeh7}_JFazN6AgynkF2y*OdLBJ-8$Zk zmRDYmq=a~^ZpJyXzR?1sBN}GM7sN&ByOvJqj^j)EsC9qST|?zkQRsAYJ4~549%D!3 zVf3(}7*{iZU_X9K9_(8(7$bYNRrFJq5Mn&_=N5HCA&JjdyeY9UPQHQ0_^yqI-57OufB@ z=n&c7a`w^ z9(zBfzbPdnQ6kbnL_o)+zHMPH?Evf5QD{^-Ny$XksYY@Ab)dNR<1ZBZ2?Pw(%uGP# zvaz1+K=aGHz^~blM~7UgleAwyZB{o5cweCIR#}A!<)}<{e5IPA<(<=QQQulo=ek1bqY@%q53a)`jzYpJu{SKksa|DNS z(3b0@ivJF$RqjLMIN|@Eo>$`h6CUoGDLPtYlE*$37Zg2);Zt$K9+v@Y*V{06{|nY< zt6^`NkFkxS9RKavGp`ck(&AnF*14|V=7Y%lbHOcseMns$`GcHwy-NOGo#DeHSL^t; zzfY~(S~C&W)3?GNK^}}R0ejUD)gHV@x1j^uvYsa4>cS$NL$Bd%^zvB}XogwTJawKUjM=63+YNRcD;)NBkm7 z!!U_HCq#k~c+9ae18K27Sc}@i-n#+zv`iKMtVb9_C|`RXujIFi*IcvY0BQ(+$p<8k zbJ$au7p$Acyde+v=t$UOVqkB75$4K4NRCnXNds{@zj)0baC{4O*Kg=Jy!IjHH=Pj_ zToP9WuEZ(13NCpjJm<6Tsrx_6yipu7$D1!P%A3!3=FD0+``Iff6YKg6@n_;E4WkqB zlOEct*be!#`qp^z>;u?S(;RpnPQpAvnNDx!LxXY}qG*STpZq2>!G}IIG;HfZ-4R-d z+vATtnK{(g@1a-YG>`udKJnF#Z*_6&$feEM)HjQ?+H>nUa0EYLF1^8r#3<%5B11Ji zyK=95rgMyH;Db$lRdHJQG`BYFFIHm;bEBL@&I$P``e62ts*!PP!|a+^=ti?y&d z?DrNb*(=>5Zppm_r`TqxlCelBRT7DDB@i1Eji|^77~*FXP0qZ$dJZ2{o=CpgpRa;F zy{fX^Z>fipw{h(s5&wznvZ(X47n{7bhDB3<*OB+MBat7!-O$BZm)LJyiD*>XnmxA)CrB!|?eE3OxBzY$^sNC+OC9r4Jfju+=w^b#6;?{JZ zJ+eM^{@L4Mezk$P-=y9SabzgE#Qg8tOf^^e56Ks^(#qiW?p?8O?_Ol2B;wg+OEGlN zKt)q_dKr`U>1-H|+S^}rrukOumzf6st@4?-8db4y-dtoPCt&!HL1=wVbA>;P_~R&(YUFRQ3*iWU zPk+Te#D{(GB*x!(iO9<$4^H;1#`PcC220|I^aX;_pc~?)nu>!nTJ}H}|}Q-VNdfzr>o4 zs!`|jcf3jeHW%j89q2EUlr4L@bHB(+^HJyGk$XuF&Yt}V9d5iHM-CrGpB`N?bNV!_ zd+SX_TS{U)`cxwBPQ-mDhsaQDV0K;V;A)tRSzDJ)Kt@Tz^eO!l8$i_*1A|&u$7>G` zfVJmejvTyiyK3m4r6D~z(a|^ZAhS$qyz=rY%z1DI?&#eE-+p^c>B86=^miSJQ}S|e z?OeC@#Tra$myIOxe_|)%YYd%v75$GFqe(}J2p>*;xDxjLRg@eQ4=4lsW(^A(M4)BG zIHV^fAcJ~dHLE->shEySD`jFppB|`^8jl~iM<^7zOS}@F%r#hZ8sX@Mrx8ck3a`Sg za+6Mu52P=YXT*P1dB)7?bzyCL!STObgRDdBv#>L-T-%A8G`w?-53e-S@#>X+ENU2m z>2)HptrhK9<_vbeQTRpXjAL5|(DzY>VfY>YD>1+bJnrGYpFYaErxGlFqijKVDEccy z^jB8 z)^Cd~iam%fkOoDI@Izvb_*gIY2%W-jc_(X@=Ryl*XU=Vkf}L+5rGzK_P+SM=x+Jg$DKD`~Vwa{l5Lu(q#+wexkD z57kG(bA9mLwl!#*%e|K9ovdH?&+rx=c9s0=Gtq%^aXQ{vIFz}=2J&J9R@`?x)-4mMD1t_{ngC-~;9l3|8-7a|0*lf1zqE*S;$6&f;MaYK>nF~$%QJM;E2pD6bMbW6YYgtgi{hTQmh-NZ2XP6` zzy4z@$LP&*jDxjY(&u+*RQE-EbLGKzjPw0!>Nv{1m1A@zUa<<3irIKekZx4 z?7!s7T>JSpKEy|Q`C|CD&iBP|{iJBnw8)DTg^%CeO<1Qw@KnCz=1*Sk_)I=;M} z&j~nvxA2_Or8~2vj;__DFDE!cwj#8MF8$umr|ib?i|$b$9DZk)(kXWxrqmm$7YA-< zp2wPDN{ogaz8hHEz=xgrUUY`To>C3g;ZI>r$x{1zYYg|E_ol*J(HA!Bvi9g?oE@lP z#q~P(jXso()sV&h3p}jbg!lT7m949X4jT` z?hjd~QT1rT71%;!0r%kRxhMU)uUnH69hbp9qPb!y>`zy~9#^uccE^2;JuQdz2(D`~ z*ClHuEQ{C8g#SS&)~Mu}z;JQw>Y<^1j?b%;6mnm`mI6rnO(E$1p^lF<)Vlky?|Dpm za4tOS-fYr#2Wz<%o!YP9lDdqtQSPy3)Pl8U0_>CfSSuRJeI9wqeNbrsHz^gtecU^3 zc?Ra9mavA$gw~QC{sU#C{754E zzS6%{v=gTF7<-tcD|liz>|>vE-`I)u*A%WL3+8g}Be}0G{Qdxf`#*s7`go_-LY@ol zihi}HWDWAE>tOF%i^A`|hDA8$8qS@ZL!C;3HMJ)9=V$MBe0`8^_X=p zFZ}z3+o|85uwJwt7VD?> zR`T!d^Ru z{Q8Qx2H@O~XvDa+F7jCTD>Z7KBJh3z_GbJCL-k_PFEMmp3-$@Nvj-yZA8E?HvESJr zOU;jaV{>Uo*bmia{U9z>pYUjvdV;#=Rrc|!z996wdwccw7|M47`v|k>Tc4pkr&n@t zNPS^+1gxjpQ{H>H*YBm`x5Iz&E2LE;&CXA!&J0(3GR1%K<*X^vcE`72z2*2G>inJ5 zbJlPKu2)}>+K1E}r1m1ugihhJOSjNzb51_z@=E3^4(W*EGwHKbOVTj=DjjFUUy4j!zALyc z{noq&2%h>H>t=LEdP(wB)#$?LH~fdVeb1sTv~qlo*hLZVV~Fcf(j&Qm`D7;q53p`` zZ&`&aq}P=B&#cpI=;kBc^l{=NB&PmKTvhQfv>vXFbFN@7?-S-qHeo1vh%8;XTCWaO z@%rPz6;Lx-L&-?i%asj_{=38PZ%O`4_5K#0c^PwEIbSlhi4TYRu;w@^oBnbK&$#rZ zj`~qZT@m_4Uwg)r6#{ps-rwvmsA8L!UVMY<&>QNHHp zr(jEOa4dZc;VatZO8pdlj#af^!Xxd{Ly7OV$ zg=D3xHEd?SAUsj&$WlEZ=|7~f zKf}Rmg)+(NyiWrARI(QkT^e7X^ok6`jy)TmmdSi$EBl+5)27+0W6d>qw-2+g6n-f^ z-O1}|q5tVtlwn>3%o+7yF6qiVU>y4jufaaRxHT%mk*)X{^5qoeBD$+!@LTylnrD}! zcO|2GMB3PS%CFdKe1N9Kjc}+PQlmr%x6i zrE_mbUEjC}1+4iN1`Y-a7xZ>KZ=%&P>sk9@5`MyKH$X|DQh18Gi@}!M)wYl~x z+;n{_)kkYst2$OLe;%Xq?xyY}h3J>QVg%0}Mbob=u0{RtMO=ih=y&Z{{VhJ0KFXSy zhQgD3v28|cbykD;+2_;0mmGT|dxGZH<*?qEM1MwD5?_RN!c#Go@)W%+;PavEOFFva z#JL#u-=x2$beuF*&&k58t6#>!LxXVt3TA8RQ5%sf0&a|4*$q3uh#MC!uhI?*sgU8)z3Y!e?Ru@-i>NG znaajxy@|1`Z_^LW=a~@uR?^5ljiOa(7yS{sh4<70=`R*6x*mmRPvNnf*@t!PSL%Fg zg#KPN*lYZJ4a`rTN5P!NFeg{!9=0^)K))n%@caV#vA?5++>%bLGFXogpP9|x>->l3 zAQ%i{`qX2 z;VasO?>r-6J=&Uj{V?-_k~(X76LX*D2J^gF@ftto*N?#6 zmqy~2O3^$Y7Q?euF=}lM%f}-pwIni<;>pW6++RBq!459%eF#HrROlDpP(N+<@MLdy z?Dg5WHk&!I*lLJ&kACL-LOV}rsr`#OC*{%4^JNJ-_An643in@zt(g$QqQMu%}$Kf8i3`{iByZbN*Esv@6DQYXtY`+=JOG2ZV5`cqaVf zP5zFIeR6f@hWs$!%iblF ztI$VC+_XlZ-O513Eh!ZRq#d3IzIOsQ27zxh1RXw9k(Ypkrr<+xP7$NNhra@<248%Z~F-W{*w(8gsL)w+_iHxl3D&@MfJ3)c^&M(y-kjyZ8a z=f2a2!7VG{^heJjD0`V>JF#u?0CZ@Wfzdbo1G}FbhypoRbmkC(tP`29jSAU`?a4y) z?#Xt{9a)d!oUbH(4!t3XhgXGFrSB}PlUbz_9D4w}DWh(nW4mopt1$#u(+myu@OGd)}=_Jg1N{4Jk zY{nkJ`t!a`IJ9md`qT~}NowQrz4Gg!TqXoF^xWY)`S1Uu^>c@Qk%QBFIjLml#$*N8 z$@@aNzvO;$c0=CvY>4}OV!+RM4Ii8x0)$>%kHK}*VRKc4Ja)!8?=drs$D&$qkl zQ1C*2QgnxX&0_quaX*e)pcd zYmmmhM2}1HME`ntyiZ*<=69=(tFj{<+C%#6!ER@bH77YG#c{wVSGBq0~-S9o+@ z`0DpJAuQHe2GpjqAu#K@Id<4 zLr6bkTo_)t7rqsLCbWih!IP0UFYKL~qv#geSqoAAU3x5ko$tTCM8;`#?&lzBmjB05 zMCWgi