| 499 | |
| 500 | |
| 501 | void Hotkey::AllDestructAndExit(int aExitCode) |
| 502 | { |
| 503 | // PostQuitMessage() might be needed to prevent hang-on-exit. Once this is done, no message boxes or |
| 504 | // other dialogs can be displayed. MSDN: "The exit value returned to the system must be the wParam |
| 505 | // parameter of the WM_QUIT message." In our case, PostQuitMessage() should announce the same exit code |
| 506 | // that we will eventually call exit() with: |
| 507 | PostQuitMessage(aExitCode); |
| 508 | |
| 509 | AddRemoveHooks(0); // Remove all hooks. By contrast, registered hotkeys are unregistered below. |
| 510 | if (g_PlaybackHook) // Would be unusual for this to be installed during exit, but should be checked for completeness. |
| 511 | UnhookWindowsHookEx(g_PlaybackHook); |
| 512 | for (int i = 0; i < sHotkeyCount; ++i) |
| 513 | delete shk[i]; // Unregisters before destroying. |
| 514 | |
| 515 | // Do this only at the last possible moment prior to exit() because otherwise |
| 516 | // it may free memory that is still in use by objects that depend on it. |
| 517 | // This is actually kinda wrong because when exit() is called, the destructors |
| 518 | // of static, global, and main-scope objects will be called. If any of these |
| 519 | // destructors try to reference memory freed() by DeleteAll(), there could |
| 520 | // be trouble. |
| 521 | // It's here mostly for traditional reasons. I'm 99.99999 percent sure that there would be no |
| 522 | // penalty whatsoever to omitting this, since any modern OS will reclaim all |
| 523 | // memory dynamically allocated upon program termination. Indeed, omitting |
| 524 | // deletes and free()'s for simple objects will often improve the reliability |
| 525 | // and performance since the OS is far more efficient at reclaiming the memory |
| 526 | // than us doing it manually (which involves a potentially large number of deletes |
| 527 | // due to all the objects and sub-objects to be destructed in a typical C++ program). |
| 528 | // UPDATE: In light of the first paragraph above, it seems best not to do this at all, |
| 529 | // instead letting all implicitly-called destructors run prior to program termination, |
| 530 | // at which time the OS will reclaim all remaining memory: |
| 531 | //SimpleHeap::DeleteAll(); |
| 532 | |
| 533 | // I know this isn't the preferred way to exit the program. However, due to unusual |
| 534 | // conditions such as the script having MsgBoxes or other dialogs displayed on the screen |
| 535 | // at the time the user exits (in which case our main event loop would be "buried" underneath |
| 536 | // the event loops of the dialogs themselves), this is the only reliable way I've found to exit |
| 537 | // so far. The caller has already called PostQuitMessage(), which might not help but it doesn't hurt: |
| 538 | exit(aExitCode); // exit() is insignificant in code size. It does more than ExitProcess(), but perhaps nothing more that this application actually requires. |
| 539 | // By contrast to _exit(), exit() flushes all file buffers before terminating the process. It also |
| 540 | // calls any functions registered via atexit or _onexit. |
| 541 | } |
| 542 | |
| 543 | |
| 544 |
nothing calls this directly
no test coverage detected