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
Its funny, I haven't seen anyone have this issue before, and now it has happened twice in the past 10 days (here is the other post: http://forums.infragistics.com/forums/p/2827/17955.aspx). It appears your are having the same problem. Here is the solution that worked before:
Add a call to Infragistics.Win.Utilities.ForceNativeMessageFilter() to the constructor of the UserControl. I say to add this call to the constructor and not to the start of the application because it doesn't hurt to call this method multiple times and calling it only applies to the thread it was called on. In a multi-threaded application, you would want to make sure the the fix is applied to user controls instantiated on all threads.
Thanks Mike, that worked great for the menus sticking on the screen. However the shortcut keys or the escape key for closing the menu still don't work. Do you have any suggestions for that?
It sounds like the keys issue is unrelated. If you can create a sample demonstrating the issue, I would recommend submitting it to the support group: http://es.infragistics.com/gethelp. Also, try to give as much information as you can about the machine configuration on which it is occurring. It is possible it only occurs with a specific OS or number of processors.
I have the same problem with sticky popup menu and shortcut keys (ribbon). I believe these two issues are related since they usually happen at the same time but do not happen 100% of the time. However, the "ForceNativeMessageFilter()" does not work for me. I have reported this sticky issue several times last year without any resolution and I hope there is a fix soon since this is a serious usability issue.
Also, when this issue happens, the "tool drop down" (eg. a button tool with down arrow that would show a drop down menu) and "tool bar list drop down" (the drop down that show "Restore", "Move", "Size", "Minimize", "Maximize", "Close" menus) become sticky as well.
If the ForceNativeMessageFilter() call did not fix the issue with the menus, you may have an unrelated issue. Is your application running in a low trust environment? This may prevent message filters or subclassers from being created, which could also cause the issue with the menus.
In my case, my application is a full trust application. It is an application we use internally so it is in a very controlled environment without a lot of variables to throw in.
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; }}