デフォルトボタン表示を無効にしたい – プログラミング – Home

デフォルトボタン表示を無効にしたい
 
通知
すべてクリア

[解決済] デフォルトボタン表示を無効にしたい


薙
 薙
(@薙)
ゲスト
結合: 8年前
投稿: 6
Topic starter  

環境:MFC、VS2012、Win7

Enterキーを無効として、スペースだけ有効なボタンを
ダイアログに張り付けています。

リソースから全てのデフォルトボタンは無効としているのですが、
ボタンをクリックすると青枠表示となってしまい
デフォルトボタンのように表示されてしまいます。

Enterキーは無効としているため、クリックしても青枠が表示されないように
したいのですが、どのようにすれば良いでしょうか?


引用未解決
トピックタグ
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 4年前
投稿: 828
 

WindowsOSが提供するコントロールをまんま使用している限りできません。
従って、
 1.キーボードフォーカス、
 2.デフォルト設定
 3.マウスホバー
等に、一切反応しないようにボタンをサブクラス化するか、
カスタムドローで済んでしまうかもしれません。
確実に行うには、ボタン自体を自作するのがよいでしょう。

ただし、
WindowsOSに対して詳細な知識をもっていれば、それほど手間はかかりませんが、、
そうでない場合は、労多くして・・ということになるでしょう。
一般に、Windowの標準動作と異なる動作をさせることは、
ユーザーにとって迷惑で煩わしい出来事にすぎません。
必須の機能でない限り、もっと重要な部分に注力した方がよいかもしれません。


返信引用
薙
 薙
(@薙)
ゲスト
結合: 8年前
投稿: 6
Topic starter  

回答ありがとうございます。

サブクラス化はしているのですが、
どのような時にデフォルトボタンになるイベントが来ている
のかわかりません。

ボタンクリックイベント時に、強制的に
デフォルト無効としても駄目でした。


返信引用
AR2
 AR2
(@ar2)
Estimable Member
結合: 4年前
投稿: 110
 

仲澤@失業者さんの提案内容が難しければ、ビットマップボタンにしてボタンのイメージ
を自分で描くのも良いかもしれません。
ボタンの数が多い場合は、CBitmapButtonから派生して自前で描画することになります
が、結構サンプルも出回ってますし難易度は高くないと思います。

手頃な紹介サイトがあったので参考までにどうぞ。
http://www7b.biglobe.ne.jp/~makandat/VC/Group6/OwnerDraw.htm


返信引用
薙
 薙
(@薙)
ゲスト
結合: 8年前
投稿: 6
Topic starter  

オーナードローと言うことでしょうか?
オーナードローにすると、ビジュアルスタイルがクラシック
になってしまい、
今までと見た目が変わってしまうため避けたいです。
(オーナードローでWin7のようなビジュアルスタイル適用法
がわかりませんでした)

SetFocusイベントを受け取ったタイミングで
無理やりデフォルトボタンフラグを削除することである程度
の希望通りの動作は出来ましたが、
TABキーで移動してくると、やはり青枠が付いてしまいま
す。

Win7の標準ボタンの見た目のまま、青枠だけを表示しないよ
うにしたいのですが、
やはり難しいのでしょうか、


返信引用
みい
 みい
(@みい)
ゲスト
結合: 22年前
投稿: 65
 

フォーカス枠のことを言ってるんでしょうか。
でしたら…

http://www.ipentec.com/document/document.aspx?page=csharp-create-no-focused-butt
on


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 4年前
投稿: 828
 

まず、デフォルトボタンに設定されるときに通知は来ないと思います。

次にボタンのサブクラス化ができているならば、
デフォルト状態を解除するのは GetWindowLongPtr(GWL_STYLE);で、
取得したフラグ状態の BS_DEFPUSHBUTTON フラグを解除し、
SetWindowLongPtr()すればできるのですが、

多分WM_PAINT 時に常に設定しなおす必要があると予測できます。

キーボードフォーカスはWS_TABSTOPを外すだけではだめで、
マウスのボタンダウン、アップの時に誰かに逃がさなくてはなりません。
親がDLGであると、子のどれかにフォーカスを設定しにくるので、
難しい面があります。
親をDLGではなく、通常のウインドウにすれば、この辺りは逃れられます。

ただし、親をDLGでなくしても、

1.ボタン上でマウス左Down
2.そのままボタン外にドラッグアウト

等をすると、押下状態(表示色)が保持されてしまいます。
この解除方法は調べたことがありません。

名称は忘れましたが、ボタン名称の周りを囲む点線も表示されます。
残念ながら、この解除方法も調べたことがありません。

といった具合で、これらをすべてやるくらいなら、
作っちまった方が楽かもしれないというわけなのです(vv;)。

さて、ところで、どうしてこのようなことをやろうとしているのでしょうか。
そっちの方を説明すると、別の解決方法もあるかもしれません。
懸念しているのはマインスイーパー盤面にならんだボタンのような
動作をさせようとしているのであれば「あれはボタンではない」
ということをSpy++でご確認ください(笑)。


返信引用
薙
 薙
(@薙)
ゲスト
結合: 8年前
投稿: 6
Topic starter  

WM_PAINTイベント時にデフォルトボタンオフで出来ました。

自分でもWM_PAINTかな・・・と行きついたところでしたが、
ほんとにここで良いか不明でしたので、回答を得られて確証持てました。
ありがとうございます。

どうしてこんなことを・・・と言いますと
ダイアログのEnterキー操作を無効にしており、
デフォルトボタンの意味が全くありませんでした。
にも関わらず、青枠が表示されているのはおかしい、
ということで非表示にしたかったのです。

ちなみに、ご提示頂いた方法の

LONG_PTR lp = GetWindowLongPtr(this->m_hWnd, GWL_STYLE);
if ( lp & BS_DEFPUSHBUTTON ) {
SetButtonStyle(BS_PUSHBUTTON);
}

だとラジオボタンの場合におかしな事になってしまったので、

if ( GetButtonStyle() == BS_DEFPUSHBUTTON ) {
SetButtonStyle(BS_PUSHBUTTON);
}

と実装しました。

BS_DEFPUSHBUTTONってビット演算でIFできないんでしょうか?


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 4年前
投稿: 828
 

// BS_DEFPUSHBUTTONを「落とす」コードは
DWORD Flag = ( DWORD)::GetWindowLongPtr( hWndBtton, GWL_STYLE);
Flag &=( ~BS_DEFPUSHBUTTON); // ビット反転したものとのANDをとる
::SetWindowLongPtr( hWndBtton, GWL_STYLE, LONG( Flag));
ですね。ビット演算は慣れてないとわかりづらいですね。


返信引用
薙
 薙
(@薙)
ゲスト
結合: 8年前
投稿: 6
Topic starter  

WinUser.h を見ると、以下のように並んでるので
そのやり方ですと BS_AUTOCHECKBOX 等が入ってきた場合も
落ちてしまうんですよね・・・

#define BS_PUSHBUTTON 0x00000000L
#define BS_DEFPUSHBUTTON 0x00000001L
#define BS_CHECKBOX 0x00000002L
#define BS_AUTOCHECKBOX 0x00000003L
#define BS_RADIOBUTTON 0x00000004L
....

0,1,2,4,8...と並んでいるのならビット演算で落とせそうなのですが
この並びの場合、BS_DEFPUSHBUTTON だけ「落とす」方法がわかりませんでした。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 4年前
投稿: 828
 

なるほど、4bitが一括してフラグ化されてますね。失礼しました。

BS_TYPEMASKでマスクしてBS_DEFPUSHBUTTONならBS_PUSHBUTTON
に変更で良いのではないでしょうか。
DWORD BsStyle4bit = Flag & BS_TYPEMASK;
if( BsStyle4bit == BS_DEFPUSHBUTTON){
BsStyle4bit = BS_PUSHBUTTON;
}
Flag &=(~BS_TYPEMASK);// 4bit落とす
Flag |= BsStyle4bit;// まぁ0ですけどね


返信引用
薙
 薙
(@薙)
ゲスト
結合: 8年前
投稿: 6
Topic starter  

なるほど、BS_TYPEMASKはマスク用に用意されてるんですね。

やはり下位WORDを抜きだして見るしかないんですね・・・
なんでこんな並びのフラグにしたんだMicrosoft。

勉強になりました。
最後までご回答いただきありがとうございました!


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

本来の問題とは関係ありませんが…。

>なんでこんな並びのフラグにしたんだMicrosoft。

複数の状態が被ることがないから…かと。
自動チェックボックスで、プッシュボタン。というスタイルはないですし。
# PUSHBUTTONでDEFPUSHBUTTONは被るような気もしますが…そこんところはどうなんだろう??


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました