Witam. Może to dość głupie pytanie. Czy jest możliwość w Visual C++ przerwania aplikacji za pomocą wyrzucenia wyjątku przez throw, a potem wyświetlenia MessageBox (np. z WinAPI)?
Jest.
/* #include whatever */
void your_app() { /* whatever */ }
void your_error_msgbox(std::exception const &e) { /* whatever */ }
int main() {
try { your_app(); } catch(std::exception const &e) {
your_error_msgbox(e);
}
return 0;
}
Zrobiłem coś takiego.
try { throw; }
catch(std::exception exc)
{
MessageBox(nullptr, TEXT("Przegrales"), TEXT("You lose"), MB_OK);
}
I to nie działa tak jak chciałem. Wyrzuca mi taki komunikat:
A ja chciałbym, żeby tego komunikatu nie było. Zamiast niego aplikacja ma się przerywać i ma się pojawiać mój MessageBox.
Wyjątek C++ i wyjątek systemowy to różne rzeczy. Tutaj masz access violation, czego wewnątrz języka nie złapiesz. Tak przy okazji: nie przyjmuj wyjątków przez wartość bo je slice'ujesz.
No dobra. W takim razie jak najprościej wymusić wyjątek C++ (niesystemowy)? Poza tym nie rozumiem zdania:
"nie przyjmuj wyjątków przez wartość bo je slice'ujesz."
catch(...)
kq napisał(a):
Wyjątek C++ i wyjątek systemowy to różne rzeczy. Tutaj masz access violation, czego wewnątrz języka nie złapiesz.
Nieprawda.
#include <stdio.h>
#include <windows.h>
using namespace std;
int main()
{
int *p = nullptr;
try
{
*p = 42;
}
catch(...)
{
printf("Booom!\n");
}
}
Jeżeli jednak nie chcemy catch(...)
, tylko złapać konkretny wyjątek (np. access violation) przegapiając pozostałe, trzeba się trochę bardziej nagimnastykować:
#include <stdio.h>
#include <eh.h>
#include <windows.h>
#include <exception>
using namespace std;
class access_violation: public exception {};
int main()
{
_set_se_translator([](unsigned int u, struct _EXCEPTION_POINTERS*)->void
{
switch(u)
{
case EXCEPTION_ACCESS_VIOLATION:
throw access_violation();
default:
throw exception();
}
});
int *p = nullptr;
try
{
*p = 42;
}
catch(access_violation &e)
{
printf("Booom!\n");
}
}