hello,
I recently started using Irrlicht a couple of days ago, with C++ and just wondering how do I go about making it so when Alt+F4 or the X button is pressed on the application window, a message box is created by addMessageBox with a yes & no button, and if yes is pressed the program closes, but if no the program stays opened?
I've been trying to figure out how to do this but couldnt... please help.
customizing application close
-
- Posts: 616
- Joined: Wed Nov 01, 2006 6:26 pm
- Location: Cairo,Egypt
- Contact:
since this is related to the windows api rather than irrlicht as irrlicht cant execute a command while application is closing(or whatever) so u have to use win api which means not a console application but rather windows api application
here's the code (found at msdn) it doesn't need explanation the code simply send message if exit function is called and when user says no it breaks and returns to the program(cancel exit function)
here's the code (found at msdn) it doesn't need explanation the code simply send message if exit function is called and when user says no it breaks and returns to the program(cancel exit function)
Code: Select all
case WM_CLOSE:
{
if (MessageBox(hWnd, "Are You Sure You Want To Exit?", "Exit", MB_YESNO) == IDYES)
{
PostQuitMessage(0);
}
else
return 0;
}break;
-
- Posts: 616
- Joined: Wed Nov 01, 2006 6:26 pm
- Location: Cairo,Egypt
- Contact:
cool it works I placed that into the WndProc in CIrrDeviceWin32.cpp, and commented out the WM_DESTROY case. Thanks
Edit:: Awesome, I just found out theres some dev = getDeviceFromHWnd(hWnd); inside some of the other switch cases. I now tried doing something like,
that seems to work. I just gotta figure out how to make it so only 1 can popup instead of many, and then give the yes button a PostQuitMessage(0) event.
Edit:: Awesome, I just found out theres some dev = getDeviceFromHWnd(hWnd); inside some of the other switch cases. I now tried doing something like,
Code: Select all
case WM_CLOSE:
{
dev = getDeviceFromHWnd(hWnd);
if (dev)
{
dev->getGUIEnvironment()->addMessageBox(L"Test", L"T", true, irr::s32(0x4) | irr::s32(0x8));
}
} break;
You could also just use postEventFromUser() and eat the message right there. Something like this...
That way you can write a user event receiver that properly handles the message and causes the application to exit in the same way as it would if the user had pressed a quit button inside the application...
A change like this would be appropriate for putting into the engine so other users can take advantage of the enhancement without needing to modify the engine source. It also has the advantage that you don't need to rebuild the Irrlicht.dll every time you decide you want to change an attribute of the message box.
Travis
Code: Select all
case WM_CLOSE:
// you'd need to add additional minor changes to IEventReceiver.h
event.EventType = irr::EET_WINDOW_EVENT;
event.WindowEvent.EventType = irr::EWE_APPLICATION_CLOSE;
dev = getDeviceFromHWnd(hWnd);
// tell the user event receiver that the app requested a close event
if (dev && dev->postEventFromUser(event)) {
// device pointer was valid, and the user event receiver
// consumed the event. assume user event receiver will
// exit the application if necessary. return now.
return 0;
}
// device pointer was invalid, or user event receiver failed to
// consume the event. this break causes us to do the default,
// which will allow the application to exit. this should maintain
// existing behavior for apps that don't explicitly handle this
// event type.
break;
Code: Select all
struct MyEventReceiver : public IEventReciever
{
MyEventReceiver (IrrlichtDevice* device)
: Device(device)
{
}
virtual bool OnEvent(const SEvent& ev)
{
if (ev.EventType == EET_WINDOW_EVENT &&
ev.AppEvent == EWE_APPLICATION_CLOSE)
{
gui::IGUIEnvironment* gui = Device->getGUIEnvironment();
assert (gui);
gui->addMessageBox(L"Test", L"T", true, EMBF_YES | EMBF_NO);
return true;
}
else if (ev.EventType == EET_GUI_INPUT_EVENT &&
ev.GUIEvent.EventType == EGET_MESSAGEBOX_YES)
{
Device->closeDevice();
return true;
}
}
private:
IrrlichtDevice* Device;
};
Travis
I like the sound of this, I might need to do some research on it and figure out where to place WindowEvent, AppEvent and EWE_APPLICATION_CLOSE in IEventReceiver.h.vitek wrote:You could also just use postEventFromUser() and eat the message right there. Something like this...
That way you can write a user event receiver that properly handles the message and causes the application to exit in the same way as it would if the user had pressed a quit button inside the application...Code: Select all
case WM_CLOSE: // you'd need to add additional minor changes to IEventReceiver.h event.EventType = irr::EET_WINDOW_EVENT; event.WindowEvent.EventType = irr::EWE_APPLICATION_CLOSE; dev = getDeviceFromHWnd(hWnd); // tell the user event receiver that the app requested a close event if (dev && dev->postEventFromUser(event)) { // device pointer was valid, and the user event receiver // consumed the event. assume user event receiver will // exit the application if necessary. return now. return 0; } // device pointer was invalid, or user event receiver failed to // consume the event. this break causes us to do the default, // which will allow the application to exit. this should maintain // existing behavior for apps that don't explicitly handle this // event type. break;
A change like this would be appropriate for putting into the engine so other users can take advantage of the enhancement without needing to modify the engine source. It also has the advantage that you don't need to rebuild the Irrlicht.dll every time you decide you want to change an attribute of the message box.Code: Select all
struct MyEventReceiver : public IEventReciever { MyEventReceiver (IrrlichtDevice* device) : Device(device) { } virtual bool OnEvent(const SEvent& ev) { if (ev.EventType == EET_WINDOW_EVENT && ev.AppEvent == EWE_APPLICATION_CLOSE) { gui::IGUIEnvironment* gui = Device->getGUIEnvironment(); assert (gui); gui->addMessageBox(L"Test", L"T", true, EMBF_YES | EMBF_NO); return true; } else if (ev.EventType == EET_GUI_INPUT_EVENT && ev.GUIEvent.EventType == EGET_MESSAGEBOX_YES) { Device->closeDevice(); return true; } } private: IrrlichtDevice* Device; };
Travis