//Workaround for .NET bug: When showing context menu in inactive thread, immediately closes it. Not always, but eg after showing in active. // In some cases vice versa: when showing in active thread after showing in inactive. // It happens when the .NET message loop receives any posted message and it is handled by ToolStripManager.ModalMenuFilter nested class. // If then ModalMenuFilter._lastActiveWindow != GetActiveWindow(), closes menu. But _lastActiveWindow is not updated in inactive thread. void _Workaround1() { try { var ty = typeof(ToolStripManager).GetNestedType("ModalMenuFilter", BindingFlags.NonPublic); var pi = ty.GetProperty("Instance", BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Static); var fi = ty.GetField("_lastActiveWindow", BindingFlags.GetField | BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance); var mmf = pi.GetValue(null); fi.SetValue(mmf, new HandleRef(null, Api.GetActiveWindow().Handle)); } catch (Exception ex) { ADebug.Print(ex); //A simpler workaround. But then stops working .NET menu autoclosing, submenu on mouse move, menu keyboard navigation (after activating a window of this thread), etc. _cancelClosing = true; ATimer.After(1, _ => _cancelClosing = false); } }
private void _bClick(object sender, EventArgs e) { if (!(_lb.SelectedItem is AToolbar tb)) { return; } if (tb._c.IsDisposed) { ADialog.Show("Closed", owner: this); return; } var w = tb._c.Hwnd(); var r = w.Rect; if (sender == _bShow) { if (AScreen.IsInAnyScreen(r)) { r.Inflate(2, 2); var osd = new AOsdRect { Rect = r, Color = 0xff0000 }; osd.Show(); ATimer.After(1000, _ => osd.Dispose()); } else { ADialog.Show("Offscreen", "Rectangle: " + r.ToString(), owner: this); } } else if (sender == _bMove) { if (!w.IsVisible && !ADialog.ShowOkCancel("Hidden", "Move this hidden toolbar?", owner: this)) { return; } var xy = AMouse.XY; w.MoveLL(xy.x, xy.y); var w2 = this.Hwnd(); if (!w.ZorderIsAbove(w2)) { w.ZorderAbove(w2); } } }