1

我需要以某种方式允许使用右键单击拖动选项移动窗口。我通过一些我不太喜欢但它有效的狡猾代码完成了这项工作。

目前我正在捕获 WM_NCRBUTTONDOWN 消息并设置一个布尔值来表示我处于移动模式,并在收到 WM_NCRBUTTONUP 时重置此变量。在移动模式下,我正在检查 WMNCMouseMove 并自己移动表单。由于跟上快速鼠标移动的速度很慢,我还设置了一个计时器来使用 GetCursorPos 来做同样的事情。

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

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

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

请帮忙!!!!!

谢谢,乔

4

1 回答 1

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

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

于 2011-10-07T18:21:58.913 回答