c++在按下关闭键时:最小化系统托盘并继续运行



我有一个用于windows的c++应用程序,当用户按下关闭按钮时,应该最小化命令行窗口。它不应该再出现在任务栏中,而应该在系统托盘中有一个图标。我的意思是:当用户按下关闭按钮时,程序只应该"隐藏"。就像我说的。

我只能设法使程序在运行时在托盘中有一个图标,但不能使它在按下x时保持运行

谢谢你的帮助!

这是我到目前为止的代码:

#include <iostream>
#include <Windows.h> // needed for console window and system tray functionality
// global variables
NOTIFYICONDATA trayIcon; // structure for the tray icon
HWND hwnd = GetConsoleWindow(); // handle to the console window
// function prototypes
void minimizeToTray(); // function to minimize the console window to the system tray
int main()
{
// set up the tray icon
trayIcon.cbSize = sizeof(NOTIFYICONDATA);
trayIcon.hWnd = hwnd;
trayIcon.uID = 1;
trayIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
trayIcon.hIcon = (HICON)LoadImage(NULL, "icon.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE); // specify the icon file
trayIcon.uCallbackMessage = WM_USER + 1; // message identifier for tray icon clicks
trayIcon.uVersion = NOTIFYICON_VERSION_4;
strcpy_s(trayIcon.szTip, "Program Running");
// add the tray icon to the system tray
Shell_NotifyIcon(NIM_ADD, &trayIcon);
std::cout << "Program running..." << std::endl;
// set up a message loop to handle tray icon clicks and window messages
MSG msg;
while (true) // infinite loop
{
// check for messages
while (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE))
{
// if the user clicks the close button, minimize the window to the tray
if (msg.message == WM_CLOSE)
{
minimizeToTray();
continue; // skip the rest of the message loop
}
// if the user clicks the tray icon, restore the window
if (msg.message == WM_USER + 1)
{
ShowWindow(hwnd, SW_RESTORE);
}
// pass the message to the default window procedure
DispatchMessage(&msg);
}
// do other tasks here
}
// remove the tray icon before exiting the program
Shell_NotifyIcon(NIM_DELETE, &trayIcon);
return 0;
}
// function to minimize the console window to the system tray
void minimizeToTray()
{
// hide the console window
ShowWindow(hwnd, SW_HIDE);
// update the tray icon
trayIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
Shell_NotifyIcon(NIM_MODIFY, &trayIcon);
}

当用户"关闭"时窗口应该隐藏而不是完全关闭,就像ms teams或discord那样

测试代码后,它肯定失败了。它无法获得消息WM_CLOSE。正如汉斯·帕桑特所说,您可以使用SetConsoleCtrlHandler()连接到控制台接收信号。

这是我的代码。它运行良好。采用ShellExecuteW()API重新启动程序,实现最小化。设置SW_MINIMIZE,它将在任务栏中最小化。设置SW_HIDE,它将在系统托盘中最小化。但是它不能再打开了。
#include <Windows.h> 
#include <string.h>     
#include <stdlib.h>     
#include <stdio.h>      
#include <errno.h>      
#include <iostream>

NOTIFYICONDATA trayIcon; 
HWND hwnd = GetConsoleWindow(); 
BOOL WINAPI ConsoleHandler(DWORD CEvent)
{
char mesg[128];
switch (CEvent)
{
case CTRL_C_EVENT:
MessageBox(NULL,
L"CTRL+C received!", L"CEvent", MB_OK);
break;
case CTRL_BREAK_EVENT:
MessageBox(NULL,
L"CTRL+BREAK received!", L"CEvent", MB_OK);
break;
case CTRL_CLOSE_EVENT:

ShellExecuteW(NULL, L"open", L"yourexe.exe", NULL, NULL, SW_MINIMIZE);
break;
case CTRL_LOGOFF_EVENT:
MessageBox(NULL,
L"User is logging off!", L"CEvent", MB_OK);
break;
case CTRL_SHUTDOWN_EVENT:
MessageBox(NULL,
L"User is logging off!", L"CEvent", MB_OK);
break;
}
return TRUE;
}
int main()
{
trayIcon.cbSize = sizeof(NOTIFYICONDATA);
trayIcon.hWnd = hwnd;
trayIcon.uID = 1;
trayIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
trayIcon.hIcon = (HICON)LoadImage(NULL, L"icon1.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE); 
trayIcon.uCallbackMessage = WM_USER + 1; 
trayIcon.uVersion = NOTIFYICON_VERSION_4;

Shell_NotifyIcon(NIM_ADD, &trayIcon);
std::cout << "Program running..." << std::endl;

MSG msg;
if (SetConsoleCtrlHandler(
(PHANDLER_ROUTINE)ConsoleHandler, TRUE) == FALSE)
{

printf("Unable to install handler!n");
return -1;
}
while (true) 
{

while (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE))
{

if (msg.message == WM_CLOSE)
{          
continue; 
}

if (msg.message == WM_USER + 1)
{
ShowWindow(hwnd, SW_RESTORE);
}

DispatchMessage(&msg);
}       

}

Shell_NotifyIcon(NIM_DELETE, &trayIcon);
return 0;
}

最新更新