マウスを手動で追跡したりボタンを交換したりする代わりに、より簡単な方法があります。それに応じてWM_NCRBUTTONDOWN
、特別なメッセージを送信してウィンドウをネイティブに移動モードにするとWM_SYSCOMMAND
、ドラッグのすべてのハードワークが処理されます。例えば:
const WPARAM MOUSE_MOVE = SC_MOVE + 2;
case WM_NCRBUTTONDOWN:
{
POINT pt;
GetCursorPos(&pt);
SendMessage(Handle, WM_NCRBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
SendMessage(Handle, WM_SYSCOMMAND, MOUSE_MOVE, MAKELPARAM(pt.x, pt.y));
break;
}
詳細については、 Q114593を参照してください。
更新:WM_SYSCOMMAND
右クリックで作業することができませんでした(ただし、子コントロールを左クリックするとうまく機能します)。OSは内部処理を行っているため、正しく動作できなくなっていると思います。そこで、マウスの動きをインターセプトしてウィンドウを手動で移動し、SetCapture()
代わりに次を使用して、タイマーを使用せずに高速のマウスの動きで正しく動作するようにしました。
bool RightButton_CanMove = false;
bool RightButton_WindowMoved = false;
POINTS LastPoint;
void __fastcall TForm1::WndProc(TMessage &Message)
{
switch( Message.Msg )
{
case WM_NCRBUTTONDOWN:
LastPoint = MAKEPOINTS(Message.LParam);
RightButton_CanMove = true;
RightButton_WindowMoved = false;
SetCapture(Handle);
Message.Result = 0;
return;
case WM_MOUSEMOVE:
if( (Message.WParam & MK_RBUTTON) && (RightButton_CanMove) )
{
POINT CurPoint;
GetCursorPos(&CurPoint);
SetWindowPos(Handle, NULL, Left + (CurPoint.x - LastPoint.x), Top + (CurPoint.y - LastPoint.y), 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
LastPoint.x = CurPoint.x;
LastPoint.y = CurPoint.y;
RightButton_WindowMoved = true;
}
break;
case WM_RBUTTONUP:
if( RightButton_CanMove )
{
RightButton_CanMove = false;
ReleaseCapture();
if( RightButton_WindowMoved )
{
RightButton_WindowMoved = false;
Message.Result = 0;
return;
}
}
break;
}
TForm::WndProc(Message);
}
このコードは、右クリック操作と右移動操作を区別しています。ユーザーがマウスを動かさずに右クリックすると、デフォルトのポップアップメニューが通常どおり表示されます。ユーザーがマウスの右ボタンを押したままウィンドウを移動した場合、ユーザーが右ボタンを離したときにデフォルトのポップアップは表示されません。