Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];

Вниз

UI: Выделение с прокруткой.   Найти похожие ветки 

 
guav ©   (2006-10-15 17:51) [0]

В программе реализовано выделение прямоугольной области мышью при зажатии левой или правой кнопки (как в пеинте или в ListView). Рисуется оно на TPaintBox лежащем на TScrollBox. Есть требование сделать так чтобы при выводе мыши из области пеинтбокса скроллбокс прокручивался, чтобы можно было выделять большие области.
Как реализовать такую прокрутку ?


 
Eraser ©   (2006-10-15 18:08) [1]

> [0] guav ©   (15.10.06 17:51)

код из совершенно другой программы, но со сходной функциональностью.
if FConnection.AdvMouseScroll and (FConnection.RenderMode = 1) then
 begin
   if HorzScrollBar.IsScrollBarVisible then
   begin
     // Вычисляем 20% от ширины окна.
     a1 := ClientWidth div 5;
     // Проверяем правую границу окна.
     if (x > ClientWidth - a1) and (FLastX > ClientWidth - a1) then
     begin
       FLastX := ClientWidth - a1;
       nX := X - FLastX;
       //Caption := "Pos = " + IntToStr(HorzScrollBar.Position) +
       //  " Range = " + IntToStr(HorzScrollBar.Range) +
       //  " ClientWidth = " + IntToStr(ClientWidth) +
       //  " nX = " + IntToStr(nX);
       //Caption := "X = " + IntToStr(x) +
       //  "LastX = " + IntToStr(FLastX) +
       //  " nX = " + IntToStr(nX);
       if (nX > 0) and
       (HorzScrollBar.Position + 1 < HorzScrollBar.Range - ClientWidth) then
       begin
         HorzScrollBar.Position := HorzScrollBar.Position + nX;
         ptCursor := ClientToScreen(Point(FLastX, FLastY));
         SetCursorPos(ptCursor.X, ptCursor.Y);
       end;
     end;
     // Проверяем левую границу окна.
     if (x < a1) and (FLastX < a1) then
     begin
       FLastX := a1;
       nX := FLastX - X;
       if (nX > 0) and
       (HorzScrollBar.Position > 0) then
       begin
         HorzScrollBar.Position := HorzScrollBar.Position - nX;
         ptCursor := ClientToScreen(Point(FLastX, FLastY));
         SetCursorPos(ptCursor.X, ptCursor.Y);
       end;
     end;
   end;
   FLastX := x;
   if VertScrollBar.IsScrollBarVisible then
   begin
     // Вычисляем 20% от высоты окна.
     a1 := ClientHeight div 5;
     // Проверяем нижнюю окна.
     if (y > ClientHeight - a1) and (FLastY > ClientHeight - a1) then
     begin
       nY := Y - FLastY;
       if (nY > 0) and
       (VertScrollBar.Position < VertScrollBar.Range - ClientHeight) then
       begin
         //Caption := IntToStr(VertScrollBar.Position) + " X " +
         //  IntToStr(VertScrollBar.Range - ClientHeight);
         VertScrollBar.Position := VertScrollBar.Position + nY;
         ptCursor := ClientToScreen(Point(FLastX, FLastY));
         SetCursorPos(ptCursor.X, ptCursor.Y);
       end;
     end;
     // Проверяем верхнюю границу окна.
     if (y < a1) and (FLastY < a1) then
     begin
       nY := FLastY - Y;
       if (nY > 0) and
       (VertScrollBar.Position > 0) then
       begin
         VertScrollBar.Position := VertScrollBar.Position - nY;
         ptCursor := ClientToScreen(Point(FLastX, FLastY));
         SetCursorPos(ptCursor.X, ptCursor.Y);
       end;
     end;
   end;
   FLastY := y;
 end;


 
guav ©   (2006-10-15 18:18) [2]

> [1] Eraser ©   (15.10.06 18:08)

Спасибо.
Идея понятна. Никаких таймеров с автопрокруткой, вместо этого при попытке выйти из области прокрутка и SetCursorPos обратно в область. Реализация, конечно, проще в этом случае, но, думаю, пользователю будет удобнее "как в Listview"; вообще не стоит злоупотреблять функциями вроде SetCursorPos или ClipCursor.
Всё же хотелось бы узнать как сделать "как в Listview".


 
Eraser ©   (2006-10-15 18:21) [3]

> [2] guav ©   (15.10.06 18:18)

думаю примерно так же, только убрать SetCursorPos.

> вообще не стоит злоупотреблять функциями вроде SetCursorPos
> или ClipCursor.

согласен, черевато багами. но в моем случае сделал, чтобы выглядело как у конкурентов :)


 
Eraser ©   (2006-10-15 18:30) [4]

все таки для граф. редактора удобнее когда процесс полностью контролируешь, а автопрокрутка в ListView уж очень слабоуправляема.


 
guav ©   (2006-10-15 18:46) [5]

> [4] Eraser ©   (15.10.06 18:30)

Уговорил, сделаю так, не понравится пользователям - переделаю.


 
guav ©   (2006-10-16 00:30) [6]

Таки не понравился такой подход мне самому.
Будем делать как в ListView.
Нашел, что похожий скроллинг у грида.
В TCustomGrid.MouseDown : SetTimer(Handle, 1, 60, nil); - т.е. никакая специальная API функция для таких дел не используется, просто прокручивание по одной ячейке по таймеру. Мжет правда мне не подойти, т.к. у меня не ячейки а пиксели, они значительно меньше.
Ещё пример похожего скролинга - в редакторе или в IE при выделении текста, если завести курсор мыши выше или ниже окна с текстом.


 
AlexeyT ©   (2006-10-16 01:21) [7]

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


 
Eraser ©   (2006-10-16 01:22) [8]

> [6] guav ©   (16.10.06 00:30)


> Мжет правда мне не подойти, т.к. у меня не ячейки а пиксели,
> они значительно меньше.

ну можно скролировать не по 1 пикселю.

> Ещё пример похожего скролинга - в редакторе или в IE при
> выделении текста, если завести курсор мыши выше или ниже
> окна с текстом

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


 
guav ©   (2006-10-16 14:01) [9]

Меня настроаживает это:

> SetTimer(Handle, 1, 60, nil);
- есть подозрение, что такие малые задержки не выполняются точно, при этом, для попиксельной прокрутки и этой задержки было бы мало.


> [7] AlexeyT ©   (16.10.06 01:21)

Что за контрол ? Грид, эдит, или графическое поле ввода ? Какой


 
guav ©   (2006-10-16 14:03) [10]

> Какой

интервал таймера ?



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.046 c
6-1151942327
ART-of-FaNtAsY
2006-07-03 19:58
2006.11.26
Отправка и получение http запросов GET и POST


5-1143724023
AlexeyT
2006-03-30 17:07
2006.11.26
Ошибка при удалении ActiveX контрола


6-1147114742
Zhekacoder
2006-05-08 22:59
2006.11.26
передача файлов по сети


15-1162971575
SergP
2006-11-08 10:39
2006.11.26
Как распечатать документ .PDF?


2-1163002693
ApplyUpdates
2006-11-08 19:18
2006.11.26
Проблемы с ApplyUpdates





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский