オーナードローボタンはデフォルトにできない?

[戻る]
K 2007/07/27(金) 20:52:24
グループ化した複数のボタンは、
tabキーでフォーカスを移動することができます。
この時、フォーカス矩形だけでなくデフォルトボタン(?)も移動します。
XPだと青い枠線、クラシックだと黒い枠線のことです。

ところが、標準のボタンとオーナドローボタンを混在させると、
フォーカス矩形は順番に移動するのですが、
デフォルトボタンの矩形が正しく移動しません。

オーナドローのWM_DRAWITEMでODS_DEFAULTをチェックしてもONならず、
次のボタンにデフォルトボタンが移動してしまいます。

具体的に書きます。A,B,Cの3つのボタンがあるとします。
A, B:標準ボタン, C:オーナードローボタン
以下は、TABを押すごとに1,2,3・・・と進んでいきます。

1.Aにフォーカスとデフォルトボタン
2.Bにフォーカスとデフォルトボタン
3.Cにフォーカス、Aにデフォルトボタン
4.Aにフォーカスとデフォルトボタン
(以下繰り返し)

以上のように、3のところでCをとばしてAがデフォルトボタンになってしまいます。
3の状態でEnterを押すと、Aのボタンが反応し、
Spaceを押すとCのボタンが反応してしまいます。

オーナードローボタンはデフォルトボタンにすることができないのでしょうか?

オレンジフィッシュ 2007/07/28(土) 00:44:40
>オーナードローボタンはデフォルトボタンにすることができないのでしょうか?
僕はボタンのスタイルで無理だと思っているけど。
定数の BS_DEFPUSHBUTTON、BS_OWNERDRAW はどれか1つしか指定できないので。
参考になるかな。
http://www.hey-to.net/ML-archive/vcppML/1998/msg02373.html

wclrp ( 'o') [HomePage] 2007/07/28(土) 10:06:07
簡単にはできないね。

自分がデフォルトボタンなのかどうか内部フラグで覚えて置くようにする。

WM_GETDLGCODEにたいして
オーナードローじゃなくて普通のプッシュボタンを同じ動作を演出する。

一般にウィンドウスタイルが変更されたことを検出できないけど
ダイアログでデフォルトプッシュボタンを変更するときだけ
メッセージで通知される。
流石にウィンドウスタイルが変更されたことに気がつかないと
困るから特別な処置なんでしょうね。
本当にウィンドウスタイルが変更されると
オーナードローじゃなくなってしまうので内部フラグを変更するだけで
ウィンドウスタイルが変わるのを阻止する。

オーナードローのときは内部フラグで太枠を描画するか判断する。

などを行えばできるかもしれないが
他にもしなければいけないことがあるかもしれない。
たぶんやったことある人がいると思うので探してみたら。
オーナードローは面倒だよな。

2007/07/28(土) 19:46:41
この場合、オーナードローではなく、サブクラスを使えばどうにかならないでしょう
か。
コントロールのWndProcをSetWindowLongで置き換えることで実現できます。
これも、結構面倒な方法かも知れませんが…。

K 2007/07/29(日) 13:51:52
[[解決]]
書いていませんでしたが、開発環境はVC2005です。
hoverで表示を切り替えるため、サブクラス化したうえでオーナードローしています。

オレンジフィッシュさんやwclrp ( 'o')さんの情報などを参考に、
Enterキーの動作をダイアログから横取りしたりして試行錯誤していたのですが、
DM_SETDEFIDというメッセージを見つけました。

フォーカスを持っているオーナードローボタンはデフォルトである、
という前提で以下のようにしました。

・オーナードローボタンのWM_SETFOCUSで親ダイアログにDM_SETDEFIDを送る。
 自分自身をデフォルトボタンに指定します。
・WM_DRAWITEMで、フォーカスがあればデフォルト描画。

DM_SETDEFIDの効果は一時的なようで、TABキーでちゃんと次のボタンにデフォルトが移
動します。
今のところ問題なさそうなので、とりあえずこれで行きたいと思います。

古いスレッドには追加発言できません。