Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Скроллинг мышью


Автор: Array 2.8.2004, 20:46
Приветствую всех на форуме.
Необходимо сделать приложение в котором будет реализован скроллинг мышью.
Подробнее вопрос в следующем:
В ScrollBox помещен компонент Image, который содержит изображение
Bitmap. Размер картинки большой, т.е. в окно ScrollBox она не влазит
(Image.AutoSize:=true). Естественно, автоматически появляются линейки скроллинга,но они не удобны в этом приложении, поэтому необходим скроллинг мышью, то есть при нажатии левой кнопки мыши над изображением оно должно перетягиваться.
Насколько я понимаю, требуется написать обработчик события
<On Mouse Down>. Но я в Delphi пока новичок и пока не могу разоб-раться, что в нем надо задавать. Может быть Мастера Delphi помогут?


С уважением

Автор: Chyslyvchyk 2.8.2004, 22:59
dontgetit.gif
Что-то я не совсем понимаю... Нужно, чтобы работал скроллинг мышью? Дык он и так работает в ScrollBox.....

Автор: Illusion Dolphin 2.8.2004, 23:08
Chyslyvchyk: человек не совсем правильно выразился... ему нужен что-то вроде drag-and-drop 8). Т.е. нажимаешь мышку - появилась на курсоре "рука", ты тягаешь в стороны мышу, и вместе с ней перетаскиваешь изображение (т.к. оно в экран не влазит). Как сделать - пока не могу думать (это обработка onMouseDown+OnMouseMove+OnMouseUp+пара переменных-триггеров), т.к. ужасно хочу спать, а ещё на работу завтра...

Автор: Burich-Caeser 3.8.2004, 01:28
Создашь глобальную булеву переменную click.
В обработчике нажатия( не по всей форме, а только по имэйджу) присваиваешь ей истину + записываешь куда-нить текущие координаты.
в обработчике отпуска click := False;
В OnMove проверяешь, click на равенство false если так, нифика не делаешь, иначе смотришь, как изменились координаты и прокручиваешь картинку в ту сторону.

Надеюсь помог.
Если что, потом могу написать исходник. thumbs-up.gif
Удачи.

З.Ы. Ты тоже недавно на форуме?
Классное место, я больше нигде и не бываю... И тебе советую остаться=))

Автор: Array 3.8.2004, 23:17
Illusion Dolphin


Да, все правильно. Именно это и требуется.



Burich-Caeser


Цитата
иначе смотришь, как изменились координаты и прокручиваешь картинку в ту сторону.


А как сделать покрутку? Все остальное понятно.


З.Ы. Я просматриваю форум несколько месяцев. Думаю, это лучший
форум по программированию

Автор: Alkash 4.8.2004, 01:18
То бишь смещаешь координаты просмотра относительно картинки.

Автор: Burich-Caeser 4.8.2004, 02:08
if I=0 then
FON.Picture.Bitmap.Canvas.CopyRect(Rect(0,0,W,H),
FON.Picture.Bitmap.Canvas,Rect(0,0,W,H));
I:=I+1;
FON.Picture.Bitmap.Canvas.CopyMode:=cmSrcCopy;
FON.Picture.Bitmap.Canvas.CopyRect(Rect(0,0,A-I,B),
FON.Picture.Bitmap.Canvas,Rect(I,0,A,B));
FON.Picture.Bitmap.Canvas.CopyRect(Rect(A-I,0,A,B),
FON.Picture.Bitmap.Canvas,Rect(0,0,I,B));
if I=A then I:=0;
end;

Что-то в этом роде... Если, не прокатит, скажешь, я постараюсь кинуть нормальный пример на мыло... Извиняй, сейчас голова туго варит, психую из-за приема на работу.... Хочу работать программером=) Написал пробную прогу для них, жду решения... Фу, выговорился hehe.gif
Простите за оффтоп sad.gif

Чуть не забыл:
W - width твоего имэйджа, то-есть не всей картинки, а рисуемого участка;
H - height...;
A - ширина всей картинки;
B - высота всей картинки;
rolleyes.gif Удачи rolleyes.gif

Автор: Dynamic 4.8.2004, 09:20
Код
type
 TForm1 = class(TForm)
   ScrollBox1: TScrollBox;
   Image1: TImage;
   procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
   procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
   procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
     Y: Integer);
 private
   IsMoving: boolean;
   StartPt: TPoint;
 end;
........
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
    StartPt := Point(X, Y);
    IsMoving := true;
    Screen.Cursor := crHandPoint;
end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
    IsMoving := false;
    Screen.Cursor := crDefault;
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
 Y: Integer);
var dx, dy: integer;
begin
    if not IsMoving then Exit;
    if (StartPt.X <> X) or (StartPt.Y <> Y) then
    begin
      dx := X - StartPt.X;
      dy := Y - StartPt.Y;
      if ((dx > 0) and (Image1.Left = 0)) or
         ((dx < 0) and (Image1.Left = ScrollBox1.ClientWidth-Image1.Width)) then dx := 0;
      if ((dy > 0) and (Image1.Top = 0)) or
         ((dy < 0) and (Image1.Top = ScrollBox1.ClientHeight-Image1.Height)) then dy := 0;
      ScrollBox1.HorzScrollBar.Position := ScrollBox1.HorzScrollBar.Position - dx;
      ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position - dy;
    end;
end;

Автор: Array 4.8.2004, 22:54
Dynamic

ОГРОМНОЕ СПАСИБО!!! То, что надо. Все работает прекрасно.


Очень выручил. Жму руку!




Burich-Caeser

Покрутка через <canvas> выглядит немного странно. Я такое довести до рабочего состояния не смог. По моему, способ Dynemic' а намного
"естественней". Главное --- работает.
НО все равно СПАСИБО!




Автор: Burich-Caeser 5.8.2004, 01:07
=)) Пожалуйста... Вообщето мой код просто копирует из картинки то, что должно быть видно в этот момент.

Автор: Burich-Caeser 6.8.2004, 01:32
Если еще надо и хочется потелепаться, то пример через WinApi:

HDC hdc;
PAINTSTRUCT ps;
SCROLLINFO si;

/* Переменные для BitBlt. */

static HDC hdcWin; /* DC окна */
static HDC hdcScreen;
static HDC hdcScreenCompat;
static HBITMAP hbmpCompat; /* handle на bitmap для старого DC */
static BITMAP bmp; /* bitmap data structure */
static BOOL fBlt; /* TRUE если BitBlt используется */

static BOOL fScroll; /* TRUE если scrolling используется */
static BOOL fSize; /* TRUE если fBlt & WM_SIZE =)логическая оп. */

/* Для горизонтального scrolling. */

static int xMinScroll; /* минимальная величина горизонтальной прокрутки */
static int xCurrentScroll; /* текущая... */
static int xMaxScroll; /* максимальная... */

/* Для вертикального scrolling. */


static int yMinScroll; /* ... вертикальной... */
static int yCurrentScroll; /* ... */
static int yMaxScroll; /* ... */

switch (uMsg) {
case WM_CREATE:

hdcScreen = CreateDC("DISPLAY", (LPCSTR) NULL,
(LPCSTR) NULL, (CONST DEVMODE *) NULL);
hdcScreenCompat = CreateCompatibleDC(hdcScreen);

bmp.bmBitsPixel =
(BYTE) GetDeviceCaps(hdcScreen, BITSPIXEL);
bmp.bmPlanes = (BYTE) GetDeviceCaps(hdcScreen, PLANES);

bmp.bmWidth = GetDeviceCaps(hdcScreen, HORZRES);
bmp.bmHeight = GetDeviceCaps(hdcScreen, VERTRES);

bmp.bmWidthBytes = ((bmp.bmWidth + 15) &~15)/8;

hbmpCompat = CreateBitmap(bmp.bmWidth, bmp.bmHeight,
bmp.bmPlanes, bmp.bmBitsPixel, (CONST VOID *) NULL);

SelectObject(hdcScreenCompat, hbmpCompat);

fBlt = FALSE;
fScroll = FALSE;
fSize = FALSE;

xMinScroll = 0;
xCurrentScroll = 0;
xMaxScroll = 0;

yMinScroll = 0;
yCurrentScroll = 0;
yMaxScroll = 0;


break;

case WM_SIZE: {

int xNewSize;
int yNewSize;

xNewSize = LOWORD(lParam);
yNewSize = HIWORD(lParam);

if (fBlt)
fSize = TRUE;

xMaxScroll = max(bmp.bmWidth-xNewSize, 0);

xCurrentScroll = min(xCurrentScroll, xMaxScroll);
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = xMinScroll;
si.nMax = xMaxScroll;
si.nPage = xNewSize;
si.nPos = xCurrentScroll;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);

yMaxScroll = max(bmp.bmHeight - yNewSize, 0);
yCurrentScroll = min(yCurrentScroll, yMaxScroll);
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = yMinScroll;
si.nMax = yMaxScroll;
si.nPage = yNewSize;
si.nPos = yCurrentScroll;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);


}
break;

case WM_PAINT: {

PRECT prect;

hdc = BeginPaint(hwnd, &ps);

if (fSize) {
BitBlt(ps.hdc,
0, 0,
bmp.bmWidth, bmp.bmHeight,
hdcScreenCompat,

xCurrentScroll, yCurrentScroll,
SRCCOPY);

fSize = FALSE;
}

if (fScroll) {
prect = &ps.rcPaint;

BitBlt(ps.hdc,
prect->left, prect->top,
(prect->right - prect->left),
(prect->bottom - prect->top),
hdcScreenCompat,
prect->left + xCurrentScroll,
prect->top + yCurrentScroll,

SRCCOPY);

fScroll = FALSE;
}

EndPaint(hwnd, &ps);
}
break;

case WM_HSCROLL: {

int xDelta;
int xNewPos;
int yDelta = 0;

switch (LOWORD(wParam)) {

case SB_PAGEUP:
xNewPos = xCurrentScroll - 50;

break;

case SB_PAGEDOWN:
xNewPos = xCurrentScroll + 50;
break;

case SB_LINEUP:
xNewPos = xCurrentScroll - 5;
break;

case SB_LINEDOWN:
xNewPos = xCurrentScroll + 5;

break;

case SB_THUMBPOSITION:
xNewPos = HIWORD(wParam);
break;

default:
xNewPos = xCurrentScroll;
}

xNewPos = max(0, xNewPos);
xNewPos = min(xMaxScroll, xNewPos);


if (xNewPos == xCurrentScroll)
break;

fScroll = TRUE;

xDelta = xNewPos - xCurrentScroll;

xCurrentScroll = xNewPos;

ScrollWindowEx(hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
(CONST RECT *) NULL, (HRGN) NULL, (LPRECT) NULL,
SW_INVALIDATE);
UpdateWindow(hwnd);

si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = xCurrentScroll;

SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);

}
break;

case WM_VSCROLL: {

int xDelta = 0;
int yDelta;
int yNewPos;

switch (LOWORD(wParam)) {

case SB_PAGEUP:
yNewPos = yCurrentScroll - 50;
break;


case SB_PAGEDOWN:
yNewPos = yCurrentScroll + 50;
break;

case SB_LINEUP:
yNewPos = yCurrentScroll - 5;
break;

case SB_LINEDOWN:
yNewPos = yCurrentScroll + 5;
break;


case SB_THUMBPOSITION:
yNewPos = HIWORD(wParam);
break;

default:
yNewPos = yCurrentScroll;
}

yNewPos = max(0, yNewPos);
yNewPos = min(yMaxScroll, yNewPos);

if (yNewPos == yCurrentScroll)
break;


fScroll = TRUE;

yDelta = yNewPos - yCurrentScroll;

yCurrentScroll = yNewPos;

ScrollWindowEx(hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
(CONST RECT *) NULL, (HRGN) NULL, (LPRECT) NULL,
SW_INVALIDATE);
UpdateWindow(hwnd);

si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = yCurrentScroll;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);

}
break;


case WM_COMMAND:
switch(wParam) {
case IDM_STC:

BitBlt(hdcScreenCompat, 0, 0, bmp.bmWidth,
bmp.bmHeight, hdcScreen, 0, 0, SRCCOPY);

hdcWin = GetDC(hwnd);

BitBlt(hdcWin, 0, 0, bmp.bmWidth, bmp.bmHeight,
hdcScreenCompat, 0, 0, SRCCOPY);

ReleaseDC(hwnd, hdcWin);

fBlt = TRUE;
break;

default:
return (DefWindowProc(hwnd, uMsg,
wParam, lParam));
}
break;

Если вопрос исчерпан, закрой, пожалуйста тему...

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