#include #include // 定义定时器 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 消息 }