5

なぜSetWindowLong(myForm.hWnd, GWL_HWNDPARENT, parentHwnd)ハングするのですか?

これらの 3 つの手順を実行することで、この問題を一貫して再現できます。

  1. .NET フォームを作成する
  2. WaitWindow COM オブジェクトを初期化し、COM オブジェクトで ShowWindow を呼び出し、.NET フォーム ハンドルを渡します。
  3. VB6 で SetWindowLong メソッドを呼び出します

C# Windows アプリケーション (ハング)

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# コンソール アプリケーション (ハングしない)

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

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

VB6 コード スニペット

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

本当に助けていただければ幸いです:)

編集

親を変更するために SetWIndowLong を呼び出すべきではないことは理解していますが、.NET フォーム ハンドルが使用されている場合にのみハングする理由を理解しようとしています。

EDIT2

この問題は SetWindowLong に関連しているのではなく、実際のハンドル自体に関連していると思います。まだ調査中ですが、.NET から VB6 コードを呼び出すと、RPC スレッドが作成されるようです。まだよくわかりませんが、クロススレッドの問題と関係があると感じています。

4

3 に答える 3

3

何が起こっているのか、問題を解決する方法を正確に把握することができました。[STAThread] 属性でメイン エントリ ポイントを指定しなかったため、デフォルトで MTA に設定されていました。これは、VB6 コードを呼び出したときに、RPC コールバック スレッドを作成し、UI が実行されるメイン スレッドへの呼び出しをマーシャリングしなかったことを意味します。

ピーター・モーテンセンはこれについて良い説明を書いています:

STA モデルは、スレッド セーフではない COM オブジェクトに使用されます。つまり、それらは独自の同期を処理しません。これの一般的な用途は、UI コンポーネントです。そのため、別のスレッドがオブジェクトと対話する必要がある場合 (フォームのボタンを押すなど)、メッセージは STA スレッドにマーシャリングされます。Windows フォーム メッセージ ポンピング システムは、この例です。

于 2012-04-19T19:39:26.767 に答える
3

MSDNのドキュメントには明確に記載されています

子ウィンドウの親を変更するために、GWL_HWNDPARENT インデックスを指定して SetWindowLong を呼び出してはなりません。代わりに、SetParent 関数を使用してください。

于 2012-04-18T19:55:27.870 に答える
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.

于 2012-04-19T17:58:16.877 に答える