win2000 vc++6.0 sp5 MFC使用
プッシュボタンを押し続けてる間、
処理をして、ボタンを離すと処理を辞める
ような事をしたいのですが、上手くいきません。
以下のような方法を使いました。
1.任意のダイアログボックス(CSampleDlgとします。)にIDC_BUTTON1
というボタンコントロールをおきます。
2.【クラスウイザード】→【クラスの追加】でCButtonの派生クラスを
作成しました。これをCButtonEx(ButtonEx.h ButtonEx.cpp)としました。
3.【クラスウイザード】→ 【メンバ変数】で、IDC_BUTTON1のメンバ変数を
追加しました。これを、m_buttonとしました。
このとき、変数のタイプを2.で作成したクラスを選択
4.クラスウイザードでCButtonExクラスにWM_LBUTTONDOWN,WM_LBUTTONUP
WM_TIMERのメッセージハンドラを作成しました。
5.ButtonEx.cppを以下のように編集しました。
/////////////////////////////////////////////////////////////////////////////
// CButtonEx メッセージ ハンドラ
void CButtonEx::OnTimer(UINT nIDEvent)
{
a++;
CButton::OnTimer(nIDEvent);
}
void CButtonEx::OnLButtonDown(UINT nFlags, CPoint point)
{
SetTimer(TIMER_ID, TIMER_5000MS, NULL);
CButton::OnLButtonDown(nFlags, point);
}
void CButtonEx::OnLButtonUp(UINT nFlags, CPoint point)
{
KillTimer(TIMER_ID);
CButton::OnLButtonUp(nFlags, point);
}
以上の方法で行なったのですが、
デバッグでIDC_BUTTON1の上でマウスの左ボタンを押しても
ButtonEx.cppの中のブレークポイントの位置に入ってきません。
アドバイスお願いします。
サブクラス化するのがいいでしょう。
(SubclassDlgItem)
>デバッグでIDC_BUTTON1の上でマウスの左ボタンを押しても
>ButtonEx.cppの中のブレークポイントの位置に入ってきません。
ブレークポイントの位置がどこなのかは、判りませんが・・
同様の手順で行ったところ問題なくOnLButtonDownに入ってきますが・・
>サブクラス化するのがいいでしょう。
>(SubclassDlgItem)
しなくても、サブクラス化されているのでわ?
ゴミです。m(__)m
試してみたら一応、それらしく動きましたけど。
TIMER_5000MS はいくつですか?
まずOnLButtonDown()が呼ばれてますね?
次に
>SetTimer(TIMER_ID, TIMER_5000MS, NULL);
インターバルが5000m秒だと5秒間帰ってきません。マウスクリックに反応させるならば、
せめて50m秒ぐらいにしないと。
もしくは、もしタイマーイベントの1回目を0m秒とするなら
OnLButtonDown()の中でで自分自身にタイマーメッセージをPostすればいいと思います。
this->PostMessage(WM_TIMER, TIMER_ID ); //this->は無くても可
蛇足ながらこのプログラムではマウスボタンがDOWN-UPの間にマウスのポイントが
ボタンを外れるとKillTimerできません。
CButtonの子クラスのハンドラを使用するならばSubclassWindowする必要はないと
思われます。
不良PGさん、Bunさん、ワルツさん
私が馬鹿でした。
CSampleDlgのcppにWM_LBUTTON_DOWNとWM_LBUTTON_UP
メッセージを残したままだったのが悪かったみたいです。
メッセージの衝突かな??
とにかく削ることで正常に処理が行なわれました。
サブクラス化とは、別のクラスから継承で作った
クラスのことですよね?
感謝致します。
>サブクラス化とは、別のクラスから継承で作った
>クラスのことですよね?
違います。
CWnd::SubclassDlgItem
CWnd::SubclassWindow
を見て下さい
手順の中の
>3.【クラスウイザード】→ 【メンバ変数】で、IDC_BUTTON1のメンバ変数を
> 追加しました。これを、m_buttonとしました。
> このとき、変数のタイプを2.で作成したクラスを選択
が、サブクラス化をしたことと同じことになります。
(実際は、フレームワークがCWnd::SubclassWindow[CWnd::SubclassDlgItem]と同様の操作
をしています)
ついでに・・、
通常は、問題ないと思いますが・・
厳密には、タイマーIDは、このように使いましょう
class CButtonEx : public CButton
{
UINT m_uTimerID;
}
void CButtonEx::OnTimer(UINT nIDEvent)
{
if( m_uTimerID == nIDEvent )
{
a++;
}
CButton::OnTimer(nIDEvent);
}
void CButtonEx::OnLButtonDown(UINT nFlags, CPoint point)
{
m_uTimerID = SetTimer(TIMER_ID, TIMER_5000MS, NULL);
CButton::OnLButtonDown(nFlags, point);
}
void CButtonEx::OnLButtonUp(UINT nFlags, CPoint point)
{
KillTimer(m_uTimerID);
CButton::OnLButtonUp(nFlags, point);
}
>SetTimer(TIMER_ID, TIMER_5000MS, NULL);
>インターバルが5000m秒だと5秒間帰ってきません。
>マウスクリックに反応させるならば、
>せめて50m秒ぐらいにしないと。
>もしくは、もしタイマーイベントの1回目を0m秒とするなら
>OnLButtonDown()の中でで自分自身にタイマーメッセージを
>Postすればいいと思います。
> this->PostMessage(WM_TIMER, TIMER_ID ); //this->は無くても可
有難うございます。秒数など
仕様がはっきりしたら
いろいろと試して行きたいと
思います。
>蛇足ながらこのプログラムではマウスボタンがDOWN-UPの間にマウスのポイントが
>ボタンを外れるとKillTimerできません。
試してみました。
ですが、DOWN-UPの間にボタンを外れるどころか
ダイアログを外れてもUPした時、
OnLButtonUp関数に飛びました。
??
必要だと思われる
SetCapture
ReleaseCapture
もないのに一体・・。
不良PGさん
要するに
ダイアログのパーツ(コントロール)
を他のクラスに対応付けることを
サブクラス化というのですね。
でmその対応付けたクラスをサブクラスであるのですね。
心より感謝致します。