PhotoShopのツールバーのようにフォーカスを失わない子ウインドウにするには?


へろ  2007-03-01 16:51:23  No: 135585

お世話になります、開発環境はVB6です。

一般に言うツールバー風の動作をするサブフォームを作成しようとしています。
サブフォームはメインフォームより常に前面に表示され、タスクバーに名前が出ないものです。
ここまではよいのですが、質問はサブフォームがアクティブである時、メインフォームが非アクティブになるのを防ぎたいというものです。

動作的にはPhotoshopの「レイヤーウインドウ」のような振る舞いを考えています。
このレイヤーウインドウがユーザーに操作されフォーカスを得ている状態でも本体のPhotoshopやその他のサブウインドウは非アクティブになりません。
このように動作させたいのですが、どうもうまくいかず悩んでいます。

ウインドウのスタイル設定でそのような動作をさせることが出来るのではと考え、APIのSetWindowLongで以下のように指定したりいろいろパターンを当たっていますが、やはりメインフォームは非アクティブになってしまいます。

Call SetWindowLong(frm.hWnd, GWL_EXSTYLE, GetWindowLong(frm.hWnd, GWL_EXSTYLE) Or WS_EX_TOOLWINDOW)

おそらく、メインフォームに対する子、あるいは一部とみなされる様な設定をサブフォームに与えてやれば質問の動作になるのではないかと思っているのですが、的外れでしょうか?
もしくは、それだけでは実現しきれないでしょうか?

なおフォトショップのツールバーウインドウのスタイルは、Spy++で見たところ以下のようになっていました。

WS_POPUP Or WS_VISIBLE Or WS_CLIPSIBLINGS Or _
WS_BORDER Or WS_OVERLAPPED Or WS_EX_LEFT Or _
WS_EX_LTRREADING Or WS_EX_RIGHTSCROLLBAR Or WS_EX_TOOLWINDOW

これをそのままサブフォームにセットしても思う動作にはなりませんでした。

正直私は、フォアグラウンドウインドウ、アクティブ/非アクティブウインドウ、トップレベルウインドウ、オーナーウインドウ、オーナー付きウインドウ、親ウインドウ、子ウインドウ etc... といったそれぞれがどのようなものであるかを少々混同しているかもしれません。(C/C++はさっぱりわからない者で^^;

ちなみに、このサブフォームは最終的にメインフォームの中にSetParentでドッキングしたりフロートさせたりもする予定です。

以上です。よろしくお願いします。


通ってみた  2007-03-02 00:58:16  No: 135586

案)
1.サブフォームで何かをした後、必ずメインフォームをアクティブにする

2.サブフォームからマウスカーソルが外れたらメインフォームをアクティブにする


へろ  2007-03-02 05:50:32  No: 135587

アドバイスありがとうございます。

案1では、例えばサブフォームマルチラインのテキストボックスがありそれを操作している最中はメインフォームが非アクティブ(つまりタスクバーで何も選択されていない)状態になってしまいます。
案2も同様です。

サブフォームが操作される時も、見かけ上メインフォームが非アクティブにならないように(そうMDIフォームの子フォームを操作しているように)したいのですが、これは難しいのかもしれません…。

その後、メインと親子関係を付けた上で、WS_EX_MDICHILDを付けてやれば、MDIのような動作になるかと考えましたが、どうもフォーム生成時にしかこのスタイルは付加出来ないようでした。

引き続き方法を模索しております。助言ありましたらお願いいたします。


へろ  2007-03-02 08:02:28  No: 135588

あれから発想を逆転させて、MDIをベースにしてみました。

メインをMDI親フォームとして作成し、サブフォームをMDIChild=Trueとしました。
それぞれのウインドウをShowした状態で、APIのSetParentでサブフォームの親(おそらくオーナー)を0として削除しました。

しかし、やはりダメでした。
サブフォームを選択するとメインフォームは非アクティブとなってしまいます。


通ってみた  2007-03-02 08:22:54  No: 135589

メインフォーム内にサブフォームがある(はみ出ない)という仕様であれば、ピクチャーボックスでフォーム自体を自作するとか

ピクチャーボックスをコンテナにして、その中にパーツを組み込めば問題ないと思います
掴んでウインドウを移動させたりするのが多少大変だと思いますが・・・


へろ  2007-03-02 09:02:11  No: 135590

返信ありがとうございます。
フォームの自作は考えた(APIで出来そうだというところまで)のですが、
やはりメインフォーム外にも出したいと思い、そうするとサブクラス化でウインドウメッセージを受け取り自力で再描写・操作を行わなければなりません。

簡単に汎用的に使用できるようにしたいので、サブフォームを増やす時は
単にフォームとして設計すればそのまま利用できる、という形にしたいのです。
(サブフォームは開発の過程で新たなデザインが増えていく予定です)

同じ理由から、開発が難航するサブクラス化の手法は極力避けようとしています。

また、サブフォームはデザイン時に雛形フォームとして用意しておく方法も少し考えました。
実行時にはこの雛形フォームを直接使わず、クローンを生成(フォーム内の全コントロールを列挙し見かけが全く同一のフォームを生成)して、これをサブフォームとして使うものです。

ただ、これだと雛形フォーム内にあるコードが容易にクローン出来ないため、断念しました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加