使用SwapMouseButton(TRUE);允许右键单击拖动窗口

时间:2011-10-07 10:49:30

标签: c++ windows c++builder-2007

我需要以某种方式允许使用右键单击拖动选项移动窗口。我通过一些我不太喜欢但却很有效的代码来做到这一点。

目前我正在捕获WM_NCRBUTTONDOWN消息并设置bool以表示我处于移动模式,在收到WM_NCRBUTTONUP时重置此变量。在移动模式下,我正在检查WMNCMouseMove并自行移动表单。由于跟上快速鼠标移动的速度很慢,我还设置了一个使用GetCursorPos来执行相同操作的计时器。

我最近发现了SwapMouseButton函数,这正是我想要的。但是有一个但是!我需要有条件地交换它,并且只有当用户右键单击窗口的CAPTION区域时才需要。

所以当我收到WM_NCRBUTTONDOWN并在WM_NCRBUTTONUP上重置时,我将鼠标按钮交换。但是,如果WM_NCRBUTTONUP从未重置它,这将适用于后续点击。我认为这是因为点击事件已经发生,所以交换时间较晚,这就是为什么它适用于后续的右键点击,而不是右键点击和拖动导致鼠标交换!

任何人都可以看到解决这个问题的方法。请记住,我需要左键单击功能,关闭,最小化,最大化按钮等。右键单击onyl移动!

请帮助!!!!!

谢谢, 乔

1 个答案:

答案 0 :(得分:0)

而不是手动跟踪鼠标或交换按钮,有一种更简单的方法 - 响应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右键单击(但是在左键单击子控件时效果很好)。我认为操作系统正在进行一些内部处理,这使得无法正常工作。因此,我采用拦截鼠标移动的方法手动移动窗口,使用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);
}

代码区分右键单击和右键单击操作。如果用户右键单击鼠标而不移动它,则允许默认弹出菜单正常显示。如果用户按住鼠标右键并移动窗口,则当用户释放右键时,不会显示默认弹出窗口。