Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Прилипание окоша к краям экрана


Автор: kjohn 28.8.2009, 19:07
Добрый день!

Нужно реализовать прилипания окна к краю экрана (например, пока только к правому), это с горем пополам получилось с помощью следующего кода со своим обработчиком WM_MOVING:

Код

//В классе формы
private:    // User declarations
        void __fastcall CatchDrag(TMessage &Msg);
        BEGIN_MESSAGE_MAP
                MESSAGE_HANDLER(WM_MOVING, TMessage, CatchDrag);
        END_MESSAGE_MAP(TForm)


Код

//Реализация
void __fastcall TCallForm::CatchDrag(TMessage &Msg)
  {
    TForm::Dispatch(&Msg);
    if(Msg.Msg == WM_MOVING)
      {
        PRECT pCurrentRec = PRECT(Msg.LParam);
        int LeftBeforeMove = pCurrentRec->left;       //Текущие координаты при перемещение верхнего левого окна формы
        int TopBeforeMove = pCurrentRec->top;
        if (LeftBeforeMove+CallForm->Width >= (Screen->DesktopWidth - 20) && LeftBeforeMove+CallForm->Width <= (Screen->DesktopWidth))
        {
                CallForm->Left = Screen->DesktopWidth - CallForm->Width + 3;
        }
      }
  }


CallForm - моя форма, прилипает она к краю при приближении к краю менее 20 пикселей.
Все работает, но коряво. Т.е. при приближение формы к краю она липнет, но тут же отлипает и возвращается на исходную позицию, где курсор... Либо если аккуратно не двигать курсором после прилипания - она прилипает, но при отпускание мыши - возвращается назад, т.е. то туда, то назад. Думал, может быть программно менять расположение курсора на экране, типа как он должен быть после прилипания на объекте (он получается смещен на 20 px), но потом посмотрел как реализовано в том же винампе и аналоге и понял, что это не выход, так как там курсор после прилипания к краю остается на своем прежнем месте. В чем загвоздка, подскажите как исправить!!!  smile 

Автор: 586 28.8.2009, 19:57
Код
class TForm1 : publiс TForm
{
__published:    // IDE-managed Components
private:    // User declarations
    void __fastcall wm_windowposchanging(TMessage &msg);
public:        // User declarations
    __fastcall TForm1(TComponent* Owner);
    BEGIN_MESSAGE_MAP
        MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, TMessage, wm_windowposchanging)
    END_MESSAGE_MAP(TForm)
};

Код
void __fastcall TForm1::wm_windowposchanging(TMessage &msg)
{
    const int sensitivity = 10;
    RECT rcWorkArea = {0};

    if(SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE))
    {
        WINDOWPOS *wp = (WINDOWPOS*)msg.LParam;
        if(abs(wp->x - rcWorkArea.left) <= sensitivity)
            wp->x = rcWorkArea.left;
        if(abs(wp->y - rcWorkArea.top) <= sensitivity)
            wp->y = rcWorkArea.top;
        if(abs(wp->cx + wp->x - rcWorkArea.right) <= sensitivity)
            wp->x = rcWorkArea.right - wp->cx;
        if(abs(wp->cy + wp->y - rcWorkArea.bottom) <= sensitivity)
            wp->y = rcWorkArea.bottom - wp->cy;
    }
    TForm::Dispatch(&msg);
}

Автор: kjohn 29.8.2009, 14:47
Спасибо, 586!

Липнет так, как нужно!  smile 

Автор: Rrader 30.8.2009, 06:13
У формы есть свойство ScreenSnap

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)