Использование SwapMouseButton( TRUE); разрешить перетаскивание окна правой кнопкой мыши

Я должен как-то разрешить перемещение окна с помощью опции перетаскивания правой кнопкой мыши. Я сделал это с помощью какого-то хитрого кода, который мне не очень нравится, но он работает.

В настоящее время я перехватываю сообщение WM_NCRBUTTONDOWN и устанавливаю логическое значение, чтобы сказать, что я нахожусь в режиме перемещения, сбрасывая эту переменную при получении WM_NCRBUTTONUP. В режиме перемещения я проверяю WMNCMouseMove и самостоятельно перемещаю форму. Поскольку медленное движение мышью идет медленно, я также установил таймер, чтобы сделать то же самое с помощью GetCursorPos.

Недавно я обнаружил функцию SwapMouseButton, и она делает именно то, что я хочу. Однако есть, но! Мне нужно поменять его условно и только тогда, когда пользователь щелкнул правой кнопкой мыши область CAPTION окна.

Поэтому я меняю кнопки мыши круглыми, когда получаю WM_NCRBUTTONDOWN и сбрасываю на WM_NCRBUTTONUP. Однако это будет работать при последующих щелчках, если WM_NCRBUTTONUP никогда не сбрасывает его. Я думаю, это потому, что событие щелчка уже произошло, так что это слишком поздно, чтобы поменять местами, поэтому оно работает для последующих щелчков правой кнопкой мыши, но не для щелчка правой кнопкой мыши и перетаскивания, которое вызвало переключение мыши!

Кто-нибудь может найти способ обойти это. Имея в виду, что мне нужны функциональные возможности левого клика для закрытия, сворачивания, максимизации кнопок и т. Д. Щелкните правой кнопкой мыши для перемещения!

Пожалуйста помоги!!!!!

Спасибо джо

1 ответ

Решение

Вместо того, чтобы вручную отслеживать мышь или менять кнопки, есть более простой способ - в ответ на 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);
}

Код различает операции правой и правой кнопки мыши. Если пользователь щелкает правой кнопкой мыши, не перемещая ее, всплывающее меню по умолчанию может отображаться в обычном режиме. Если пользователь удерживает нажатой правую кнопку мыши и перемещает окно, всплывающее окно по умолчанию не отображается, когда пользователь отпускает правую кнопку.

Другие вопросы по тегам