>また、ビューなどがあるとその上にマウスカーソルがあってもメッセージは来なくて、ビュー
>が親にWM_MOUSEMOVEが来た事を知らせるようにしないとダメだったと思います。
ViewクラスにOnMouseMove()を追加すればいいのでしょうか?
親にWM_MOUSEMOVEが来た事を知らせるにはどうすればいいのでしょうか?
> また、ビューなどがあるとその上にマウスカーソルがあってもメッセージは来なくて、
> ビューが親にWM_MOUSEMOVEが来た事を知らせるようにしないとダメだったと思います。
クリックしてドラッグというパターンでないため、
何の上にカーソルがあるか分からないわけですね…。
さらに、ビューの上に何かあればそっちにWM_MOUSEMOVEが行ってしまいますね。
というわけで、どのウィンドウがWM_MOUSEMOVEを受け取ってもいいように、
OnMouseMoveを使う方法はやめて、
PreTranslateMessageを追加して処理する方法をお勧めします。
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_MOUSEMOVE && m_bMoving) {
// ここで動かす処理をする
return TRUE;
}
return CFrameWnd::PreTranslateMessage(pMsg);
}
>というわけで、どのウィンドウがWM_MOUSEMOVEを受け取ってもいいように、OnMouseMoveを使
>う方法はやめて、PreTranslateMessageを追加して処理する方法をお勧めします。
PreTranslateMessage()はクラスウィザードで追加できるんですか?
OnMouseMove()の中での処理は以下のように、マウスが動いた時に呼ばれるだけでいいのでしょ
うか?
void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
{
CFrameWnd::OnMouseMove(nFlags, point);
}
PreTranslateMessage()を追加したところWindowが一瞬表示されてすぐに消えてしまうように
なってしましました。
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_MOUSEMOVE && m_bMoving)
{
CPoint point;
::GetCursorPos(&point);
m_pointNew = point;
CRect rect;
GetWindowRect(&rect);
rect.left += (m_pointOld.x - m_pointNew.x);
rect.right += (m_pointOld.x - m_pointNew.x);
rect.top += (m_pointOld.y - m_pointNew.y);
rect.bottom += (m_pointOld.y - m_pointNew.y);
SetWindowPos(&wndTopMost, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
SWP_SHOWWINDOW);
return TRUE;
}
return CFrameWnd::PreTranslateMessage(pMsg);
}
ん?なにもPreTranslateMessage()使わんでも、
マウスキャプチャーして、WM_MOUSEMOVEで処理すればいいんとちゃう?
>マウスキャプチャーして、WM_MOUSEMOVEで処理すればいいんとちゃう?
OnMouseMove()の中でSetCapture()を使えばいいってことですか?
Yes.
んで、クリックしたらReleaseCaptureして、
OnCaptureChangedで m_bMoving をリセットすればよろしいかと。
>>マウスキャプチャーして、WM_MOUSEMOVEで処理すればいいんとちゃう?
>OnMouseMove()の中でSetCapture()を使えばいいってことですか?
そうするのなら、メニューの移動が選択されたとき、じゃないかな?
SetCapture()をOnMove()内で使ったら、Windowは何とか動くようにはなりました。
ただ、マウスの動きとWindowの動きが反対方向に動いてしまいます。
何がいけないのでしょうか?
以下はソースコードです。
void CMainFrame::OnMove()
{
m_bMoving = TRUE;
CPoint point;
::GetCursorPos(&point);
m_pointOld = point;
SetCapture();
}
void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
{
if(m_bMoving == TRUE)
{
CPoint point;
::GetCursorPos(&point);
m_pointNew = point;
CRect rect;
GetWindowRect(&rect);
rect.left += (m_pointOld.x - m_pointNew.x);
rect.right += (m_pointOld.x - m_pointNew.x);
rect.top += (m_pointOld.y - m_pointNew.y);
rect.bottom += (m_pointOld.y - m_pointNew.y);
SetWindowPos(&wndTopMost, rect.left, rect.top,rect.right - rect.left,
rect.bottom - rect.top,SWP_SHOWWINDOW);
}
CFrameWnd::OnMouseMove(nFlags, point);
}
void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point)
{
ReleaseCapture();
m_bMoving = FALSE;
CFrameWnd::OnLButtonDown(nFlags, point);
}
>>OnMouseMove()の中でSetCapture()を使えばいいってことですか?
>そうするのなら、メニューの移動が選択されたとき、じゃないかな?
あ、そうですね。早とちり、ごめんなさい。
>マウスの動きとWindowの動きが反対方向に動いてしまいます。
座標の足し算が逆なんでしょ。
>座標の足し算が逆なんでしょ。
そうでした、逆にしたら直りました。
もう少しなんですが、マウスを動かすとマウスよりもWindowの移動幅が大きくなってしまいま
す。たぶんm_pointOldの値がメニューの移動を選択した時の値で、m_pointNewの値は
OnMouseMove()が呼ばれる度に変わってしまうからだと思うのですが、マウスとWindowが常に
同じ位置に移動するには、どうすればよいのでしょうか?
どうすればよいと思いますか?
各値がどうなるか順を追って考えればわかると思うのですが。。。
> ::GetCursorPos(&point);
> m_pointNew = point;
せっかくpointが取得できているのに
> void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
(2番目の引数です。念の為)
わざわざ取らなくてもいいような気が....。
SetCapture()した時点でのマウスの位置とウィンドウの位置の差分だけ記憶しておけばOKだ
と思いますが。
>せっかくpointが取得できているのに
>わざわざ取らなくてもいいような気が....。
スクリーン座標じゃないと都合が悪いような。。。
> スクリーン座標じゃないと都合が悪いような。。。
ClientToScreen()で変換してはどうでしょう?