Sign in to follow this  
0x3a

Can the SDL_PollEvent() return window messages

Recommended Posts

I'm having some issues receiving messages from my dialog while using SDL.

This is my current event pollevent loop which is fine:
		SDL_Event event;
while (SDL_PollEvent( &event ))
{
switch (event.type)
{
case SDL_QUIT:
exitapp = 1;
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
{
exitapp = 1;
}
SceneManager->KeyDown( event.key.keysym.scancode );
break;
case SDL_KEYUP:
SceneManager->KeyUp( event.key.keysym.scancode );
break;
case SDL_MOUSEMOTION:
SceneManager->MouseMove( event.motion.x, event.motion.y );
break;
case SDL_MOUSEBUTTONUP:
SceneManager->MouseUp( event.button.button );
break;
case SDL_MOUSEBUTTONDOWN:
SceneManager->MouseDown( event.button.button );
break;
default:
break;
}
}


The problem is, the normal way of receiving messages on a dialog is abstracted by SDL. I am wondering how I can get the message from my menu for example. Normally I would check on the ID of the menu item but now I can't because of this abstraction. Is there a way to still check the messages from the dialog? I assume I can still do this but the SDL wiki isn't clearing it up for me.

I'd like to just be able to check on ID_FILE_EXIT for example, this is one of the ID's of my menu.


Help would be appreciated :)

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
You should look into SDL_SysWMEvent. You may have to look through the SDL source to see what the structure is like on your platform of choice.


I've been doing that just now. What I found out is that it never gets there, I extended the loop like this:

			case SDL_SYSWMEVENT:
printf("SYSWMEVENT!\n");
switch (event.syswm.msg->msg)
{
case WM_COMMAND:
printf("WM_COMMAND!\n");
int mId = LOWORD(event.syswm.msg->wParam);
int wmEvent = HIWORD(event.syswm.msg->wParam);
switch(mId)
{
case ID_FILE_EXIT:
exitapp = 1;
break;
}
break;
}
break;


But the SDL_SYSWMEVENT is never called. (I added printf() to check this.)

Whenever I hit a button on the menu the case never gets hit. It doesn't reach WM_COMMAND this way of course.

The SDL Wiki tells me that the msg from the event is the normal WinAPI message setup.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Have you enabled these events?

From the page I linked.
Quote:

If you enable this event using SDL_EventState, it will be generated whenever unhandled events are received from the window manager.


Yes, I added:
SDL_EventState( SDL_SYSWMEVENT, SDL_ENABLE );


But the switch statement still never gets hit, I'm reading the wiki now to see what I'm doing wrong but can't really find anything about it.


Edit: Weird thing is, when I enable this the normal exit button on the dialog does not work as SDL_QUIT anymore. So something has been affected, but I have no clue what..

Share this post


Link to post
Share on other sites
I'm on Linux so I cannot directly test your code.

The following "works" for me, in that the message gets printed when you do window manager related things, such as manipulating the window size, etc.

#include <iostream>
#include <cstdlib>

#include "SDL.h"

int main(int argc, char* argv[])
{
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
std::cout << "Failed to initialise SDL: " << SDL_GetError() << '\n';
return 1;
}
std::atexit(&SDL_Quit);

SDL_Surface *screen = SDL_SetVideoMode(400, 300, 0, SDL_RESIZABLE);
if(!screen)
{
std::cout << "Failed to set video mode: " << SDL_GetError() << '\n';
return 1;
}

SDL_EventState( SDL_SYSWMEVENT, SDL_ENABLE );
if(SDL_EventState( SDL_SYSWMEVENT, SDL_QUERY ) != SDL_ENABLE)
{
std::cout << "Failed to change event state: " << SDL_GetError() << '\n';
return 1;
}

bool running = true;
while(running)
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
{
running = false;
}
else if(event.type == SDL_SYSWMEVENT)
{
std::cout << "Got a window manager event!\n";
}
}
SDL_Flip(screen);
}

return 0;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
I'm on Linux so I cannot directly test your code.

The following "works" for me, in that the message gets printed when you do window manager related things, such as manipulating the window size, etc.
*** Source Snippet Removed ***


I've tried your piece of code but the "Got a window manager event!" prints at pretty random moments... Nothing happens when I press one of the menu buttons but randomly does when I click on the window itself. I suppose it should print every time I hit one of the menu options and/or click the window.

Pretty odd, I'm doing nothing special, this is how my entire loop looks right now:
		// event loop
SDL_Event event;
int mId;
int wmEvent;

SDL_EventState( SDL_SYSWMEVENT, SDL_ENABLE );
if(SDL_EventState( SDL_SYSWMEVENT, SDL_QUERY ) != SDL_ENABLE)
std::cout << "Failed to change event state: " << SDL_GetError() << '\n';

while (SDL_PollEvent( &event ))
{
switch (event.type)
{
case SDL_SYSWMEVENT:
printf("SYSWMEVENT!\n");

switch (event.syswm.msg->msg)
{
case WM_COMMAND:
printf("WM_COMMAND!\n");

mId = LOWORD(event.syswm.msg->wParam);
wmEvent = HIWORD(event.syswm.msg->wParam);

switch(mId)
{
case ID_FILE_EXIT:
exitapp = 1;
break;
}
break;
case WM_DESTROY: //When the window is forced to close
exitapp = 1;
break;
case WM_CLOSE: //When the window is closed using the X button in the toolbar
exitapp = 1;
break;
}
break;
case SDL_QUIT:
exitapp = 1;
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
{
exitapp = 1;
// find other keys here: http://sdl.beuc.net/sdl.wiki/SDLKey
}
game->KeyDown( event.key.keysym.scancode );
break;
case SDL_KEYUP:
game->KeyUp( event.key.keysym.scancode );
break;
case SDL_MOUSEMOTION:
game->MouseMove( event.motion.x, event.motion.y );
break;
case SDL_MOUSEBUTTONUP:
game->MouseUp( event.button.button );
break;
case SDL_MOUSEBUTTONDOWN:
game->MouseDown( event.button.button );
break;
default:
printf("%i\n", event.type );
// more info on events in SDL: http://sdl.beuc.net/sdl.wiki/SDL_Event
break;
}
}



Edit: When I try SDL_WaitEvent( &event ) instead of SDL_PollEvent( &event ) the SDL_SYSWMEVENT does get hit. But something is still off, the exitapp = 1; never gets called somehow and the WM_DESTROY, WM_CLOSE, SDL_KEYDOWN, SDL_KEYUP, SDL_MOUSEMOTION, SDL_MOUSEBUTTONUP and SDL_MOUSEBUTTONDOWN never get called anymore. So this is not an option it seems.

[Edited by - 0x3a on December 9, 2010 1:02:26 PM]

Share this post


Link to post
Share on other sites
Problem solved!

C++ and its scopes ;)

I made it look like this:
		while (SDL_WaitEvent( &event ) && !exitapp)//while (SDL_WaitEvent( &event ))
{
switch (event.type)
{
case SDL_SYSWMEVENT:
{
switch (event.syswm.msg->msg)
{
case WM_COMMAND:
{
mId = LOWORD(event.syswm.msg->wParam);
wmEvent = HIWORD(event.syswm.msg->wParam);

switch(mId)
{
case ID_FILE_EXIT:
{
printf("ID_FILE_EXIT\n");
exitapp = true;
break;
}
case ID_FILE_LOADSCENE:
{
printf("ID_FILE_LOADSCNE\n");
//exitapp = true;
break;
}
}
break;
case WM_DESTROY: //When the window is forced to close
{
exitapp = true;
break;
}
case WM_CLOSE: //When the window is closed using the X button in the toolbar
{
exitapp = true;
break;
}
}
}
break;
}
case SDL_QUIT:
{
exitapp = true;
break;
}
case SDL_KEYDOWN:
{
if (event.key.keysym.sym == SDLK_ESCAPE)
{
exitapp = 1;
// find other keys here: http://sdl.beuc.net/sdl.wiki/SDLKey
}
game->KeyDown( event.key.keysym.scancode );
break;
}
case SDL_KEYUP:
{
game->KeyUp( event.key.keysym.scancode );
break;
}
case SDL_MOUSEMOTION:
{
game->MouseMove( event.motion.x, event.motion.y );
break;
}
case SDL_MOUSEBUTTONUP:
{
game->MouseUp( event.button.button );
break;
}
case SDL_MOUSEBUTTONDOWN:
{
game->MouseDown( event.button.button );
break;
}
default:
{
printf("Type: %i\n", event.type );
// more info on events in SDL: http://sdl.beuc.net/sdl.wiki/SDL_Event
break;
}
}
}


The && exitapp is for my entire while loop, it got stuck because of events in the WinAPI being continuously send. This fixed it :) For any people in the future who are doing this, could be a useful snippet, who knows.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this