VC6 SP6 MFC WinXP Proで
CButton派生クラスを作成し、その中で
グループボックスをオーナードローしています。
今、そのオーナードローしたグループボックスの上に
MFC標準のコンボボックスコントロールを重ねようと
しています。
双方ともウィンドウ生成時に動的に作成するものなのですが、
コントロールを作成する順番に関わらす、
常にコンボボックスの上にオーナードローしている
グループボックスの枠線が重なってしまいます。
これを回避し、グループボックスの枠線の上に
コンボボックスコントロールが作成されるように
するにはどうしたらいいのでしょうか。
ご存知の方、どうぞご教授下さい。
Zオーダーを設定してあげたらどうなるでしょうか。
たとえば CWnd::SetWindowPos で
囚人様 回答ありがとうございます。
SetWindowPosを使用し、
グループボックスをCWnd::wndBottomに、
コンボボックスをCWnd::wndTopMostに設定してみましたが
現象は変わりませんでした。
#オーナードローグループボックスのサンプルコードを
#あまり見かけないのはこの辺に理由があるのでしょうか?
> 双方ともウィンドウ生成時に動的に作成するものなのですが、
コンボボックスの親をグループボックスにすることはできますか?
> #オーナードローグループボックスのサンプルコードを
> #あまり見かけないのはこの辺に理由があるのでしょうか?
多分違うと思う。ただの枠だと思い気にする人が少ないんだと思う。
でも↓ここに3つあった。
http://www.codeguru.com/cpp/controls/controls/
1. WS_TABSTOP属性をつけない
2. WM_GETDLGCODEメッセージをハンドルして、DLGC_STATICを返す
3. WM_NCHITTESTメッセージをハンドルして、HTTRANSPARENTを返す
私の場合これでうまくいきました。
お試しください。
たいちう様、Kerry様 回答ありがとうございます。
たいちう様
>コンボボックスの親をグループボックスにすることはできますか?
確かにそうすることでコンボボックスがグループボックスの手前に来ます。
ですが、今回は動的にコントロールを作成した後、その作成した
コントロールをマウスによって移動できるようにしています。
作成したコンボボックスコントロールの移動後の位置が2つのグループボックスに
またがっていた場合など、親ウィンドウの識別が困難な状況が考えられるため
親ウィンドウを切り替える操作は少々やりづらかったりします。
どうしても他に方法がない場合はなんとかするしかないのですが。
>多分違うと思う。ただの枠だと思い気にする人が少ないんだと思う。
>でも↓ここに3つあった。
> http://www.codeguru.com/cpp/controls/controls/
見てみました。が、どれもダイアログエディタ上にあらかじめ
グループボックスが配置されていたり、親ウィンドウのクラス内に実体の宣言が
必要だったりで、動的に作成することを考えて作られたものではありませんでした。
(ムリヤリ動的に作成してみましたがちゃんと描画されなかったり)
Kerry様
>1. WS_TABSTOP属性をつけない
>2. WM_GETDLGCODEメッセージをハンドルして、DLGC_STATICを返す
>3. WM_NCHITTESTメッセージをハンドルして、HTTRANSPARENTを返す
1.は満たしていたので残りの2.および3.を実装してみましたが現象が
変わりませんでした。
#そもそもの描画の仕方がいけないのでしょうか。
#DrawItemの中で描画してはいけないとか・・・?
私は試してませんが、CWnd::SetWindowPos()の最初の引数に、
CWnd*を使うとどうなりますか?
つまり、全てのグループボックスについて、
groupbox.SetWindowPos(&combo,...); とするのは?
> #そもそもの描画の仕方がいけないのでしょうか。
> #DrawItemの中で描画してはいけないとか・・・?
描画の仕方はともかく、そもそも仕様に無理があるのではないかと。
そのようなアプリケーションを見たことがありますか?
もっと自然な実装にすることは無理ですか?
普通じゃないものを作るにはそれだけの深い知識と
手間暇が必要です。頑張って作ってみても、実行環境の
違いに弱かったり、保守が大変だったり、本来必要でない
苦労を強いられます。
プログラマに選択権があるとは限らないけどね。
コントロールを移動したときにZオーダーが変わっている、
ということはないですかね?
>描画の仕方はともかく、そもそも仕様に無理があるのではないかと。
>そのようなアプリケーションを見たことがありますか?
>もっと自然な実装にすることは無理ですか?
使用のされ方は若干違いますが、動きとしては
VC6のダイアログエディタに似ていると思います。
オーナードローしてるかどうかはともかく
あれはうまくいってますよね。
コントロールを配置した後移動する、というのは
画面をデザインするアプリケーションでは
はずせない仕様だと思います。
先ほど挙げた例はその際に当然起こりうる状態の一例です。
標準のコントロールで作成したものは八割方できていて、
その上でデザインを改善していくために
既存の標準コントロールを独自のオーナードローコントロールに
変えていく、ということになって今回の現象に直面したというわけです。
>プログラマに選択権があるとは限らないけどね。
#仕様に関する決定権がないのは事実ですけど。
VC++6ならば、SPY++で確認できると思いますが、
ダイアログエディタにコントロールは張り付いていません。
VC++6の開発者にとっては、CViewに描かれたダイアログの絵です。
(本当にCViewが使われているかどうかは知りませんが、
コントロールではないということ)
同様に、デザイン時と実行時を別物と考えてはいかがでしょうか?
コントロールとしての機能を持ったまま自由に動かす仕組みを
作らないで済みますよ。
無責任に書きましたが、既に八割がたできているなら、
私の書いたことは今更仕方がないですね。
思いつきですが、2つのグループボックスも親子関係にしてしまっては?
全てのコントロールは、希望するZオーダーの順に直系になっている。
たいちうさんも言われていますけれど、
ダイアログエディタ上のグラフィックが単なる絵であるならば、
そもそも廿楽さんの言われている問題も起こらないような気もしますし。
ダイアログのテスト表示の時は確かにコントロールが生成されているようですが、
実際のデザイン時は単なる絵として描画されているのではないでしょうか。
そもそもコントロールの描画部分のソースはMSが持っているわけですから
それを持ってきてまったく同じ描画をして見せるのは難しくないような
気がします。
うわっ、ごめんなさい。
既にたいちうさんが出来ちゃってるのに書いても仕方ないと書かれてました。
うーむ。
新しくコントロールを起こした時点で全てのコントロールを親ウインドウを
土台にしてZオーダーを張りなおさないと駄目かもしれませんね。
その辺の描画順の管理がどうなっているのかいまいち解りにくいですし。
そういえば、タブオーダーってダイアログに対して
コード上で直接指定できましたっけ?
タブオーダーが問題なんて事は無いですか?
途中、Kerryさんの書き込みを見逃しておりました。失礼しました。
>コントロールを移動したときにZオーダーが変わっている、
>ということはないですかね?
この現象は移動後に限り起きるわけではなく、
初期表示の状態で、移動をまったくしていないときも再現します。
いろいろ調べてみましたが、どうやらVC6.0では
タブオーダー=Zオーダーとみなしてもよさそうな感じです。
そうすると、SetWindowPosによるZオーダーの変更で
現象が改善されなかったことを考えると、
Zオーダーやタブオーダーの変更だけではいけないのかなと。
画像で描画する方法は、画面をデザインするときは
現象を回避できそうなのですが、
実際にデザインを使用する側でコントロールを作成するため、
そのときに同様の現象が起きることが予想されます。
ということで、この際に抜本的な解決をしておこうということになりました。
ということは必然的に親子関係を全てのコントロールに
持たせることになるのでしょうか・・・
#なお、同じクラスでチェックボックスやボタンも描画しているのですが
#そちらはちゃんと望んだとおりの重なり方をしてくれます。
#グループボックスだけが変・・・混乱中ですー