SDL 实现透明悬浮窗
最近一直想用SDL实现弹幕功能,但是一直没法实现悬浮窗和透明背景功能。
在一个老外的博客上发现了思路:EthioProgrammer: Applying transparency using win32 api, C++/SDL code
就是通过SDL_GetWindowWMInfo函数获取到窗口的HWND句柄,然后调用win32 api设置窗口的属性即可。
在别的平台也一样,调用系统api设置窗体属性。
有一点需要注意,目测只能用Surface,不能用Renderer,不然无法通过窗体colorKey实现透明背景。
代码如下:
#include <SDL2/SDL.h> #include <SDL2/SDL_syswm.h> #include <SDL2/SDL_video.h> #include <windows.h> int main(int argc, char *argv[]) { SDL_Window *window; SDL_Renderer *renderer; SDL_Surface *winSurface; SDL_Event event; int quit = 0; SDL_Rect rectRect = {0,0,50,50}; SDL_Rect backRect = {0}; SDL_SysWMinfo info; HWND hwnd; SDL_Init(SDL_INIT_EVERYTHING); window = SDL_CreateWindow("Test",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,640,480,SDL_WINDOW_SHOWN|SDL_WINDOW_BORDERLESS); SDL_VERSION(&info.version); if(SDL_GetWindowWMInfo(window,&info)) { hwnd = info.info.win.window; } /*设置窗口colorkey*/ SetWindowLong( hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE)|WS_EX_LAYERED); SetLayeredWindowAttributes( hwnd, RGB(255,255,255),0, LWA_COLORKEY); /*设置窗口为悬浮窗 */ SetWindowPos ( hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); /*--------------*/ winSurface = SDL_GetWindowSurface(window); SDL_GetWindowSize(window,&backRect.w,&backRect.h); UINT32 keyColor = SDL_MapRGB(winSurface->format,255,255,255); SDL_SetSurfaceBlendMode(winSurface,SDL_BLENDMODE_NONE); while(!quit){ while(SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) quit = 1; } SDL_FillRect(winSurface,&backRect,keyColor); rectRect.x+=1; SDL_FillRect(winSurface,&rectRect,SDL_MapRGB(winSurface->format,0xff,0x00,0x00)); SDL_UpdateWindowSurface(window); SDL_Delay(1000/60); } SDL_Quit(); return 0; }
效果图: