Home > Back-end >  How to add tray icon in a C console program?
How to add tray icon in a C console program?

Time:06-03

I am developing a console program and I have planned to add a tray icon for it. But it seems that only Win32 GUI program can do something caused by messages. (WndProc())

My message checking loop code snippet: (Independent sub thread)

void WCH_message_loop() {
    // Message loop.
    MSG msg;
    GetMessageW(&msg, nullptr, 0, 0);
    Myn = new MyNotify(msg.hwnd);
    MyC = new CTrayIcon();
    MyC -> CreateTray(msg.hwnd, LoadIconW(NULL, IDI_ERROR), WCH_IDM_OPENPIC, L"Web Class Helper");
    constexpr int ShowHide = 121;
    constexpr int PrintScreen = 122;
    RegisterHotKey(NULL, ShowHide, MOD_CONTROL, 'P');
    RegisterHotKey(NULL, PrintScreen, MOD_CONTROL, VK_DOWN); // Register "Ctrl   Down" hotkey.
    while (GetMessage(&msg, nullptr, 0, 0)) {
        if (msg.message == WM_HOTKEY) {
            switch (msg.wParam) {
                case ShowHide:
                    WCH_SetWindowStatus(!WCH_cmd_line);
                    break;
                case PrintScreen:
                    cout << endl;
                    WCH_command_list.clear();
                    WCH_command_list = WCH_split("pi");
                    WCH_pi();
                    MyC -> ChangeTray(L"Successfully printed screen");
                    break;
                default:
                    break;
            }
        }
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
}

WndProc() function: (How could I bind it to something or make it take effect?)

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    #ifdef _DEBUG
    WCH_printlog(WCH_LOG_STATUS_DEBUG, "Starting \"WndProc()\"");
    #endif
    switch (message) {
        case 1025:
            switch (lParam) {
                case WM_LBUTTONDOWN:
                    WCH_SetWindowStatus(true);
                    break;
                case WM_RBUTTONDOWN:
                    WCH_SetTrayIconMenu(hWnd);
                    break;
            }
            break;
        case WM_COMMAND:
            switch (LOWORD(wParam)) {
                case WCH_IDM_SHOWHIDE:
                    WCH_SetWindowStatus(!WCH_cmd_line);
                    break;
                case WCH_IDM_EXIT:
                    exit(0);
                    break;
                default:
                    return DefWindowProcW(hWnd, message, wParam, lParam);
                    break;
            }
        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
            break;
        }
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProcW(hWnd, message, wParam, lParam);
    }
    return 0;
}

Dependent code snippet:

class CTrayIcon {
public:
    CTrayIcon() {};
    ~CTrayIcon() {};
    BOOL CreateTray(HWND, HICON, UINT, LPCTSTR = L"Web Class Helper");
    BOOL ChangeTray(LPCTSTR, LPCTSTR = L"Web Class Helper", UINT = 3000);
    BOOL DeleteTray();
private:
    NOTIFYICONDATA m_Notify;
};

struct MyNotify {
    MyNotify(HWND hWND, WCHAR* Path = (WCHAR*)L"WCHs.ico", WCHAR* Title = (WCHAR*)L"Web Class Helper", UINT uID = 1) {
        NOTIFYICONDATA nID = {};
        nID.hIcon = (HICON)LoadImageW(NULL, Path, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
        wcscpy_s(nID.szTip, Title);
        nID.hWnd = hWND;
        nID.uID = uID;
        nID.uFlags = NIF_GUID | NIF_ICON | NIF_MESSAGE | NIF_TIP;
        nID.uCallbackMessage = 1025;
        Shell_NotifyIconW(NIM_ADD, &nID);
    }
};

ATOM WCH_RegisterClass(HINSTANCE hInstance, WCHAR* szWindowClass) {
    #ifdef _DEBUG
    WCH_printlog(WCH_LOG_STATUS_DEBUG, "Registering class");
    #endif
    WNDCLASSEXW wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_WCH));
    wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW   1);
    wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WCH);
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIconW(wcex.hInstance, MAKEINTRESOURCEW(IDI_SMALL));
    return RegisterClassExW(&wcex);
}

How could I solve this problem? Thanks!

Now I don't know why does WndProc() do not work. (Maybe just in GUI program?)

But I don't want to convert it to GUI program.

  • Related