新增: 加入托盘图标、通知消息

main
机械师 2025-09-12 20:51:47 +08:00
parent 57cac6a451
commit deecdbeeab
7 changed files with 33 additions and 13 deletions

View File

@ -31,6 +31,7 @@ file(GLOB SRC
${IMGUI_DIR}/misc/cpp/*.cpp ${IMGUI_DIR}/misc/cpp/*.cpp
app/src/*.* app/src/*.*
main.cpp main.cpp
) )
@ -63,7 +64,7 @@ if(IMGUI_BACKENDS STREQUAL "win32_dx11")
endif() endif()
# generate binary # 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") if(IMGUI_BACKENDS STREQUAL "glfw_opengl")
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}

View File

@ -35,12 +35,18 @@ public:
// 设置回调函数 // 设置回调函数
void SetShowWindowCallback(const ShowWindowCallback &callback); void SetShowWindowCallback(const ShowWindowCallback &callback);
void SetExitCallback(const ExitCallback &callback); void SetExitCallback(const ExitCallback &callback);
enum class NotifyAction {
Notify_NONE,
Notify_INFO,
Notify_WARNING,
Notify_ERROR,
Notify_USER
};
#ifdef _WIN32 #ifdef _WIN32
void ShowWindowsNotification(const std::wstring& title, const std::wstring& message); void ShowNotification(const std::wstring &title, const std::wstring &message, NotifyAction notify= NotifyAction::Notify_INFO) const;
#elif __APPLE__
void ShowMacNotification(const std::string& title, const std::string& message);
#else #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 #endif
private: private:
void CreateMenu(); void CreateMenu();

View File

@ -503,7 +503,6 @@ void CLIProcess::Start(const std::string& command) {
if (result) { if (result) {
AddLog("进程已启动: " + command + " PID: " + std::to_string(pi_.dwProcessId)); AddLog("进程已启动: " + command + " PID: " + std::to_string(pi_.dwProcessId));
CloseHandle(hWritePipe_); CloseHandle(hWritePipe_);
CloseHandle(hReadPipe_stdin_); CloseHandle(hReadPipe_stdin_);
hWritePipe_ = nullptr; hWritePipe_ = nullptr;

View File

@ -6,6 +6,7 @@
#include "imgui_internal.h" #include "imgui_internal.h"
#include "resource.h"
#include "Units.h" #include "Units.h"
Manager::Manager() = default; Manager::Manager() = default;
@ -126,6 +127,7 @@ bool Manager::Initialize() {
m_app_state.cli_process.Start(m_app_state.command_input); m_app_state.cli_process.Start(m_app_state.command_input);
m_app_state.show_main_window = false; m_app_state.show_main_window = false;
HideMainWindow(); 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_tray->UpdateStatus(m_app_state.cli_process.IsRunning() ? L"运行中" : L"已停止", m_app_state.cli_process.GetPid());
m_initialized = true; m_initialized = true;
@ -487,9 +489,11 @@ void Manager::RenderStatusMessages() {
} }
ImGui::End(); ImGui::End();
m_save_success_timer -= ImGui::GetIO().DeltaTime; m_save_success_timer -= ImGui::GetIO().DeltaTime;
if (m_save_success_timer <= 0.0f) { if (m_save_success_timer <= 0.0f) {
m_show_save_success = false; m_show_save_success = false;
m_tray->ShowNotification(L"CLI_Manager",L"当前布局保存成功!");
} }
} }
@ -503,13 +507,14 @@ void Manager::RenderStatusMessages() {
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar |
ImGuiWindowFlags_AlwaysAutoResize)) { ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "布局已加载");
} }
ImGui::End(); ImGui::End();
m_load_success_timer -= ImGui::GetIO().DeltaTime; m_load_success_timer -= ImGui::GetIO().DeltaTime;
if (m_load_success_timer <= 0.0f) { if (m_load_success_timer <= 0.0f) {
m_show_load_success = false; 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; m_theme_save_success_timer -= ImGui::GetIO().DeltaTime;
if (m_theme_save_success_timer <= 0.0f) { if (m_theme_save_success_timer <= 0.0f) {
m_show_theme_save_success = false; 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_app_state.AddCommandToHistory(m_app_state.command_input);
m_tray->UpdateStatus(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_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()) { 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; 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<TrayIcon>(m_tray_hwnd, trayIcon); m_tray = std::make_unique<TrayIcon>(m_tray_hwnd, trayIcon);
// 设置托盘窗口的用户数据指向TrayIcon实例 // 设置托盘窗口的用户数据指向TrayIcon实例

View File

@ -77,16 +77,16 @@ void TrayIcon::SetExitCallback(const ExitCallback &callback) {
} }
#ifdef _WIN32 #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; NOTIFYICONDATA nid = m_nid;
nid.uFlags |= NIF_INFO; nid.uFlags |= NIF_INFO;
wcsncpy_s(nid.szInfoTitle, title.c_str(), _TRUNCATE); wcsncpy_s(nid.szInfoTitle, title.c_str(), _TRUNCATE);
wcsncpy_s(nid.szInfo, message.c_str(), _TRUNCATE); wcsncpy_s(nid.szInfo, message.c_str(), _TRUNCATE);
nid.dwInfoFlags = NIIF_INFO; // 信息图标,可选 NIIF_WARNING, NIIF_ERROR nid.dwInfoFlags = static_cast<DWORD>(notify); // 信息图标,可选 NIIF_WARNING, NIIF_ERROR
Shell_NotifyIcon(NIM_MODIFY, &nid); Shell_NotifyIcon(NIM_MODIFY, &nid);
} }
#elif __APPLE__ #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 桥接 // 通过 AppleScript 或 Objective-C 桥接
std::string script = "display notification \"" + message + "\" with title \"" + title + "\""; 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()); system(cmd.c_str());
} }
#else #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 命令 // 使用 notify-send 命令
std::string cmd = "notify-send \"" + title + "\" \"" + message + "\""; std::string cmd = "notify-send \"" + title + "\" \"" + message + "\"";

BIN
logo.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

2
logo.rc Normal file
View File

@ -0,0 +1,2 @@
#include "app/inc/resource.h"
IDI_ICON1 ICON DISCARDABLE "logo.ico"