private static void UpdateHelpStack() { needStackUpdate = false; // Retrieving all windows in a z-sorted way is a "time consuming" (~ 0.05ms) and API-heavy // query, and we don't need to be that accurate. Don't do it every time. Once a second is enough. bool updateGlobalWindows = globalWindows == null || (DateTime.Now - lastGlobalWindowUpdate).TotalMilliseconds > 1000 || globalWindows.Any(f => f.IsDisposed); if (updateGlobalWindows) { lastGlobalWindowUpdate = DateTime.Now; globalWindows = EditorHelper.GetZSortedAppWindows(); } // Iterate through our list of windows to find the one we're hovering foreach (Form form in globalWindows) { if (!form.Visible) continue; if (!new Rectangle(form.Location, form.Size).Contains(Cursor.Position)) continue; Point localPos = form.PointToClient(Cursor.Position); hoveredControl = form.GetChildAtPointDeep(localPos, GetChildAtPointSkip.Invisible | GetChildAtPointSkip.Transparent); break; } Control c; HelpInfo help; // Get rid of disposed Controls c = hoveredHelpProvider as Control; if (c == null || c.IsDisposed) { hoveredHelpProvider = null; hoveredHelpCaptured = false; } // An IHelpProvider has captured the mouse: Ask what to do with it. if (hoveredHelpCaptured) { help = hoveredHelpProvider.ProvideHoverHelp(c.PointToClient(Cursor.Position), ref hoveredHelpCaptured); // Update provider's help info stack.UpdateFromProvider(hoveredHelpProvider, help); // If still in charge: Return early. if (hoveredHelpCaptured) return; } // No IHelpProvider in charge: Find one that provides help help = null; IHelpProvider lastHelpProvider = hoveredHelpProvider; foreach (IHelpProvider hp in hoveredControl.GetControlAncestors<IHelpProvider>()) { c = hp as Control; help = hp.ProvideHoverHelp(c.PointToClient(Cursor.Position), ref hoveredHelpCaptured); hoveredHelpProvider = hp; if (help != null || hoveredHelpCaptured) break; } // Update help system based on the result. if (lastHelpProvider != hoveredHelpProvider) stack.UpdateFromProvider(lastHelpProvider, hoveredHelpProvider, help); else if (hoveredHelpProvider != null) stack.UpdateFromProvider(hoveredHelpProvider, help); }
private static void UpdateHelpStack() { needStackUpdate = false; foreach (Form f in EditorHelper.GetZSortedAppWindows()) { if (!f.Visible) continue; if (!new Rectangle(f.Location, f.Size).Contains(Cursor.Position)) continue; Point localPos = f.PointToClient(Cursor.Position); hoveredControl = f.GetChildAtPointDeep(localPos, GetChildAtPointSkip.Invisible | GetChildAtPointSkip.Transparent); break; } Control c; HelpInfo help; // Get rid of disposed Controls c = hoveredHelpProvider as Control; if (c == null || c.IsDisposed) { hoveredHelpProvider = null; hoveredHelpCaptured = false; } // An IHelpProvider has captured the mouse: Ask what to do with it. if (hoveredHelpCaptured) { help = hoveredHelpProvider.ProvideHoverHelp(c.PointToClient(Cursor.Position), ref hoveredHelpCaptured); // Update provider's help info stack.UpdateFromProvider(hoveredHelpProvider, help); // If still in charge: Return early. if (hoveredHelpCaptured) return; } // No IHelpProvider in charge: Find one that provides help help = null; IHelpProvider lastHelpProvider = hoveredHelpProvider; foreach (IHelpProvider hp in hoveredControl.GetControlAncestors<IHelpProvider>()) { c = hp as Control; help = hp.ProvideHoverHelp(c.PointToClient(Cursor.Position), ref hoveredHelpCaptured); hoveredHelpProvider = hp; if (help != null || hoveredHelpCaptured) break; } // Update help system based on the result. if (lastHelpProvider != hoveredHelpProvider) stack.UpdateFromProvider(lastHelpProvider, hoveredHelpProvider, help); else if (hoveredHelpProvider != null) stack.UpdateFromProvider(hoveredHelpProvider, help); }