Home > Back-end >  How can I send a Windows Notification in Lua?
How can I send a Windows Notification in Lua?

Time:01-01

I am trying to send a Windows notification through Lua, I found a few methods to do it, but in Python, I couldn't find anything for Lua. Is there any method I can do this? And if it is, could someone tell me how? Thanks!

I tried searching for answers, but I couldn't find anything about it.

CodePudding user response:

Lua does not have such standard function, you need to use some external library.
For example, you can use FFI library to invoke Win32API functions directly.
The following script uses LuaJIT FFI:

local ffi = require'ffi'
local shell32 = ffi.load'shell32'

ffi.cdef[[
typedef int BOOL;
typedef unsigned int DWORD;
typedef unsigned int UINT;
typedef intptr_t HANDLE;
typedef intptr_t HWND;
typedef intptr_t HICON;
typedef intptr_t HINSTANCE;
typedef struct {int Data[4];} GUID;

typedef struct {
  DWORD cbSize;
  HWND  hWnd;
  UINT  uID;
  UINT  uFlags;
  UINT  uCallbackMessage;
  HICON hIcon;
  char  szTip[128];
  DWORD dwState;
  DWORD dwStateMask;
  char  szInfo[256];
  union {
    UINT uTimeout;
    UINT uVersion;
  };
  char  szInfoTitle[64];
  DWORD dwInfoFlags;
  GUID  guidItem;
  HICON hBalloonIcon;
} NOTIFYICONDATAA;

BOOL Shell_NotifyIconA(
  int dwMessage,
  NOTIFYICONDATAA * lpData
);
HICON LoadIconA(
  HINSTANCE hInstance,
  intptr_t IconCode
);
BOOL DestroyIcon(
  HICON hIcon
);
HWND GetConsoleWindow();
]]



-- icon codes:
--    32512   Your application's icon
--    32513   Error       ("X" inside red circle)
--    32514   Question    ("?" inside blue circle)
--    32515   Warning     ("!" inside yellow triangle)
--    32516   Information ("i" inside blue circle)
--    32518   Security Shield

local tray_icon_code    = 32516   -- Information
local balloon_icon_code = 32518   -- Shield

-- create tray icon
local tray_icon_handle = ffi.C.LoadIconA(0, tray_icon_code)
local balloon_icon_handle = ffi.C.LoadIconA(0, balloon_icon_code)
local notify_icon_data = ffi.new"NOTIFYICONDATAA"
notify_icon_data.cbSize = ffi.sizeof(notify_icon_data)
notify_icon_data.hWnd = ffi.C.GetConsoleWindow()  -- HWND of your application window
notify_icon_data.uFlags = 1   2  -- NIF_MESSAGE | NIF_ICON
notify_icon_data.hIcon = tray_icon_handle
notify_icon_data.uVersion = 4
notify_icon_data.hBalloonIcon = balloon_icon_handle
shell32.Shell_NotifyIconA(0, notify_icon_data)  -- NIM_ADD
shell32.Shell_NotifyIconA(4, notify_icon_data)  -- NIM_SETVERSION
print("Tray icon added.  Press Enter to continue..."); io.read()

-- show notifications
local function copy_string(dest_array_ptr, str)
    ffi.copy(dest_array_ptr, (str or ""):sub(1, ffi.sizeof(dest_array_ptr) - 1))
end

local function show_notification(text, title)
    notify_icon_data.uFlags = 1   2   16   -- NIF_MESSAGE | NIF_ICON | NIF_INFO
    notify_icon_data.dwInfoFlags = 4   32  -- NIIF_USER | NIIF_LARGE_ICON
    copy_string(notify_icon_data.szInfoTitle, title)
    copy_string(notify_icon_data.szInfo, text)
    shell32.Shell_NotifyIconA(1, notify_icon_data) -- NIM_MODIFY
end

show_notification("some text", "some title")
print("Notification displayed.  Press Enter to continue..."); io.read()

show_notification("first line\nsecond line", "another title")
print("Another notification displayed.  Press Enter to continue..."); io.read()

-- notification requests generated by show_notification() are queued,
-- each notification is kept on the screen for several seconds before next one is displayed
-- to immediately remove the notification - remove the tray icon

-- remove tray icon
shell32.Shell_NotifyIconA(2, notify_icon_data)  -- NIM_DELETE
ffi.C.DestroyIcon(balloon_icon_handle)
ffi.C.DestroyIcon(tray_icon_handle)
print("Tray icon removed.  Press Enter to exit..."); io.read()
  • Related