MFC & SDL

This had me beating my head against the  wall for days. Now as you know, It is fairly straightforward to open an SDL  surface in a window:

SDL_Surface *screen = SDL_SetVideoMode(width, height, 24, SDL_NOFRAME);

if(screen == 0)

    throw AVException(SDL_GetError());

The SDL_NOFRAME option removes  the window borders so the window is now ready to become a child window. Next  we need to obtain the SDL window’s HWND

#include <SDL_syswm.h>

 

struct SDL_SysWMinfo wmInfo;

SDL_VERSION(&wmInfo.version);

 

if(-1 == SDL_GetWMInfo(&wmInfo))

    throw  AVException(SDL_GetError());

 

HWND hwndSDL = wmInfo.window;

Now we can parent it to our window:

SetParent(hwndSDL, hwndMyWindow);

So far so good but this is where it all  falls apart. When the parent window is moved, the SDL window does not move  with it. You get an effect where the clipping rectangle moves but the  contents of the window stay put.

This took me days to figure out. It  tried messsing about with WM_MOVE handlers and using offsets on my  SDL_UpdateRect() coordinates and all kinds of crazy stuff but in the end I  found two important facts:

  1. The SDL window does not receive WM_MOVE       noftifications from its parent
  2. Using MoveWindow to set the position of       the SDL window does not work if the new coordinates are the same as the       current coordinates (that was the tough one to work out)

Since I am using SDL to play video, I am  constantly updating the window all the time. This means I can use a test in  my update function to check if the window has moved. If so, I need to use two  calls to MoveWindow to fool SDL into moving. If you are not doing animation,  perhaps you could use a timer call or something to achieve the same result.  Anyway, here is the code:

// Dumps the given frame to the screen.

void showFrame(SDL_Surface *surface)

{

    static RECT lastPos;

 

// Check to see if the window has been moved.

    RECT r;

    GetWindowRect(hwndSDL,  &r);

 

    if(r.left != lastPos.left ||  r.top != lastPos.top)

    {

        GetClientRect(hwndSDL,  &r);

        MoveWindow(hwndSDL,  r.left, r.top, r.right - r.left, r.bottom - r.top, FALSE);

        MoveWindow(hwndSDL, r.left  + 4, r.top, r.right - r.left, r.bottom - r.top, FALSE);

        lastPos = r;

    }

 

// Copy the off-screen surface to the screen.

    SDL_BlitSurface(surface, 0,  screen, 0);

    SDL_UpdateRect(screen, 0, 0,  0, 0);

}

Comments  (0)

No Comments »

 

Filed under: Nerd Notes — adam @ 12:23  pm

This had me beating my head against the  wall for days. Now as you know, It is fairly straightforward to open an SDL  surface in a window:

SDL_Surface *screen = SDL_SetVideoMode(width, height, 24, SDL_NOFRAME);

if(screen == 0)

    throw  AVException(SDL_GetError());

The SDL_NOFRAME option removes  the window borders so the window is now ready to become a child window. Next  we need to obtain the SDL window’s HWND

#include <SDL_syswm.h>

 

struct SDL_SysWMinfo wmInfo;

SDL_VERSION(&wmInfo.version);

 

if(-1 == SDL_GetWMInfo(&wmInfo))

    throw  AVException(SDL_GetError());

 

HWND hwndSDL = wmInfo.window;

Now we can parent it to our window:

SetParent(hwndSDL, hwndMyWindow);

So far so good but this is where it all  falls apart. When the parent window is moved, the SDL window does not move  with it. You get an effect where the clipping rectangle moves but the  contents of the window stay put.

This took me days to figure out. It  tried messsing about with WM_MOVE handlers and using offsets on my  SDL_UpdateRect() coordinates and all kinds of crazy stuff but in the end I  found two important facts:

  1. The SDL window does not receive WM_MOVE       noftifications from its parent
  2. Using MoveWindow to set the position of       the SDL window does not work if the new coordinates are the same as the       current coordinates (that was the tough one to work out)

Since I am using SDL to play video, I am  constantly updating the window all the time. This means I can use a test in  my update function to check if the window has moved. If so, I need to use two  calls to MoveWindow to fool SDL into moving. If you are not doing animation,  perhaps you could use a timer call or something to achieve the same result.  Anyway, here is the code:

// Dumps the given frame to the screen.

void showFrame(SDL_Surface *surface)

{

    static RECT lastPos;

 

// Check to see if the window has been moved.

    RECT r;

    GetWindowRect(hwndSDL,  &r);

 

    if(r.left != lastPos.left ||  r.top != lastPos.top)

    {

        GetClientRect(hwndSDL,  &r);

        MoveWindow(hwndSDL,  r.left, r.top, r.right - r.left, r.bottom - r.top, FALSE);

        MoveWindow(hwndSDL, r.left  + 4, r.top, r.right - r.left, r.bottom - r.top, FALSE);

        lastPos = r;

    }

 

// Copy the off-screen surface to the screen.

    SDL_BlitSurface(surface, 0,  screen, 0);

    SDL_UpdateRect(screen, 0, 0,  0, 0);

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值