5

Why does SetWindowLong(myForm.hWnd, GWL_HWNDPARENT, parentHwnd) hang?

I can recreate this problem consistently doing these three steps.

  1. Create the .NET Form
  2. Initalize the WaitWindow COM object, call ShowWindow on the COM object while passing the .NET Forms Handle
  3. In VB6 invoke the SetWindowLong method

C# Windows Application (Hangs)

private static void Main(string[] args)
{
      Form form = new Form();
      form.Show();

      Interop.WaitWindow waitWindow = new Interop.WaitWindow();
      waitWindow.ShowWindow(form.Handle.ToInt32(), Language.RISEnglish);
}

C# Console Application (Doesn't Hang)

private static void Main(string[] args)
{
      IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;     

      Interop.WaitWindow waitWindow = new Interop.WaitWindow();
      waitWindow.ShowWindow(handle.ToInt32(), Language.RISEnglish);
}

VB6 Code Snippet

Public Sub ShowWindow(ByVal parentHwnd As Long, ByVal language As Language)

    SetWindowLong(myForm.hWnd, GWL_HWNDPARENT, parentHwnd)  'Hangs Here
    CenterWindow (parentHwnd)

    myForm.ShowRetrieving (language)
    myForm.Show (vbModal)
End Sub

Really would appreciate your help :)

EDIT

I do understand that SetWIndowLong shouldn't be called to change the parent but I'm trying to understand why it hangs only when a .NET form handle is used.

EDIT2

I now believe the issue is not related to SetWindowLong but the actual handle itself. I'm still investigating but it appears that when I call the VB6 code from .NET it creates an RPC thread. I'm not sure yet but I have a feeling it has something to do with a cross-threading issue.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
silentfrost
  • 302
  • 2
  • 10
  • 1
    Note: I'm unable to update the VB6 portion of the code as this is part of an existing system and has been working "fine" up until this specific condition. – silentfrost Apr 18 '12 at 20:18

3 Answers3

3

The MSDN documentation clearly says

You must not call SetWindowLong with the GWL_HWNDPARENT index to change the parent of a child window. Instead, use the SetParent function.

John
  • 5,561
  • 1
  • 23
  • 39
  • I did read the documentation, although it doesn't state WHY you shouldn't call it. I forgot to mention that I'm unable to modify the VB6 code as it's existing code which many modules reference. I'm curious as to why it works unless I pass it a .NET form handle. – silentfrost Apr 18 '12 at 20:15
  • probably because this results in sending a message. Try to get a stack dump for each of the threads with windbg. See also http://blogs.msdn.com/b/oldnewthing/archive/2007/12/28/6882760.aspx – John Apr 18 '12 at 21:26
  • 3
    MS don't need to explain you can't do this. They tell you not to do it, so don't. – David Heffernan Apr 18 '12 at 21:50
3

I managed to figure out exactly what was going on and how to fix the problem. I didn't specify my main entry point with the [STAThread] attribute so it was defaulting to MTA instead. This meant when I called the VB6 code it created a RPC Callback Thread and didn't marshall the call to the main thread where the UI executes.

Peter Mortensen wrote a good explanation about this:

The STA model is used for COM objects that are not thread safe. That means they do not handle their own synchronization. A common use of this is a UI component. So if another thread needs to interact with the object (such as pushing a button in a form) then the message is marshalled onto the STA thread. The windows forms message pumping system is an example of this.

Community
  • 1
  • 1
silentfrost
  • 302
  • 2
  • 10
1

Are you running this in a 64 bit system? is your VB6 application a 32 bits application? If you fall in this scenario, it would explain why an RPC call is being created and it would explain why your illegal hack it is not working. If this is the case, bad news is that there is now way you can make it work.

You should also be aware that the underling windows handle of a .net control may change during the lifetime of the control. See also this question in SO for a discussion on this matter.

Community
  • 1
  • 1
yms
  • 10,361
  • 3
  • 38
  • 68
  • I'm running everything in Windows XP SP3 32 bit, thank god... Already have enough headaches with his project :p. Thanks for the suggestion though. – silentfrost Apr 19 '12 at 18:07