簡體   English   中英

C++ 按下關閉時:最小化到系統托盤並繼續運行

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

我在 c++ 中有一個 windows 的應用程序,當用戶按下關閉按鈕時,它應該最小化命令行的 window。 它不應該再出現在任務欄中,並且在系統托盤中有一個圖標。 我的意思是:當用戶按下關閉按鈕時,程序應該只像我描述的那樣“隱藏”。

我只能設法讓程序在運行時在托盤中有一個圖標,但不能讓它在按下 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);
}

當用戶“關閉”window 時,它應該只是隱藏而不是完全關閉,就像 ms teams 或 discord 那樣

測試你的代碼后,它肯定失敗了。 它無法獲得消息 WM_CLOSE。 正如 Hans Passant 所說,您可以使用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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM