マウスの動きにあわせてWindowが動くようにしたい – 固定ページ 2 – プログラミング – Home

マウスの動きにあわせてWindowが動...
 
通知
すべてクリア

[解決済] マウスの動きにあわせてWindowが動くようにしたい

固定ページ 2 / 4

MoriMori
 MoriMori
(@MoriMori)
ゲスト
結合: 22年前
投稿: 16
Topic starter  

>また、ビューなどがあるとその上にマウスカーソルがあってもメッセージは来なくて、ビュー
>が親にWM_MOUSEMOVEが来た事を知らせるようにしないとダメだったと思います。

ViewクラスにOnMouseMove()を追加すればいいのでしょうか?

親にWM_MOUSEMOVEが来た事を知らせるにはどうすればいいのでしょうか?


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

> また、ビューなどがあるとその上にマウスカーソルがあってもメッセージは来なくて、
> ビューが親に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);
}


返信引用
MoriMori
 MoriMori
(@MoriMori)
ゲスト
結合: 22年前
投稿: 16
Topic starter  

>というわけで、どのウィンドウがWM_MOUSEMOVEを受け取ってもいいように、OnMouseMoveを使
>う方法はやめて、PreTranslateMessageを追加して処理する方法をお勧めします。

PreTranslateMessage()はクラスウィザードで追加できるんですか?

OnMouseMove()の中での処理は以下のように、マウスが動いた時に呼ばれるだけでいいのでしょ
うか?
void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
{
CFrameWnd::OnMouseMove(nFlags, point);
}


返信引用
MoriMori
 MoriMori
(@MoriMori)
ゲスト
結合: 22年前
投稿: 16
Topic starter  

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);
}


返信引用
PAI
 PAI
(@PAI)
ゲスト
結合: 23年前
投稿: 359
 

ん?なにもPreTranslateMessage()使わんでも、
マウスキャプチャーして、WM_MOUSEMOVEで処理すればいいんとちゃう?


返信引用
MoriMori
 MoriMori
(@MoriMori)
ゲスト
結合: 22年前
投稿: 16
Topic starter  

>マウスキャプチャーして、WM_MOUSEMOVEで処理すればいいんとちゃう?

OnMouseMove()の中でSetCapture()を使えばいいってことですか?


返信引用
PAI
 PAI
(@PAI)
ゲスト
結合: 23年前
投稿: 359
 

Yes.

んで、クリックしたらReleaseCaptureして、
OnCaptureChangedで m_bMoving をリセットすればよろしいかと。


返信引用
たみあ
 たみあ
(@たみあ)
ゲスト
結合: 22年前
投稿: 57
 

>>マウスキャプチャーして、WM_MOUSEMOVEで処理すればいいんとちゃう?

>OnMouseMove()の中でSetCapture()を使えばいいってことですか?

そうするのなら、メニューの移動が選択されたとき、じゃないかな?


返信引用
MoriMori
 MoriMori
(@MoriMori)
ゲスト
結合: 22年前
投稿: 16
Topic starter  

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);
}


返信引用
PAI
 PAI
(@PAI)
ゲスト
結合: 23年前
投稿: 359
 

>>OnMouseMove()の中でSetCapture()を使えばいいってことですか?
>そうするのなら、メニューの移動が選択されたとき、じゃないかな?

あ、そうですね。早とちり、ごめんなさい。

>マウスの動きとWindowの動きが反対方向に動いてしまいます。
座標の足し算が逆なんでしょ。


返信引用
MoriMori
 MoriMori
(@MoriMori)
ゲスト
結合: 22年前
投稿: 16
Topic starter  

>座標の足し算が逆なんでしょ。
そうでした、逆にしたら直りました。

もう少しなんですが、マウスを動かすとマウスよりもWindowの移動幅が大きくなってしまいま
す。たぶんm_pointOldの値がメニューの移動を選択した時の値で、m_pointNewの値は
OnMouseMove()が呼ばれる度に変わってしまうからだと思うのですが、マウスとWindowが常に
同じ位置に移動するには、どうすればよいのでしょうか?


返信引用
たみあ
 たみあ
(@たみあ)
ゲスト
結合: 22年前
投稿: 57
 

どうすればよいと思いますか?

各値がどうなるか順を追って考えればわかると思うのですが。。。


返信引用
ひろぴー
 ひろぴー
(@ひろぴー)
ゲスト
結合: 22年前
投稿: 182
 

> ::GetCursorPos(&point);
> m_pointNew = point;
せっかくpointが取得できているのに
> void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
(2番目の引数です。念の為)
わざわざ取らなくてもいいような気が....。

SetCapture()した時点でのマウスの位置とウィンドウの位置の差分だけ記憶しておけばOKだ
と思いますが。


返信引用
たみあ
 たみあ
(@たみあ)
ゲスト
結合: 22年前
投稿: 57
 

>せっかくpointが取得できているのに
>わざわざ取らなくてもいいような気が....。

スクリーン座標じゃないと都合が悪いような。。。


返信引用
ひろぴー
 ひろぴー
(@ひろぴー)
ゲスト
結合: 22年前
投稿: 182
 

> スクリーン座標じゃないと都合が悪いような。。。
ClientToScreen()で変換してはどうでしょう?


返信引用
固定ページ 2 / 4

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました