VC++.net 2002 MFC でプログラミングしています
ボタンを押しながらマウスを動作させた時のマウスの位置の取得はどうすればよいので
しょうか?(ボタンはできればツールバー上のボタン)あるボタンを左クリックしなが
ら、マウスを上に動かすと、その動きに合わせて例えば数値が増加する。みたいなのを
考えています。VBではbottum click とmouse moveでできましたが、VC++ではボタンを押
している間(クリック中)はOnMouseMoveが働いていないようです。 GetCursorPosとタ
イマーの組み合わせしかないのでしょうか?
長文すいません。
ボタンをサブクラス化して、
(OnLButtonDownで押していますよフラグを立てて)
OnMouseMoveから親ウィンドウにメッセージを投げるとか。
> (OnLButtonDownで押していますよフラグを立てて)
これいらないかも。ボタンの上のMouseMoveイベントは必要ないのであれば、
こんな感じでしょうかね。
// ボタンをサブクラス化して、親のコントロールメンバ変数として持たせる
void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
{
CRect rct;
this->GetClientRect(&rct);
// ボタン上の座標でない場合
if (!rct.PtInRect(point))
{
CWnd* pWnd = this->GetParentOwner();
if (pWnd)
{
// 親座標に変換
this->MapWindowPoints(pWnd, &point, 1);
// 親にOnMouseMoveイベントを通知
pWnd->SendMessage(WM_MOUSEMOVE, nFlags,
MAKELPARAM(point.x, point.y));
}
}
CButton::OnMouseMove(nFlags, point);
}
よく考えたらダメかも。
上のコードだとボタンを押していれば、ボタン以外の位置であれば
どこにあっても親にWM_MOUSEMOVEを投げちゃいますね。
つまり、親ウィンドウの外でも、別のコントロール上にマウスカーソルがあっても
WM_MOUSEMOVEイベントが発生してしまいます。
前者は親ウィンドウの領域をとってPtInRectで判定すれば出来そうですが、
後者はほかのコントロールの上にあるって事までは(ボタン側では)判定できませんね。
(親側から判定するしかないかな。)
お返事ありがとうございます。
初心者なのでなかなか理解できないのですが、親にOnMouseMoveイベントを通知とありま
すがこれをどのように親側で受け取ればよいのでしょうか?
変な質問していたら申し訳ありません。
どこまでできていますか?
CButtonを継承したクラスをダイアログ(だと思う)のメンバ変数にしてWM_MOUSEMOVEをハ
ンドルして、17:19:15のコードを貼り付け、
そのクラスをコントロールメンバ変数としてダイアログのメンバに追加までできていま
すか?
そしたらダイアログクラスのWM_MOUSEMOVEをハンドルしたOnMouseMoveを追加すれば
勝手にそこに送られてくるはずです。
確認用
void CXXXXDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出し
ます。
TRACE2(%d,%d\n, point.x, point.y);
CDialog::OnMouseMove(nFlags, point);
}
これで、デバッグ実行すると「出力」ウィンドウに座標が出力されます。
返信ありがとうございます。
①Buttonをダイアログに1つつくる。(te2Dlg.cpp)
②クラスの追加ー>MSCクラスで
基本クラスCBottun, クラス名subclassとする
③subclassで
void subslass::OnMouseMove(UINT nFlags, CPoint point)
{
....略17:19:15のコード
CButton::OnMouseMove(nFlags, point);
}
④ダイアログでButtonを選択して変数の追加
変数の種類CButton 名前m_btn1
⑤確認用に
void Cte2Dlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出し
ます。
CString str;
str.Format(%d, point.y);
m_edit1.SetWindowText(str);
CDialog::OnMouseMove(nFlags, point);
}
で表示。(edicontrol上に表示しています)
で結果は通常のCte2Dlg::OnMouseMoveとまったく同じです。
なんか抜けてますよね?
>変数の種類CButton 名前m_btn1
が間違っているようです。
変数の追加のダイアログではおそらくCButtonしか選べないですが
ここをサブクラス化したクラスにしないとだめです。
まぁやり直すのは面倒ですので、
ダイアログのヘッダファイルに
・#include subclass.h を追加
・CButton m_btn1; を subclass m_btn1; に変更
としてみてください。
ご指摘のようにしてみましたが、通常のCte2Dlg::OnMouseMoveとまったく同じでした。
はじめから作り直してもみたのですが。。。
ボタンを押さなくてもカーソル位置が帰ってきます。
ほかに何かすべきことがあるのでしょうか?
>④ダイアログでButtonを選択して変数の追加
が根本的に間違っているのかな?
「コントロール変数」ってのにチェックを入れて
該当のボタンのコントロールと結びついていないと意味ないです。
ソースコード中に
DDX_Control(pDX, IDC_BUTTON1, m_btn1);
のような記述があるか確認してください。
ないのであれば手動で
CDialog::DoDataExchange(pDX);
のしたに入れてください。
で確認時ですが、
>void subslass::OnMouseMove(UINT nFlags, CPoint point)
の関数内の記述のどこかにブレイクポイント(F9)でもおいて
デバッグ実行してちゃんととまるかやってみてください。
てーかさ、キャプチャすればいいだけじゃないの?
キャプチャ設定したウィンドウ上にカーソルが無くてもMOVEメッセージがカーソルに
飛んで来るんだし、要するにドラッグ処理なわけだから。
うまくいきました。ありがとうございます。
最後のところはそのように以前もしていたのですが、とにかくできました。
これを元にいろいろ先の処理を考えたいと思います。一歩前進しました。
また、お尋ねすることがあると思いますがよろしくお願いします。
迅速なお返事大変感謝しております。