We are developing a mixed c++ application were we host a usercontrol within an MFC CWinFormsView. This control contains UltraToolbars with PopupMenuTool dropdown menus.
We are experiencing problems with the dropdown menus remaining sticky on the screen when the mouse clicks outside the menu or the form is moved or closed. Furthermore, the Escape doesn't work for closing the menus or any other shortcut key assigned to a menu entry. We also have a WinNavigationBar that has the same problems when a dropdown for a location is opened.
Could you please advise?
Carlo
I can't see how that would affect the UltraToolbarsManager. Just to make sure of a few things, you are calling Utilities.ForceNativeMessageFilter and you are using the derived toolbars manager I posted above, correct? Specifically, is the ActiveControlOfActiveForm override returning something non-null when the shortcut is pressed?
Mike I finally think I have found what causes the Infragistics Hotkeys to not register. If Microsoft Outlook is open when you launch the program with the hotkeys it seems to block the registration of those hotkeys. Close Outlook and launch the program and all is well.
This issue has been driving my users nuts for over a year and we think we've finally stumbled on the cause of the problem. Finally!
Now only if Infragistics can solve the rest of the riddle.
Out of curiosity, has anyone tried this solution? If so, did it fix the problem? I'd also like to know just in case someone else has this problem in the future. Thanks for any input.
I'm not sure if anyone is doing this already, but there are some protected members that can be overridden on the toolbars manager that may help with this. They were added to help use a toolbars manager when it was hosted on a web page in Internet Explorer, and they may help in this situation too. Try overriding these members with the implementations described in each of their comments to see if it fixes the issue:
ActivateForm()ActiveControlOfActiveFormFormWindowStateIsControlOnActiveForm( Control control )IsFormActiveOnFloatingToolbarWindowShown( FloatingToolbarWindowBase floatingToolbarWindow )
Also, track the activation of the VB6 window and call these protected methods at the appropriate times:
OnFormActivated()OnFormDeactivate()
Here is a partial implementation that may help get you started. Also, you don't have to use a timer to track the form activation.
public class MyToolbarsManager : UltraToolbarsManager{ private bool isFormActive; private Timer timer;
protected override void Dispose( bool disposing ) { base.Dispose( disposing );
if ( this.timer != null ) { this.timer.Enabled = false; this.timer.Dispose(); this.timer = null; } }
protected override void OnEndInit() { base.OnEndInit();
this.timer = new Timer(); this.timer.Interval = 100; this.timer.Tick += new EventHandler( timer_Tick ); this.timer.Enabled = true; }
private void timer_Tick( object sender, EventArgs e ) { Control dockWithinContainer = this.DockWithinContainer;
if ( dockWithinContainer == null ) return;
bool isFormNowActive = IsControlOnActiveForm( dockWithinContainer );
if ( isFormNowActive != this.isFormActive ) { this.isFormActive = isFormNowActive;
if ( this.isFormActive ) this.OnFormActivated(); else this.OnFormDeactivate(); } }
protected override bool ActivateForm() { bool succeeded = base.ActivateForm();
if ( succeeded ) return true;
Control dockWithinContainer = this.DockWithinContainer;
if ( dockWithinContainer == null || dockWithinContainer.IsHandleCreated == false ) return false;
IntPtr parentHwnd = NativeWindowMethods.FindTopLevelWindow( dockWithinContainer.Handle );
if ( parentHwnd == IntPtr.Zero ) return false;
NativeWindowMethods.SetActiveWindow( parentHwnd ); return true; }
protected override Control ActiveControlOfActiveForm { get { Control control = base.ActiveControlOfActiveForm;
if ( control != null ) return control;
return Control.FromChildHandle( NativeWindowMethods.GetFocus() ); } }
protected override FormWindowState FormWindowState { get { FormWindowState windowState = base.FormWindowState;
if ( windowState != FormWindowState.Normal ) return windowState;
// TODO: Get the window state and return it return windowState; } }
protected override bool IsControlOnActiveForm( Control control ) { bool isOnActiveForm = base.IsControlOnActiveForm( control );
if ( isOnActiveForm ) return true;
IntPtr activeForm = NativeWindowMethods.GetForegroundWindow();
IntPtr controlHandle = control.Handle;
while ( controlHandle != IntPtr.Zero ) { if ( controlHandle == activeForm ) return true;
controlHandle = NativeWindowMethods.GetParent( controlHandle ); }
return false; }
protected override bool IsFormActive { get { bool isFormActive = base.IsFormActive;
if ( isFormActive ) return true;
IntPtr activeForm = NativeWindowMethods.GetForegroundWindow(); IntPtr form = NativeWindowMethods.FindTopLevelWindow( dockWithinContainer.Handle );
while ( activeForm != IntPtr.Zero ) { if ( activeForm == form ) return true;
activeForm = NativeWindowMethods.GetWindowLong( activeForm, NativeWindowMethods.GWL_HWNDPARENT ); }
return false; } }
protected override void OnFloatingToolbarWindowShown( FloatingToolbarWindowBase floatingToolbarWindow ) { base.OnFloatingToolbarWindowShown( floatingToolbarWindow );
if ( floatingToolbarWindow.Owner != null ) return;
if ( dockWithinContainer != null && dockWithinContainer.IsHandleCreated ) { try { IntPtr ownerHandle = NativeWindowMethods.FindTopLevelWindow( dockWithinContainer.Handle );
if ( ownerHandle != IntPtr.Zero ) { NativeWindowMethods.SetWindowLong( floatingToolbarWindow.Handle, NativeWindowMethods.GWL_HWNDPARENT, ownerHandle ); // TODO: If the owner is TopMost, make the floating toolbar window TopMost } } catch ( SecurityException ) { } } }}
[SuppressUnmanagedCodeSecurity]internal class NativeWindowMethods{ internal const int GWL_HWNDPARENT = -8;
[DllImport( "user32" )] internal static extern IntPtr GetFocus();
[DllImport( "user32" )] internal static extern IntPtr GetForegroundWindow();
[DllImport( "user32" )] internal static extern IntPtr GetParent( IntPtr childHwnd );
[DllImport( "user32" )] internal static extern IntPtr GetWindowLong( IntPtr hWnd, int nIndex );
[DllImport( "user32" )] internal static extern IntPtr SetActiveWindow( IntPtr hWnd );
[DllImport( "user32" )] internal static extern IntPtr SetWindowLong( IntPtr hWnd, int nIndex, IntPtr newLong );
internal static IntPtr FindTopLevelWindow( IntPtr childWindow ) { IntPtr control = childWindow;
while ( true ) { IntPtr nextControl = GetParent( control );
if ( nextControl == IntPtr.Zero ) break;
control = nextControl; }
return control; }}