Форум: "Основная";
Текущий архив: 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.48 MB
Время: 0.038 c