MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / ~Script

Method ~Script

source/script.cpp:613–672  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

611
612
613Script::~Script() // Destructor.
614{
615 // MSDN: "Before terminating, an application must call the UnhookWindowsHookEx function to free
616 // system resources associated with the hook."
617 AddRemoveHooks(0); // Remove all hooks.
618 if (mNIC.hWnd) // Tray icon is installed.
619 Shell_NotifyIcon(NIM_DELETE, &mNIC); // Remove it.
620
621 int i;
622 // It is safer/easier to destroy the GUI windows prior to the menus (especially the menu bars).
623 // This is because one GUI window might get destroyed and take with it a menu bar that is still
624 // in use by an existing GUI window. GuiType::Destroy() adheres to this philosophy by detaching
625 // its menu bar prior to destroying its window.
626 GuiType* gui;
627 while (gui = g_firstGui) // Destroy any remaining GUI windows (due to e.g. circular references). Also: assignment.
628 gui->Destroy();
629 for (i = 0; i < GuiType::sFontCount; ++i) // Now that GUI windows are gone, delete all GUI fonts.
630 if (GuiType::sFont[i].hfont)
631 DeleteObject(GuiType::sFont[i].hfont);
632 // The above might attempt to delete an HFONT from GetStockObject(DEFAULT_GUI_FONT), etc.
633 // But that should be harmless:
634 // MSDN: "It is not necessary (but it is not harmful) to delete stock objects by calling DeleteObject."
635
636 // Above: Probably best to have removed icon from tray and destroyed any Gui windows that were
637 // using it prior to getting rid of the script's custom icon below:
638 if (mCustomIcon)
639 {
640 DestroyIcon(mCustomIcon);
641 DestroyIcon(mCustomIconSmall); // Should always be non-NULL if mCustomIcon is non-NULL.
642 }
643
644 // Since they're not associated with a window, we must free the resources for all popup menus.
645 // Update: Even if a menu is being used as a GUI window's menu bar, see note above for why menu
646 // destruction is done AFTER the GUI windows are destroyed:
647 for (UserMenu *m = mFirstMenu; m; m = m->mNextMenu)
648 m->Dispose();
649
650 // Since tooltip windows are unowned, they should be destroyed to avoid resource leak:
651 for (i = 0; i < MAX_TOOLTIPS; ++i)
652 if (g_hWndToolTip[i] && IsWindow(g_hWndToolTip[i]))
653 DestroyWindow(g_hWndToolTip[i]);
654
655 if (mOnClipboardChange.Count()) // Remove from viewer chain.
656 EnableClipboardListener(false);
657
658 // Close any open sound item to prevent hang-on-exit in certain operating systems or conditions.
659 // If there's any chance that a sound was played and not closed out, or that it is still playing,
660 // this check is done. Otherwise, the check is avoided since it might be a high overhead call,
661 // especially if the sound subsystem part of the OS is currently swapped out or something:
662 if (g_SoundWasPlayed)
663 {
664 TCHAR buf[MAX_PATH * 2]; // See "MAX_PATH note" in Line::SoundPlay for comments.
665 mciSendString(_T("status ") SOUNDPLAY_ALIAS _T(" mode"), buf, _countof(buf), NULL);
666 if (*buf) // "playing" or "stopped"
667 mciSendString(_T("close ") SOUNDPLAY_ALIAS, NULL, 0, NULL);
668 }
669
670 DeleteCriticalSection(&g_CriticalRegExCache); // g_CriticalRegExCache is used elsewhere for thread-safety.

Callers

nothing calls this directly

Calls 4

AddRemoveHooksFunction · 0.85
DestroyMethod · 0.80
DisposeMethod · 0.45
CountMethod · 0.45

Tested by

no test coverage detected