简体   繁体   English

C++ 按下关闭时:最小化到系统托盘并继续运行

[英]C++ when pressing close: minimize to system tray and keep running

I have an app in c++ for windows, which should minimize the window of the command line when the user presses the close button.我在 c++ 中有一个 windows 的应用程序,当用户按下关闭按钮时,它应该最小化命令行的 window。 It shouldn't be in the taskbar anymore and have an icon in the system tray.它不应该再出现在任务栏中,并且在系统托盘中有一个图标。 What I mean is: when user presses close button, the program should only "hide" like i described.我的意思是:当用户按下关闭按钮时,程序应该只像我描述的那样“隐藏”。

I can only manage to make the program have an icon in the tray while running, but can't make it stay running when x is pressed我只能设法让程序在运行时在托盘中有一个图标,但不能让它在按下 x 时保持运行

Thanks for help!感谢帮助!

this is my code so far:到目前为止,这是我的代码:

#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);
}

When the user "closes" the window it should just hide and not close entirely, like ms teams or discord do当用户“关闭”window 时,它应该只是隐藏而不是完全关闭,就像 ms teams 或 discord 那样

After testing your code, it definitely fails.测试你的代码后,它肯定失败了。 It cannot get the message WM_CLOSE.它无法获得消息 WM_CLOSE。 Just as Hans Passant said, you can use SetConsoleCtrlHandler() to attached to the console receive the signal.正如 Hans Passant 所说,您可以使用SetConsoleCtrlHandler()连接到控制台接收信号。

Here is my code.这是我的代码。 It runs well.它运行良好。 It used ShellExecuteW() API to restart the program to implement minimization.它使用ShellExecuteW() API 重启程序实现最小化。 Setting SW_MINIMIZE , it will minimize in the task bar.设置SW_MINIMIZE ,它将在任务栏中最小化。 Setting SW_HIDE , it will minimize in the system tray.设置SW_HIDE ,它将在系统托盘中最小化。 But it cannot be opened again.但无法再次打开。

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM