プッシュボタンを押してる間、処理をするロジックについて

[戻る]
竹の子ビッチ 2002/05/08(水) 14:32:42
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の中のブレークポイントの位置に入ってきません。
アドバイスお願いします。

ワルツ 2002/05/08(水) 15:21:36
サブクラス化するのがいいでしょう。
(SubclassDlgItem)

不良PG [E-Mail] 2002/05/08(水) 15:29:19
>デバッグでIDC_BUTTON1の上でマウスの左ボタンを押しても
>ButtonEx.cppの中のブレークポイントの位置に入ってきません。

ブレークポイントの位置がどこなのかは、判りませんが・・

同様の手順で行ったところ問題なくOnLButtonDownに入ってきますが・・

Bun 2002/05/08(水) 16:23:22
>サブクラス化するのがいいでしょう。
>(SubclassDlgItem)

しなくても、サブクラス化されているのでわ?

ゴミです。m(__)m

Bun 2002/05/08(水) 16:33:45
試してみたら一応、それらしく動きましたけど。

TIMER_5000MS はいくつですか?

みみみ 2002/05/08(水) 16:34:30
まず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する必要はないと
思われます。

竹の子ビッチ 2002/05/08(水) 16:39:47
[[解決]]
不良PGさん、Bunさん、ワルツさん
私が馬鹿でした。

CSampleDlgのcppにWM_LBUTTON_DOWNとWM_LBUTTON_UP
メッセージを残したままだったのが悪かったみたいです。
メッセージの衝突かな??
とにかく削ることで正常に処理が行なわれました。
サブクラス化とは、別のクラスから継承で作った
クラスのことですよね?

感謝致します。

不良PG [E-Mail] 2002/05/08(水) 17:47:26
>サブクラス化とは、別のクラスから継承で作った
>クラスのことですよね?
違います。

CWnd::SubclassDlgItem
CWnd::SubclassWindow
を見て下さい

手順の中の

>3.【クラスウイザード】→ 【メンバ変数】で、IDC_BUTTON1のメンバ変数を
> 追加しました。これを、m_buttonとしました。
> このとき、変数のタイプを2.で作成したクラスを選択

が、サブクラス化をしたことと同じことになります。
(実際は、フレームワークがCWnd::SubclassWindow[CWnd::SubclassDlgItem]と同様の操作
をしています)

不良PG [E-Mail] 2002/05/08(水) 19:51:01
ついでに・・、
通常は、問題ないと思いますが・・
厳密には、タイマー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);
}

竹の子ビッチ 2002/05/08(水) 20:33:24
>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
もないのに一体・・。

竹の子ビッチ 2002/05/08(水) 20:55:43
不良PGさん

要するに
ダイアログのパーツ(コントロール)
を他のクラスに対応付けることを
サブクラス化というのですね。
でmその対応付けたクラスをサブクラスであるのですね。

心より感謝致します。

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