Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Dynamic Libraries (Windows)
#44
This program hides the program icon in the Windows tray on the right (to system items) and also allows you to call it.

Program use Tray.H file

Tray.H:

Code: (Select All)
#ifndef QB64_TRAY_H
#define QB64_TRAY_H

#ifdef _WIN32

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <stdint.h>
#include <string.h>

/* --- runtime link na Shell_NotifyIconA (žádné linkování navíc) --- */
static HMODULE qb64_tray_shell32 = NULL;
typedef BOOL (WINAPI *qb64_Shell_NotifyIconA_t)(DWORD, PNOTIFYICONDATAA);
static qb64_Shell_NotifyIconA_t qb64_Shell_NotifyIconA_p = NULL;

static NOTIFYICONDATAA qb64_tray_nid;
static int  qb64_tray_icon_added = 0;
static HWND  qb64_tray_hwnd = NULL;
static WNDPROC qb64_tray_oldproc = NULL;
static UINT  qb64_tray_cbmsg = (WM_APP + 0x4B64); /* libovolné "unikátní" číslo */

static void qb64_tray_load_shell_notifyicon(void) {
    if (qb64_Shell_NotifyIconA_p) return;
    qb64_tray_shell32 = LoadLibraryA("shell32.dll");
    if (!qb64_tray_shell32) return;
    qb64_Shell_NotifyIconA_p = (qb64_Shell_NotifyIconA_t)GetProcAddress(qb64_tray_shell32, "Shell_NotifyIconA");
}

static HICON qb64_tray_get_window_icon(HWND hwnd) {
    HICON h = (HICON)SendMessageA(hwnd, WM_GETICON, ICON_SMALL, 0);
    if (!h) h = (HICON)(uintptr_t)GetClassLongPtrA(hwnd, GCLP_HICONSM);
    if (!h) h = (HICON)SendMessageA(hwnd, WM_GETICON, ICON_BIG, 0);
    if (!h) h = (HICON)(uintptr_t)GetClassLongPtrA(hwnd, GCLP_HICON);
    if (!h) h = LoadIconA(NULL, IDI_APPLICATION);
    return h;
}

static void qb64_tray_fill_nid(const char* tip) {
    ZeroMemory(&qb64_tray_nid, sizeof(qb64_tray_nid));
    qb64_tray_nid.cbSize = sizeof(qb64_tray_nid); /* doporučený postup */
    qb64_tray_nid.hWnd = qb64_tray_hwnd;
    qb64_tray_nid.uID  = 1;
    qb64_tray_nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
    qb64_tray_nid.uCallbackMessage = qb64_tray_cbmsg;
    qb64_tray_nid.hIcon = qb64_tray_get_window_icon(qb64_tray_hwnd);

    if (tip && tip[0]) {
        strncpy(qb64_tray_nid.szTip, tip, sizeof(qb64_tray_nid.szTip) - 1);
        qb64_tray_nid.szTip[sizeof(qb64_tray_nid.szTip) - 1] = '\0';
    } else {
        qb64_tray_nid.szTip[0] = '\0';
    }
}

static void qb64_tray_add_icon(void) {
    qb64_tray_load_shell_notifyicon();
    if (!qb64_Shell_NotifyIconA_p || !qb64_tray_hwnd) return;

    if (!qb64_tray_icon_added) {
        qb64_Shell_NotifyIconA_p(NIM_ADD, &qb64_tray_nid);
        qb64_tray_icon_added = 1;
    } else {
        qb64_Shell_NotifyIconA_p(NIM_MODIFY, &qb64_tray_nid);
    }
}

static void qb64_tray_delete_icon(void) {
    qb64_tray_load_shell_notifyicon();
    if (!qb64_Shell_NotifyIconA_p || !qb64_tray_hwnd) return;

    if (qb64_tray_icon_added) {
        qb64_Shell_NotifyIconA_p(NIM_DELETE, &qb64_tray_nid);
        qb64_tray_icon_added = 0;
    }
}

static void qb64_tray_restore_window(void) {
    if (!qb64_tray_hwnd) return;
    qb64_tray_delete_icon();
    ShowWindow(qb64_tray_hwnd, SW_RESTORE);
    SetForegroundWindow(qb64_tray_hwnd);
}

static void qb64_tray_hide_window(void) {
    if (!qb64_tray_hwnd) return;
    qb64_tray_add_icon();
    ShowWindow(qb64_tray_hwnd, SW_HIDE);
}

static LRESULT CALLBACK qb64_tray_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    if (msg == WM_SYSCOMMAND) {
        UINT cmd = (UINT)(wParam & 0xFFF0);
        if (cmd == SC_MINIMIZE) {
            qb64_tray_hide_window();
            return 0;
        }
    }

    if (msg == qb64_tray_cbmsg) {
        if (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONUP) {
            qb64_tray_restore_window();
            return 0;
        }
    }

    if (msg == WM_DESTROY) {
        qb64_tray_delete_icon();
    }

    return CallWindowProcA(qb64_tray_oldproc, hwnd, msg, wParam, lParam);
}

/* --- API pro QB64PE --- */
extern "C" int Tray_Enable(uintptr_t hwnd, const char* tip) {
    if (!hwnd) return 0;
    qb64_tray_hwnd = (HWND)hwnd;

    if (!qb64_tray_oldproc) {
        qb64_tray_oldproc = (WNDPROC)(uintptr_t)GetWindowLongPtrA(qb64_tray_hwnd, GWLP_WNDPROC);
        SetLastError(0);
        LONG_PTR prev = SetWindowLongPtrA(qb64_tray_hwnd, GWLP_WNDPROC, (LONG_PTR)qb64_tray_wndproc);
        if (prev == 0 && GetLastError() != 0) {
            qb64_tray_oldproc = NULL;
            return 0;
        }
    }

    qb64_tray_fill_nid(tip);
    return 1;
}

extern "C" void Tray_Disable(void) {
    if (!qb64_tray_hwnd) return;

    qb64_tray_delete_icon();

    if (qb64_tray_oldproc) {
        SetWindowLongPtrA(qb64_tray_hwnd, GWLP_WNDPROC, (LONG_PTR)qb64_tray_oldproc);
        qb64_tray_oldproc = NULL;
    }
}

extern "C" void Tray_Hide(void) { qb64_tray_hide_window(); }
extern "C" void Tray_Show(void) { qb64_tray_restore_window(); }

extern "C" void Tray_SetTip(const char* tip) {
    qb64_tray_fill_nid(tip);
    if (qb64_tray_icon_added) qb64_tray_add_icon(); /* MOD */
}

#else
/* Non-Windows: prázdné stuby */
extern "C" int  Tray_Enable(unsigned long long, const char*) { return 0; }
extern "C" void Tray_Disable(void) {}
extern "C" void Tray_Hide(void) {}
extern "C" void Tray_Show(void) {}
extern "C" void Tray_SetTip(const char*) {}
#endif

#endif


Tray.bas:

Code: (Select All)

Option _Explicit

Declare Library "tray"
    Function Tray_Enable% (ByVal hwnd As _Offset, tip As String)
    Sub Tray_Disable
    Sub Tray_Hide
    Sub Tray_Show
    Sub Tray_SetTip (tip As String)
End Declare

_Title "QB64PE Tray Demo"
Screen _NewImage(640, 240, 32)

Dim ok%
ok% = Tray_Enable(_WindowHandle, "My Apllication" + Chr$(0))
If ok% = 0 Then Print "Tray_Enable fail."

Print "H = Hide to tray, S = show, ESC = end"
Dim k$
Do
    k$ = UCase$(InKey$)
    If k$ = "H" Then Tray_Hide
    If k$ = "S" Then Tray_Show
    If k$ = Chr$(27) Then Exit Do
    _Limit 60
Loop

Tray_Disable
System


Reply


Messages In This Thread
Dynamic Libraries (Windows) - by Petr - 12-08-2025, 06:48 PM
RE: Dynamic Libraries - by Petr - 12-08-2025, 07:12 PM
RE: Dynamic Libraries - by Petr - 12-08-2025, 07:52 PM
RE: Dynamic Libraries - by Jack - 12-08-2025, 08:41 PM
RE: Dynamic Libraries - by Petr - 12-09-2025, 07:21 PM
RE: Dynamic Libraries - by Petr - 12-11-2025, 04:19 PM
RE: Dynamic Libraries - by Petr - 12-12-2025, 10:00 PM
RE: Dynamic Libraries - by Petr - 12-13-2025, 05:56 PM
RE: Dynamic Libraries - by 2112 - 12-13-2025, 07:06 PM
RE: Dynamic Libraries - by ahenry3068 - 12-13-2025, 07:47 PM
RE: Dynamic Libraries - by Petr - 12-13-2025, 07:41 PM
RE: Dynamic Libraries - by 2112 - 12-13-2025, 08:23 PM
RE: Dynamic Libraries - by Petr - 12-13-2025, 08:36 PM
RE: Dynamic Libraries - by Petr - 12-13-2025, 09:03 PM
RE: Dynamic Libraries - by ahenry3068 - 12-13-2025, 11:16 PM
RE: Dynamic Libraries - by Petr - 12-14-2025, 12:15 AM
RE: Dynamic Libraries - by Petr - 12-15-2025, 08:22 AM
RE: Dynamic Libraries (Windows) - by Petr - 12-15-2025, 06:30 PM
RE: Dynamic Libraries (Windows) - by Mad Axeman - 12-19-2025, 02:37 PM
RE: Dynamic Libraries (Windows) - by Pete - 12-18-2025, 07:45 PM
RE: Dynamic Libraries (Windows) - by Steffan-68 - 12-18-2025, 08:31 PM
RE: Dynamic Libraries (Windows) - by Pete - 12-18-2025, 08:55 PM
RE: Dynamic Libraries (Windows) - by Steffan-68 - 12-18-2025, 09:48 PM
RE: Dynamic Libraries (Windows) - by Petr - 12-18-2025, 09:32 PM
RE: Dynamic Libraries (Windows) - by Pete - 12-18-2025, 11:53 PM
RE: Dynamic Libraries (Windows) - by Pete - 12-19-2025, 06:40 AM
RE: Dynamic Libraries (Windows) - by Petr - 12-19-2025, 03:08 PM
RE: Dynamic Libraries (Windows) - by Petr - 12-19-2025, 10:35 PM
RE: Dynamic Libraries (Windows) - by Petr - 12-19-2025, 10:54 PM
RE: Dynamic Libraries (Windows) - by Petr - 12-19-2025, 11:20 PM
RE: Dynamic Libraries (Windows) - by Pete - 12-19-2025, 11:37 PM
RE: Dynamic Libraries (Windows) - by Petr - 12-20-2025, 10:22 PM
RE: Dynamic Libraries (Windows) - by SMcNeill - 12-20-2025, 11:03 PM
RE: Dynamic Libraries (Windows) - by Petr - 12-21-2025, 05:40 PM
RE: Dynamic Libraries (Windows) - by Petr - 12-22-2025, 08:23 PM
RE: Dynamic Libraries (Windows) - by Petr - 12-23-2025, 09:06 AM
RE: Dynamic Libraries (Windows) - by Petr - 12-24-2025, 09:54 PM
RE: Dynamic Libraries (Windows) - by Petr - 12-25-2025, 10:02 AM
RE: Dynamic Libraries (Windows) - by Petr - 12-26-2025, 11:14 PM
RE: Dynamic Libraries (Windows) - by Petr - 12-27-2025, 01:35 PM
RE: Dynamic Libraries (Windows) - by MasterGy - 12-27-2025, 07:23 PM
RE: Dynamic Libraries (Windows) - by Petr - 01-07-2026, 06:31 PM
RE: Dynamic Libraries (Windows) - by Petr - 01-07-2026, 09:13 PM
RE: Dynamic Libraries (Windows) - by Petr - 02-24-2026, 06:38 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Dynamic Libraries (Linux) Petr 19 1,155 12-29-2025, 09:52 PM
Last Post: Petr

Forum Jump:


Users browsing this thread: 1 Guest(s)