Question

We have a c++ legacy application and have been extending it with c# applets that are invoked using COM from the parent c++ app. They bring up windows that are not modal. Moreover, I think these .NET windows are not proper children of the c++ application, since EnumChildWindows misses them, and EnumWindows finds them. One child-like behavior remains, however, in that if you close the parent c++ app, the c# window will close as well.

My basic problem with all this is that if the user invokes one of these c# applets, then inadvertently clicks the parent (c++) app window, the c# window drops to the background. If the user wants to bring this back to the top, they should be able to just click its icon in the TaskBar. Unfortunately, for some strange reason, it is often necessary to click the TaskBar icon three times! The first time should bring a hidden window to the top, but it doesn't. The second click minimizes the hidden window, and the third restores it successfully.

Has anyone else run across this bug/feature when bridging the legacy->.NET divide? I'm wondering if I can intercept the first click on the taskbar icon for my C# applet, and somehow force it to claw its way back to the top. :-)

I've been experimenting with the following:

  [DllImport("User32.dll")]
  private static extern int ShowWindow(IntPtr hwnd, IntPtr nCmdShow);

but even if I get this working I'll still need to intercept that first mouseclick. Thanks for your help!

Was it helpful?

Solution

Would it work if the C# windows actually were child windows? It might be possible to accomplish that by passing the parent HWND as an argument to the C# COM object, and then using PInvoke to call SetParent on the C# windows. (I've never done this, but it sounds at least as safe as fighting with ShowWindow and the task bar?)

(Note from the comments in the documetation for SetParent that you might also need to fiddle with the child window's window flags?)

(Depending on the C# window type, it might already have a Handle property you can use; otherwise you could kludge a PInvoke call to FindWindow to get its handle.)

OTHER TIPS

 // Here's the code... 
 [DllImport("User32.dll")]
  static extern int GetForegroundWindow();
  [DllImport("User32.dll")]
  private static extern int SetParent(int hwndChild, int hwndParent);


  public void ShowMyFormAsChildOf ( int hwndParent )
  {
    MyForm form = new MyForm();
    form.Show(); // immediately after .Show(), it is the foreground window!
    SetWindowParent( hwndParent );
  }

  private void SetWindowParent(int parenthwnd)
  {
     if (0 != parenthwnd)
     {
        int handle = GetForegroundWindow();
        SetParent(handle, parenthwnd);
     }
  }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top