Thank you very much for your answer, but it seems it will still exist. Below is all my code:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_syswm.h>
#include <stdio.h>
#include <windows.h>
#include <shellapi.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
// Constant Definitions
#define IMAGE_DIR “./cat” // Image folder directory
#define SWITCH_INTERVAL 50 // Image switch interval (in milliseconds)
// Check if the file is in PNG format
int is_png(const char *filename) {
const char *ext = strrchr(filename, ‘.’);
return ext != NULL && strcmp(ext, “.png”) == 0;
}
// Get all PNG files in the specified directory
int get_png_files(const char *dir, char ***image_files) {
DIR *d = opendir(dir);
if (d == NULL) {
fprintf(stderr, “Failed to open directory: %s\n”, dir);
return 0;
}
struct dirent *entry;
int count = 0;
while ((entry = readdir(d)) != NULL) {
if (is_png(entry->d_name)) {
(*image_files) = realloc(*image_files, sizeof(char*) * (count + 1));
(*image_files)[count] = malloc(strlen(dir) + strlen(entry->d_name) + 2);
sprintf((*image_files)[count], "%s/%s", dir, entry->d_name);
count++;
}
}
closedir(d);
return count;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
fprintf(stderr, “SDL_Init Error: %s\n”, SDL_GetError());
return 1;
}
// Initialize SDL_image
if (IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG == 0) {
fprintf(stderr, "IMG_Init Error: %s\n", IMG_GetError());
SDL_Quit();
return 1;
}
// Get all PNG files in IMAGE_DIR directory
char **image_files = NULL;
int image_count = get_png_files(IMAGE_DIR, &image_files);
if (image_count == 0) {
fprintf(stderr, "No PNG files found in %s\n", IMAGE_DIR);
IMG_Quit();
SDL_Quit();
return 1;
}
// Get the width and height of the first image
SDL_Surface *image = IMG_Load(image_files[0]);
if (image == NULL) {
fprintf(stderr, "IMG_Load Error: %s\n", IMG_GetError());
IMG_Quit();
SDL_Quit();
return 1;
}
int imgWidth = image->w;
int imgHeight = image->h;
// Create window, adjust window size according to image size
SDL_Window *window = SDL_CreateWindow("SDL2 Image Display", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, imgWidth, imgHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS);
if (window == NULL) {
fprintf(stderr, "SDL_CreateWindow Error: %s\n", SDL_GetError());
SDL_FreeSurface(image);
IMG_Quit();
SDL_Quit();
return 1;
}
// Get the native window handle
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
if (SDL_GetWindowWMInfo(window, &wmInfo) != 1) {
fprintf(stderr, "SDL_GetWindowWMInfo failed\n");
SDL_DestroyWindow(window);
SDL_FreeSurface(image);
IMG_Quit();
SDL_Quit();
return 1;
}
HWND hwnd = wmInfo.info.win.window;
// Set the window as a tool window
LONG_PTR style = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
SetWindowLongPtr(hwnd, GWL_EXSTYLE, style | WS_EX_TOOLWINDOW | WS_EX_LAYERED | WS_EX_TRANSPARENT);
// Set the window to be transparent and allow mouse penetration
SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 0, LWA_COLORKEY); // Set the transparent color key to black
// Set the window to always be on top
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
// Create renderer
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (renderer == NULL) {
fprintf(stderr, "SDL_CreateRenderer Error: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_FreeSurface(image);
IMG_Quit();
SDL_Quit();
return 1;
}
// Create texture
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, image);
SDL_FreeSurface(image); // No longer needed
if (texture == NULL) {
fprintf(stderr, "SDL_CreateTextureFromSurface Error: %s\n", SDL_GetError());
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
return 1;
}
// Set blend mode
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); // Set texture blend mode to blend
// Set tray icon
NOTIFYICONDATA nid;
ZeroMemory(&nid, sizeof(NOTIFYICONDATA));
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hwnd;
nid.uID = 1;
nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
nid.uCallbackMessage = WM_APP; // Set message callback
nid.hIcon = (HICON)LoadImage(NULL, "icon.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE); // Icon path
// Modify nid.szTip type to wchar_t array
wchar_t szTip[128]; // Define as wchar_t type
wcsncpy(szTip, L"My Tray Icon", sizeof(szTip) / sizeof(wchar_t)); // Wide-character string
wcscpy((wchar_t*)nid.szTip, szTip); // Fill with wide-character string
Shell_NotifyIcon(NIM_ADD, &nid);
// Event loop
SDL_Event e;
int quit = 0;
int current_image_index = 0;
Uint32 last_time = SDL_GetTicks();
while (!quit) {
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
quit = 1;
}
}
// Switch the image every SWITCH_INTERVAL milliseconds
Uint32 current_time = SDL_GetTicks();
if (current_time - last_time >= SWITCH_INTERVAL) {
last_time = current_time;
current_image_index = (current_image_index + 1) % image_count;
// Load the next image
SDL_Surface *new_image = IMG_Load(image_files[current_image_index]);
if (new_image == NULL) {
fprintf(stderr, "IMG_Load Error: %s\n", IMG_GetError());
continue;
}
// Create new texture
SDL_Texture *new_texture = SDL_CreateTextureFromSurface(renderer, new_image);
SDL_FreeSurface(new_image);
if (new_texture == NULL) {
fprintf(stderr, "SDL_CreateTextureFromSurface Error: %s\n", SDL_GetError());
continue;
}
SDL_DestroyTexture(texture); // Destroy old texture
texture = new_texture; // Update to the new texture
}
// Render the image
SDL_RenderClear(renderer);
SDL_Rect dstRect = {0, 0, imgWidth, imgHeight}; // Target rectangle, specifying the image size
SDL_RenderCopy(renderer, texture, NULL, &dstRect); // Render using the specified size
SDL_RenderPresent(renderer);
SDL_Delay(10); // Prevent excessive CPU usage
}
// Clean up resources
Shell_NotifyIcon(NIM_DELETE, &nid); // Remove tray icon
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
// Free image filenames array
for (int i = 0; i < image_count; i++) {
free(image_files[i]);
}
free(image_files);
return 0;
}