2012-04-18 14 views
3

* SetWindowLong(myForm.hWnd、GWL_HWNDPARENT、parentHwnd)*がハングするのはなぜですか?SetWindowLong Hanging

この3つのステップを一貫して再現できます。通過.NET形態はVB6で

  • を処理しながら

    1. Initalizeを
    2. WaitWindow COMオブジェクトを.NETフォームを作成し、

    SetWindowLong関数のメソッドを呼び出すCOMオブジェクト上のShowWindowを呼び出すCの# Windowsアプリケーション(ハング)

    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 
    

    本当にあなたの助けをいただければ幸いです:)

    EDITを

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

    EDIT2

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

  • +1

    注:これは既存のシステムの一部であり、この特定の条件まで「細かい」作業を行っているため、コードのVB6部分を更新できません。 – silentfrost

    答えて

    3

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

    ピーター・モーテンセンは、このことについてgood explanationを書いた:

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

    2

    MSDNのドキュメントは明らかにあなたが子ウィンドウの親を変更するにはGWL_HWNDPARENTインデックスとSetWindowLong関数を呼び出すことはできません

    を言います。代わりに、SetParent関数を使用します。

    +0

    私はドキュメンテーションを読みましたが、なぜあなたはそれを呼び出すべきではないのかを述べていません。多くのモジュールが参照する既存のコードであるため、VB6コードを変更できないということを忘れてしまいました。私はそれが.NETのフォームハンドルを渡さない限り、なぜ動作するのか不思議です。 – silentfrost

    +0

    と表示される可能性があります。 windbgを使って各スレッドのスタックダンプを取得してみてください。 http://blogs.msdn.com/b/oldnewthing/archive/2007/12/28/6882760.aspx – John

    +3

    MSもこれを行うことはできないと説明する必要はありません。彼らはあなたにそれをしないように言うので、そうしないでください。 –

    1

    これは64ビットシステムで実行していますか?あなたのVB6アプリケーションは32ビットアプリケーションですか?このシナリオに該当する場合は、なぜRPC呼び出しが作成されているのかを説明し、という違法な理由が説明されます。ハックが機能していません。この場合、悪いニュースは、あなたがそれを動作させる方法が今あるということです。

    また、.Netコントロールmay change during the lifetime of the controlの下にあるウィンドウのハンドルがあることに注意する必要があります。この問題については、this questionをご参照ください。

    +0

    私はWindows XP SP3 32ビットですべてを動かしています。神に感謝します...彼のプロジェクトにはすでに頭痛があります。しかし、提案をありがとう。 – silentfrost

    関連する問題