Files
WinGUI/c_WinUI_Toast.c
T
2026-07-28 23:35:51 +08:00

112 lines
3.4 KiB
C

#include <c_WinUI_Toast.h>
#include <string.h>
// 定义定时器 ID
#define TIMER_CLOSE_ID 1
// Toast 窗口的全局配置
#define TOAST_WIDTH 320
#define TOAST_HEIGHT 80
#define MARGIN_RIGHT 20
#define MARGIN_BOTTOM 60
#define WINDOW_CLASS_NAME "c_WinUI_Toast"
#define PROP_KEY_TITLE "c_WinUI_Toast.Title"
#define PROP_KEY_MESSAGE "c_WinUI_Toast.Message"
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
c_WinGUI_EventHandlerDef(WM_PAINT, Toast_Paint) {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
char* title = GetProp(hwnd, PROP_KEY_TITLE);
char* message = GetProp(hwnd, PROP_KEY_MESSAGE);
if (title && message) {
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(255, 255, 255));
RECT rcTitle = {15, 12, TOAST_WIDTH-15, 35};
DrawText(hdc, title, -1, &rcTitle, DT_LEFT|DT_TOP|DT_END_ELLIPSIS);
SetTextColor(hdc, RGB(200, 200, 200));
RECT rcMsg = {15, 38, TOAST_WIDTH-15, TOAST_HEIGHT-10};
DrawText(hdc, message, -1, &rcMsg, DT_LEFT|DT_TOP|DT_WORDBREAK|DT_END_ELLIPSIS);
}
EndPaint(hwnd, &ps);
}
c_WinGUI_EventHandlerDef(WM_TIMER, Toast_Timer) {
if (id==TIMER_CLOSE_ID) {
KillTimer(hwnd, TIMER_CLOSE_ID);
AnimateWindow(hwnd, 300, AW_HIDE|AW_BLEND);
DestroyWindow(hwnd);
}
}
c_WinGUI_EventHandlerDef(WM_LBUTTONDOWN, Toast_LButtonDown) {
PostMessage(hwnd, WM_TIMER, TIMER_CLOSE_ID, 0);
}
c_WinGUI_EventHandlerDef(WM_DESTROY, Toast_Destroy) {
char* title = GetProp(hwnd, PROP_KEY_TITLE);
char* message = GetProp(hwnd, PROP_KEY_MESSAGE);
if (title){ free(title); }
if (message){ free(message); }
RemoveProp(hwnd, PROP_KEY_TITLE);
RemoveProp(hwnd, PROP_KEY_MESSAGE);
}
c_WinGUI_EventMapBegin(WndProc)
c_WinGUI_EventMap(WM_DESTROY, Toast_Destroy);
c_WinGUI_EventMap(WM_TIMER, Toast_Timer);
c_WinGUI_EventMap(WM_LBUTTONDOWN, Toast_LButtonDown);
c_WinGUI_EventMap(WM_PAINT, Toast_Paint);
c_WinGUI_EventMapEnd()
void c_WinUI_Toast_Show(HINSTANCE hInst, const char* title, const char* message, UINT timeoutMs) {
if (!title || !message) {
return;
}
WNDCLASS wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInst;
wc.lpszClassName = WINDOW_CLASS_NAME;
wc.hbrBackground = CreateSolidBrush(RGB(32, 32, 32));
// wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wc);
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
int posX = screenWidth - TOAST_WIDTH - MARGIN_RIGHT;
int posY = screenHeight - TOAST_HEIGHT - MARGIN_BOTTOM;
HWND hwnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
WINDOW_CLASS_NAME, title,
WS_POPUP,
posX, posY, TOAST_WIDTH, TOAST_HEIGHT,
NULL, NULL, hInst, NULL);
if (!hwnd) {
return;
}
char* p_title = strdup(title);
char* p_message = strdup(message);
SetProp(hwnd, PROP_KEY_TITLE, p_title);
SetProp(hwnd, PROP_KEY_MESSAGE, p_message);
SetTimer(hwnd, TIMER_CLOSE_ID, timeoutMs, NULL);
AnimateWindow(hwnd, 200, AW_SLIDE | AW_VER_NEGATIVE | AW_ACTIVATE);
InvalidateRect(hwnd, NULL, TRUE); // 标记整个窗口需要重绘
UpdateWindow(hwnd); // 立即发送 WM_PAINT 消息
}