オーナー設定したウィンドウの作成個数には限界がある!

こんにちは、Platform SDK (Windows SDK) サポートチームです。

ウィンドウの Z オーダーを制御したい場合等、ウィンドウ作成時に、オーナー ウィンドウを設定することがあると思います。

今回は、このオーナー設定したウィンドウを作成する場合に、作成したウィンドウの数によっては、予期せぬ動作となる現象について、お知らせします。

現象

ウィンドウに対してオーナーの設定を行うと、所有される側のウィンドウ (オウンド ウィンドウ) が、所有する側のウィンドウ (オーナー ウィンドウ) の前面に必ず表示されるようにすることができます。
たとえば、Windows フォーム アプリケーションの場合は、Owner プロパティや、AddOwnedForm メソッド、RemoveOwnedForm メソッドによって、設定可能です。

しかしながら、オーナー設定したウィンドウ数が 50 個以上になると、ウィンドウ間の Z オーダーが不正な状態になります。具体的には、オウンド ウィンドウの前面にオーナー ウィンドウが出たり、予期せぬウィンドウが前面に表示されたりします。

原因

本現象は、Windows XP 以降の OS における制限に起因します。

OS 側では、オーナー ウィンドウ数の最大値として、50 個の制限値を定義しています。そして OS 内部では、オーナー ウィンドウの深度をカウントしており、50 個に達した場合には、オーナー ウィンドウの設定に失敗します。
なお、オーナー ウィンドウの設定に失敗した場合も、OS 内部では SetLastError 関数で拡張エラー コードを設定していないため、アプリケーション側ではエラーは発生しません。

これは OS 側で定義している制限であるため、MFC アプリケーションや Windows フォーム アプリケーション等、アプリケーションのフレームワークに限らず、現象が発生します。

対処方法

アプリケーション側の対処方法としては、ウィンドウ作成数に対して 50 個未満で閾値を設けて、オーナーの大元を変更することにより対処可能です。

上記対策により、50 個以上のウィンドウを作成してオーナー設定する時も、意図した Z オーダーとすることが可能となります。

しかしながら、オーナー設定によって OS 内部では多くの再帰処理が発生しています。
このため、スタック オーバーフローにより、ウィンドウが作成できない場合もありますので、ご注意ください。

対象製品

Windows XP 以降の OS