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;
}

效果图:

posted @ 2016-12-11 13:27  mmmmar  阅读(4100)  评论(1编辑  收藏  举报