Использование SwapMouseButton (TRUE);разрешить перетаскивание окна правой кнопкой мыши - PullRequest
1 голос
/ 07 октября 2011

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

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

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

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

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

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

Спасибо, Джо

1 Ответ

0 голосов
/ 07 октября 2011

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

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

...