0

C++ レガシ アプリケーションがあり、親の C++ アプリから COM を使用して呼び出される C# アプレットでそれを拡張しています。モーダルではないウィンドウが表示されます。さらに、これらの .NET ウィンドウは C++ アプリケーションの適切な子ではないと思います。なぜなら、EnumChildWindows はそれらを見逃し、EnumWindows はそれらを見つけるからです。ただし、親の C++ アプリを閉じると、c# ウィンドウも閉じるという点で、子供のような動作が 1 つあります。

これらすべてに関する私の基本的な問題は、ユーザーがこれらの c# アプレットのいずれかを呼び出してから、誤って親 (c++) アプリ ウィンドウをクリックすると、c# ウィンドウがバックグラウンドに落ちることです。ユーザーがこれを一番上に戻したい場合は、タスクバーのアイコンをクリックするだけでよいはずです。残念ながら、奇妙な理由で、タスクバーのアイコンを3 回クリックしなければならないことがよくあります。最初は非表示のウィンドウが一番上に表示されるはずですが、そうではありません。2 回目のクリックで非表示のウィンドウが最小化され、3 回目のクリックで正常に復元されます。

レガシーから .NET への分割を橋渡しするときに、このバグ/機能に出くわした人はいますか? C# アプレットのタスクバー アイコンの最初のクリックを傍受し、どうにかしてトップに戻るように強制できるかどうか疑問に思っています。:-)

私は次のことを実験してきました:

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

しかし、これが機能したとしても、最初のマウスクリックをインターセプトする必要があります。ご協力いただきありがとうございます!

4

2 に答える 2

1

C# ウィンドウが実際に子ウィンドウである場合、機能しますか? 親 HWND を引数として C# COM オブジェクトに渡し、PInvoke を使用して C# ウィンドウでSetParentを呼び出すことで、これを実現できる場合があります。(私はこれをやったことがありませんが、少なくとも ShowWindow とタスク バーと戦うのと同じくらい安全に思えますか?)

( SetParent のドキュメントのコメントから、子ウィンドウのウィンドウ フラグをいじる必要があるかもしれないことに注意してください。)

(C# ウィンドウの種類によっては、使用できる Handle プロパティが既に存在する場合があります。それ以外の場合は、FindWindow への PInvoke 呼び出しをこじ開けてハンドルを取得することができます。)

于 2009-12-17T00:27:55.683 に答える
0
 // 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);
     }
  }
于 2009-12-21T18:59:19.850 に答える