Notify.NET/native/WinToastWrapper/WinToastWrapper.h

206 lines
7.9 KiB
C

/**
* WinToastWrapper.h
*
* Flat C API that wraps WinToastLib (https://github.com/mohabouje/WinToast).
* This header is the sole interface between the managed P/Invoke layer and
* the C++ WinToastLib implementation.
*
* ABI contract (must stay in sync with WinToastNative.cs):
* - All strings are wchar_t* (UTF-16LE, null-terminated).
* - Callbacks are called on a WinRT thread-pool thread, NOT the calling STA thread.
* - WNT_ShowToast must be called from the STA thread that called WNT_Initialize.
* - WNT_HideToast must be called from the same STA thread.
*/
#pragma once
#include <Windows.h>
#ifdef WINTOASTWRAPPER_EXPORTS
#define NOTIFYAPI __declspec(dllexport)
#else
#define NOTIFYAPI __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------------
* Callback function pointer types
* ------------------------------------------------------------------------- */
/** Called when the user clicks the notification body (no button). */
typedef void (CALLBACK* WNT_ActivatedCallback)(INT64 toastId);
/** Called when the user clicks one of the action buttons. */
typedef void (CALLBACK* WNT_ButtonActivatedCallback)(INT64 toastId, int buttonIndex);
/**
* Called when the notification is dismissed.
* reason: 0 = UserCancelled, 1 = ApplicationHidden, 2 = TimedOut
*/
typedef void (CALLBACK* WNT_DismissedCallback)(INT64 toastId, int reason);
/** Called when the notification fails to display. */
typedef void (CALLBACK* WNT_FailedCallback)(INT64 toastId);
/* -------------------------------------------------------------------------
* Structs (must match StructLayout in WinToastNative.cs exactly)
* ------------------------------------------------------------------------- */
typedef enum _WNT_Scenario {
WNT_SCENARIO_DEFAULT = 0,
WNT_SCENARIO_ALARM = 1,
WNT_SCENARIO_REMINDER = 2,
WNT_SCENARIO_INCOMING_CALL = 3
} WNT_Scenario;
typedef enum _WNT_AudioOption {
WNT_AUDIO_DEFAULT = 0,
WNT_AUDIO_SILENT = 1,
WNT_AUDIO_LOOP = 2
} WNT_AudioOption;
/**
* Selects which Windows system notification sound to play.
* WNT_AUDIO_FILE_NONE (-1) means no specific sound file override (use AudioOption behaviour).
* Values 0-25 map directly to WinToastTemplate::AudioSystemFile.
*/
typedef enum _WNT_AudioFile {
WNT_AUDIO_FILE_NONE = -1,
WNT_AUDIO_FILE_DEFAULT = 0,
WNT_AUDIO_FILE_IM = 1,
WNT_AUDIO_FILE_MAIL = 2,
WNT_AUDIO_FILE_REMINDER = 3,
WNT_AUDIO_FILE_SMS = 4,
WNT_AUDIO_FILE_ALARM = 5,
WNT_AUDIO_FILE_ALARM2 = 6,
WNT_AUDIO_FILE_ALARM3 = 7,
WNT_AUDIO_FILE_ALARM4 = 8,
WNT_AUDIO_FILE_ALARM5 = 9,
WNT_AUDIO_FILE_ALARM6 = 10,
WNT_AUDIO_FILE_ALARM7 = 11,
WNT_AUDIO_FILE_ALARM8 = 12,
WNT_AUDIO_FILE_ALARM9 = 13,
WNT_AUDIO_FILE_ALARM10 = 14,
WNT_AUDIO_FILE_CALL = 15,
WNT_AUDIO_FILE_CALL1 = 16,
WNT_AUDIO_FILE_CALL2 = 17,
WNT_AUDIO_FILE_CALL3 = 18,
WNT_AUDIO_FILE_CALL4 = 19,
WNT_AUDIO_FILE_CALL5 = 20,
WNT_AUDIO_FILE_CALL6 = 21,
WNT_AUDIO_FILE_CALL7 = 22,
WNT_AUDIO_FILE_CALL8 = 23,
WNT_AUDIO_FILE_CALL9 = 24,
WNT_AUDIO_FILE_CALL10 = 25
} WNT_AudioFile;
/** Controls how the app-logo image is cropped. */
typedef enum _WNT_CropHint {
WNT_CROP_HINT_SQUARE = 0,
WNT_CROP_HINT_CIRCLE = 1
} WNT_CropHint;
/**
* Describes the notification to display.
* All pointer fields may be NULL where noted.
* Callers must keep pointed-to memory valid for the duration of WNT_ShowToast.
*
* Field layout (x64, no explicit packing):
* offsets 0..39 — five pointers (title, body, imagePath, heroImagePath, buttonLabels)
* offset 40 — buttonCount (int, 4 bytes) + 4 bytes natural padding
* offset 48 — expirationMs (long long, 8 bytes)
* offset 56 — scenario (int, 4 bytes)
* offset 60 — audioOption (int, 4 bytes)
* offsets 64..79 — three new pointers (inlineImagePath, attributionText, customAudioPath)
* offset 88 — cropHint (int, 4 bytes)
* offset 92 — audioFile (int, 4 bytes)
* Total: 96 bytes
*/
typedef struct _WNT_ToastDescriptor {
const wchar_t* title; /* required */
const wchar_t* body; /* nullable */
const wchar_t* imagePath; /* nullable — absolute path; app logo override in generic templates */
const wchar_t* heroImagePath; /* nullable — absolute path; full-width banner above the notification */
const wchar_t** buttonLabels; /* nullable — array of buttonCount wchar_t* */
int buttonCount;
long long expirationMs; /* 0 = platform default */
WNT_Scenario scenario;
WNT_AudioOption audioOption;
/* Extended fields (added in v2): */
const wchar_t* inlineImagePath; /* nullable — image displayed inline inside the notification body */
const wchar_t* attributionText; /* nullable — small text shown at the bottom of the notification */
const wchar_t* customAudioPath; /* nullable — ms-winsoundevent: URI or ms-appx:/// path; overrides audioFile */
int cropHint; /* WNT_CropHint — how imagePath is cropped (Square or Circle) */
int audioFile; /* WNT_AudioFile — system sound to play; -1 = not overridden */
} WNT_ToastDescriptor;
/**
* Bundle of callback function pointers for one notification.
* The struct is copied by value inside WNT_ShowToast; callers need not keep it alive.
* Individual function pointers may be NULL to skip that event.
*/
typedef struct _WNT_Handler {
WNT_ActivatedCallback onActivated;
WNT_ButtonActivatedCallback onButtonActivated;
WNT_DismissedCallback onDismissed;
WNT_FailedCallback onFailed;
} WNT_Handler;
/* -------------------------------------------------------------------------
* API functions
* ------------------------------------------------------------------------- */
/**
* Initialises WinToastLib. Must be called once from an STA thread.
*
* @param appName Human-readable name shown in the Action Centre.
* @param appUserModelId AppUserModelId (AUMI). The wrapper creates a Start-Menu
* shortcut carrying this AUMI automatically if one does not
* already exist.
* @param appIconPath Optional absolute path to an .ico (or .exe/.dll) file whose
* first icon is stamped onto the Start-Menu shortcut. This is
* the small icon shown in the top-left corner of every toast
* notification from this app. Pass NULL to use the default
* (the host executable's icon).
* @return TRUE on success.
*/
NOTIFYAPI BOOL WNT_Initialize(const wchar_t* appName, const wchar_t* appUserModelId, const wchar_t* appIconPath);
/**
* Releases all WinToastLib resources. Call from the same STA thread as WNT_Initialize.
*/
NOTIFYAPI void WNT_Uninitialize(void);
/**
* Returns TRUE if WinToast is supported on the current Windows version (requires Win 8+).
* Check this before calling WNT_Initialize.
*/
NOTIFYAPI BOOL WNT_IsCompatible(void);
/**
* Displays a toast notification.
*
* Must be called from the STA thread that called WNT_Initialize.
*
* @param descriptor Pointer to a WNT_ToastDescriptor (read-only during the call).
* @param handler Pointer to a WNT_Handler with callback function pointers.
* @return A positive INT64 toast ID on success, or a negative WinToastError code on failure.
*/
NOTIFYAPI INT64 WNT_ShowToast(const WNT_ToastDescriptor* descriptor, const WNT_Handler* handler);
/**
* Programmatically dismisses a previously shown toast.
*
* Must be called from the same STA thread as WNT_ShowToast.
*
* @param toastId The ID returned by WNT_ShowToast.
* @return TRUE if the toast was successfully hidden.
*/
NOTIFYAPI BOOL WNT_HideToast(INT64 toastId);
#ifdef __cplusplus
} /* extern "C" */
#endif