MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / Destroy

Method Destroy

source/script_gui.cpp:2134–2218  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2132
2133
2134void GuiType::Destroy()
2135// Destroys the window and performs related cleanup which is only necessary for
2136// a successfully constructed Gui, then calls Dispose() for the remaining cleanup.
2137{
2138 if (!mHwnd)
2139 return; // We have already been destroyed.
2140
2141 // First destroy any windows owned by this window, since they will be auto-destroyed
2142 // anyway due to their being owned. By destroying them explicitly, the Destroy()
2143 // function is called recursively which keeps everything relatively neat.
2144 // Lexikos: I'm not really sure what Chris meant by "neat", since Destroy() is called
2145 // recursively via WM_DESTROY anyway. It's currently left to WM_DESTROY because the
2146 // code below is actually broken in two ways (unique to the new object-oriented API):
2147 // 1) If there are no external references to gui, it will be deleted and gui->mNextGui
2148 // will likely crash the program.
2149 // 2) Destroy() removes the gui from the list, which causes the loop to break at the
2150 // first owned/child window. Saving the next/previous link before-hand may not
2151 // solve the problem since Destroy() could recursively destroy other windows.
2152 //for (GuiType* gui = g_firstGui; gui; gui = gui->mNextGui)
2153 // if (gui->mOwner == mHwnd)
2154 // gui->Destroy();
2155
2156 // Testing shows that this must be done prior to calling DestroyWindow() later below, presumably
2157 // because the destruction immediately destroys the status bar, or prevents it from answering messages.
2158 // MSDN says "During the processing of [WM_DESTROY], it can be assumed that all child windows still exist".
2159 // However, for DestroyWindow() to have returned means that WM_DESTROY was already fully processed.
2160 if (mStatusBarHwnd) // IsWindow(gui.mStatusBarHwnd) isn't called because even if possible for it to have been destroyed, SendMessage below should return 0.
2161 {
2162 // This is done because the vast majority of people wouldn't want to have to worry about it.
2163 // They can always use DllCall() if they want to share the same HICON among multiple parts of
2164 // the same bar, or among different windows (fairly rare).
2165 HICON hicon;
2166 int part_count = (int)SendMessage(mStatusBarHwnd, SB_GETPARTS, 0, NULL); // MSDN: "This message always returns the number of parts in the status bar [regardless of how it is called]".
2167 for (int i = 0; i < part_count; ++i)
2168 if (hicon = (HICON)SendMessage(mStatusBarHwnd, SB_GETICON, i, 0))
2169 DestroyIcon(hicon);
2170 }
2171
2172 if (IsWindow(mHwnd)) // If WM_DESTROY called us, the window might already be partially destroyed.
2173 {
2174 // If this window is using a menu bar but that menu is also used by some other window, first
2175 // detach the menu so that it doesn't get auto-destroyed with the window. This is done
2176 // unconditionally since such a menu will be automatically destroyed when the script exits
2177 // or when the menu is destroyed explicitly via the Menu command. It also prevents any
2178 // submenus attached to the menu bar from being destroyed, since those submenus might be
2179 // also used by other menus (however, this is not really an issue since menus destroyed
2180 // would be automatically re-created upon next use). But in the case of a window that
2181 // is currently using a menu bar, destroying that bar in conjunction with the destruction
2182 // of some other window might cause bad side effects on some/all OSes.
2183 ShowWindow(mHwnd, SW_HIDE); // Hide it to prevent re-drawing due to menu removal.
2184 ::SetMenu(mHwnd, NULL);
2185 if (!mDestroyWindowHasBeenCalled)
2186 {
2187 mDestroyWindowHasBeenCalled = true; // Signal the WM_DESTROY routine not to call us.
2188 DestroyWindow(mHwnd); // The WindowProc is immediately called and it now destroys the window.
2189 }
2190 // else WM_DESTROY was called by a function other than this one (possibly auto-destruct due to
2191 // being owned by script's main window), so it would be bad to call DestroyWindow() again since

Callers 2

GuiWindowProcFunction · 0.80
~ScriptMethod · 0.80

Calls 2

RemoveGuiFromListFunction · 0.85
ExitIfNotPersistentMethod · 0.80

Tested by

no test coverage detected