いつもお世話になります。
ebimayoです
<<やろうとしている事>>
CBitmapButtonを派生させたクラス作成し、そのボタンにフォーカスがある状態で
Enterキー押下したときにボタンをクリックさせたのと同じ動きをさせたい。
<<実現のために試した方法と結果>>
CXXXXはCBitmapButtonを派生させたクラスです。
BOOL CXXXX::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_KEYDOWN &&
pMsg->wParam == VK_RETURN) {
SendMessage(BM_CLICK);
return TRUE;
}
return CBitmapButton::PreTranslateMessage(pMsg);
}
としたのですが、これだとクリックイベントは受け取ることが出来るのですが、
ボタンをマウスでクリックさせたときのような凹凸の描画が行われませんでした。
<<知りたいこと>>
あのボタンをマウスクリックしたときのような、一旦凹んでから浮かんでくる
一連の押されたよと分かる動きはどのようにしたら実現できるのでしょうか?
開発環境
Microsoft WindowsXP(SP2)
Microsoft Visual C++ 2005
ダイアログベースアプリケーション(MFC)
確認したいこと
1.押された状態のビットマップは用意してありますか?
2.用意してあるなら、それらをCBitmapButtonにちゃんと読み込ませてますか?
以下は私の想像にすぎません。
標準のメッセージバックスも凹にならずに即閉じちゃうね。
たぶん難しいよ。
WM_KEYDOWN-VK_RETURN発生
ボタンを凹にする(ボタンを再描画させる必要あるかな?)
少し待つ
ボタンを凸にする
BM_CLICKを発生させる
ということになるのかな?
少し待つってあたりが微妙に難しそうだ
あるいは
WM_KEYDOWN-VK_RETURN発生
ボタンを凹にする
WM_KEYUP-VK_RETURN発生
ボタンを凸にする
BM_CLICKを発生させる
WM_KEYUP-VK_RETURN発生しないまま他のアプリにフォーカスが移ってしまったら?
WM_KEYUP-VK_RETURN発生しないままマウスで別のボタンをクリックしたら?
ボタンを凹にするのは、CButton::SetStateだったきがする。
Spaceキーだと押したとき凹み、放したときイベントが発生しますね。
EnterをSpaceに置き換えてみては?
BOOL CXXXX::PreTranslateMessage(MSG* pMsg)
{
if (Enterキー) {
if (押した) {
SendMessage(Spaceキーを押したときのパラメータ);
} else {
SendMessage(Spaceキーを放したときのパラメータ);
}
return TRUE;
}
後略
ryoさん、超初心者さん、dairygoodsさん回答ありがとうございます
返事が遅くなって申し訳ありません。
ryoさんへ
> 確認したいこと
> 1.押された状態のビットマップは用意してありますか?
用意してあります。
> 2.用意してあるなら、それらをCBitmapButtonにちゃんと読み込ませてますか?
マウスでクリックしたときは凹凸表示できていますので
ちゃんと読み込めていると思います。
超初心者さんへ
メッセージバックスの意味が分かりませんでした。
ここで言う「ボタンを凹にする」とか「ボタンを凸にする」というのは
ボタンのフォーカスを持っている状態のBitmap画像を切り替えるという
ことでしょうか?
dairygoodsさんへ
これで上手くいきそうです。
前にSpaceキーへの置き換えは上手くいったのは試していたのですが、
テキストボックス(CEdit)にフォーカスがあるときスペースが入力されてしまい
この方法はダメだと思い込んでいましたが、
if( (CWnd::FromHandle(pMsg->hwnd))->IsKindOf( RUNTIME_CLASS(
CBitmapButton ) ) ){
これも使えばよかったんですね。すっかり忘れていました。
すいません間違えていました
if( (CWnd::FromHandle(pMsg->hwnd))->IsKindOf( RUNTIME_CLASS(
CBitmapButton ) ) ){
これはCBitmapButtonを派生させたクラスを使用している
クラスで判定しているときに使ってました。
実際の処理としては以下のようにすることでEnterキーの押下時に
マウスクリックと同じ動きを実現できるようになりました。
「pMsg->wParam == VK_RETURN」この状態のときにKEYDOWNとUP以外に
メッセージが来るか分からなかったので各if文にreturnを移動しました。
BOOL CXXXX::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->wParam == VK_RETURN) {
if(pMsg->message == WM_KEYDOWN){
SendMessage(WM_KEYDOWN,VK_SPACE,0);
return TRUE;
}else
if(pMsg->message == WM_KEYUP){
SendMessage(WM_KEYUP,VK_SPACE,0);
return TRUE;
}
}
return CBitmapButton::PreTranslateMessage(pMsg);
}
他にも教えていただいた「SendMessage(BM_SETSTATE,TRUE,0);」とかを
使った方法も以下のように試したのですが、Enterキーを押しっぱなしの状態で
キーボードの矢印キーなどで別のCBitmapButtonフォーカスを移動してEnterキーを
離すとなぜか最初にフォーカスを持っていたCBitmapButtonとフォーカス移動後の
CBitmapButtonの二つでクリックイベントが発生してしまったので、上記の
教えていただいたSpaceに置き換える方法を使うことにしました。
BOOL CXXXX::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->wParam == VK_RETURN) {
if(pMsg->message == WM_KEYDOWN){
SendMessage(BM_SETSTATE,TRUE,0);
return TRUE;
}else
if(pMsg->message == WM_KEYUP){
SendMessage(BM_CLICK);
return TRUE;
}
}
return CBitmapButton::PreTranslateMessage(pMsg);
}
解決できたのでチェックマークつけさせてもらいます。
私のやり方で間違っている箇所があったらご指摘ください。
ありがとうございました。