Страница 1 из 2
Позиционирование на колонке листбокса
Добавлено: 23 Апрель 2011, 15:04
Jornada
Добрый день!
Вопрос следующий: Есть листбокс, первая колонка фиксирована, остальные скроллируются по горизонтали. Колонок достаточно много, поэтому есть необходимость позиционирования на определенной.
Под позиционированием понимается, что при открытии формы колонки как бы уже проскроллированы до нужной.
Какие есть мысли по этому поводу?
Re: Позиционирование на колонке листбокса
Добавлено: 23 Апрель 2011, 16:09
Admin
Jornada писал(а):Добрый день!
Вопрос следующий: Есть листбокс, первая колонка фиксирована, остальные скроллируются по горизонтали. Колонок достаточно много, поэтому есть необходимость позиционирования на определенной.
Под позиционированием понимается, что при открытии формы колонки как бы уже проскроллированы до нужной.
Какие есть мысли по этому поводу?
Только в сторону
PROP:HScrollPos EQUATE(7CBBH) ! integer: Horizontal scroll position
отображается колонка или скрыта за краем листа,... такого пропа не помню.
Re: Позиционирование на колонке листбокса
Добавлено: 23 Апрель 2011, 16:59
Jornada
Спасибо)
Re: Позиционирование на колонке листбокса
Добавлено: 23 Апрель 2011, 17:10
Jornada
Еще вопрос. Как отловить событие перемещения горизонтального бегунка? EVENT:ScrollDrag срабатывает только для вертикального
Re: Позиционирование на колонке листбокса
Добавлено: 24 Апрель 2011, 1:48
Admin
Только сабкласить листбокс и пробовать ловить события от горизонтального скрола.
Re: Позиционирование на колонке листбокса
Добавлено: 24 Апрель 2011, 12:50
Jornada
А примера нигде не завалялось?
Re: Позиционирование на колонке листбокса
Добавлено: 24 Апрель 2011, 14:54
Дед Пахом
Посмотрите пример из Help > PROP:WndProc для начала.
Re: Позиционирование на колонке листбокса
Добавлено: 25 Апрель 2011, 9:19
Admin
Admin писал(а):Только сабкласить листбокс и пробовать ловить события от горизонтального скрола.
Кстати я тут подумал. Может не мучиться и сделать таймер и на нем проверять?
Re: Позиционирование на колонке листбокса
Добавлено: 25 Апрель 2011, 19:26
Jornada
пока что свой скролл нарисовал, используя PROP:HScrollPos.
Re: Позиционирование на колонке листбокса
Добавлено: 27 Апрель 2011, 3:04
Jornada
Поторопился я. Не получается горизонтальный скролл.. Попробовал пример из Help'a, по совету Деда Пахома, порылся в скудных обрывках информации по сабклассам.. Ну месседж получить могу, когда бегунок горизонтальный перемещаю.. а вот повлиять на его местоположение.. GetScrollPos ничего не возвращает, SetScrollPos не устанавливает. Может кто поделится рабочим примером?
Re: Позиционирование на колонке листбокса
Добавлено: 27 Апрель 2011, 5:15
Admin
Jornada писал(а): Может кто поделится рабочим примером?
Можно на Windows API довольно таки легко сделать свой скроллбар.
Только как он будет с листом работать х.з.
Пример за давностью потерялся.
Re: Позиционирование на колонке листбокса
Добавлено: 27 Апрель 2011, 9:57
Дед Пахом
Jornada писал(а):Поторопился я. Не получается горизонтальный скролл.. Попробовал пример из Help'a, по совету Деда Пахома, порылся в скудных обрывках информации по сабклассам.. Ну месседж получить могу, когда бегунок горизонтальный перемещаю.. а вот повлиять на его местоположение.. GetScrollPos ничего не возвращает, SetScrollPos не устанавливает. Может кто поделится рабочим примером?
Похоже, сабклассить надо не листбокс, а его скроллбар. Его хэндл легко найти: HScrollHwnd = FindWindowEx(?List{PROP:Handle}, 0). Правда, я в Spy никак не могу отловить события горизонтального скроллинга, что-то неправильно делаю, наверно.
Re: Позиционирование на колонке листбокса
Добавлено: 27 Апрель 2011, 10:19
agat
Попробовал вот так:
?List1{Prop:selected} = 1
?List1{Prop:column} = 25
POST(EVENT:NewSelection, ?List1)
Встало на первую строчку, 25 колонку и список прокрутился до нужного места.
Re: Позиционирование на колонке листбокса
Добавлено: 27 Апрель 2011, 12:41
Jornada
Уважаемые Гуру, большая к Вам просьба.. не могли бы вы отвечать более развернуто, а то после ответов "это легко" возникает вопросов больше, чем было до этого)
В частности, я не нашел описания прототипа FindWindowEx для клары, там только FindWindow. Кроме того у FindWindowEx - 4 параметра.
hwndParent
Идентифицирует родительское окно, чьи дочерние окна должны быть найдены. Если hwndParent - ПУСТО (NULL), функция использует окно рабочего стола как родительское окно. Функция ищет среди окон, которые являются дочерними окнами рабочего стола.
hwndChildAfter
Идентифицирует дочернее окно. Поиск начинается со следующего дочернего окна в Z - последовательности. hwndChildAfter должен быть прямое дочернее окно hwndParent, а не простое порожденное окно. Если hwndChildAfter - ПУСТО (NULL), поиск начинается с первого дочернего окна определенного параметром hwndParent. Обратите внимание, что, если и hwndParent и hwndChildAfter - ПУСТО (NULL), функция ищет все окна верхнего уровня.
lpszClass
Указывает на строку с нулевым символом в конце, которая определяет имя класса или - атом, который идентифицирует строку имени класса. Если этот параметр - атом, он должен быть общий атом, созданный предыдущим вызовом к функции GlobalAddAtom. Атом, 16-разрядное значение, в котором должно быть размещено в младшей части слова - lpszClass; старшее слово должно быть нулевое.
lpszWindow
Указывает на строку с нулевым символом в конце, которая определяет имя окна (заголовок окна). Если этот параметр ПУСТО (NULL), имена всех окон соответствующие.
Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор окна, которое имеет определенный класс и имена окон.
И если с первыми двумя могу стоить догадки, что туда передается хендл окна и листа, то что в указатели писать..
Re: Позиционирование на колонке листбокса
Добавлено: 27 Апрель 2011, 13:24
Jornada
Код: Выделить всё
PROGRAM
! Common equates
HANDLE EQUATE(UNSIGNED)
HWND EQUATE(HANDLE)
HBITMAP EQUATE(HANDLE)
HDC EQUATE(HANDLE)
HGDIOBJ EQUATE(HANDLE)
HBRUSH EQUATE(HANDLE)
WPARAM EQUATE(UNSIGNED)
LPARAM EQUATE(LONG)
GWL_WNDPROC EQUATE(-4)
SB_HORZ EQUATE(0)
SB_VERT EQUATE(1)
SB EQUATE(3)
WM_HSCROLL EQUATE(0114h)
WM_CTLCOLORSCROLLBAR EQUATE(0137h)
MAP
PaintArea_WndProc (HWND hWnd, UNSIGNED wMsg, WPARAM wParam, LPARAM lParam),LONG,PASCAL
MODULE('Windows API')
CallWindowProc (LONG lpPrevWndFunc, HWND hWnd, UNSIGNED wMsg, WPARAM wParam, LPARAM lParam),LONG,PASCAL,NAME('CallWindowProcA')
GetScrollPos (HWND hWnd, SIGNED nBar),SIGNED,PASCAL
SetScrollPos (HWND hWnd, SIGNED nBar, SIGNED Pos, BOOL),SIGNED,PASCAL
SetWindowLong (HWND hWnd, SIGNED nIndex, LONG dwNewLong),LONG,PROC,PASCAL,NAME('SetWindowLongA')
SetScrollRange (HWND, SIGNED, SIGNED, SIGNED, BOOL),PASCAL
END
END
PaintArea_WndProc_Addr LONG ! Адрес оригинальной процедуры окна
PaintArea_hWnd HWND ! Handle окна области просмотра
PaintArea_hDC HDC ! Контекст области просмотра
PaintArea_hMemDC HDC ! Контекст в памяти с картинкой
PaintArea_hBitMap HBITMAP ! Битовая карта изображения
PaintArea_hOldBitMap HBITMAP ! Предыдущая битовая карта контекста
PaintArea_HScrollPos SIGNED ! Текущая позиция (0-255) горизонтального скролбара
PaintArea_VScrollPos SIGNED ! Текущая позиция (0-255) вертикального скролбара
DataQueue QUEUE,PRE()
Level1 LONG
Level2 LONG
Level3 LONG
Level4 LONG
END
PaintArea:Win WINDOW('Paint Area'),AT(,,300,200),FONT('MS Sans Serif',8),CENTER,GRAY,DOUBLE,SYSTEM
!LIST,AT(0,0,100,100),USE(?List),FULL,HVSCROLL,IMM
LIST,AT(0,0,200,100),USE(?List),FORMAT('80L(2)|M~Level1~@s20@80L(2)|M~Level2~@s20@80L(2)|M~Level3~@s20@80L(2)|M~Level4~@s20@'),FROM(DataQueue) ,HVSCROLL,IMM
!IMAGE('Blank_500x500.gif'),AT(5,5,125,105),USE(?PaintArea:Image),HVSCROLL
PROMPT('Horz:'),AT(5,116)
STRING(@s6),AT(28,116),USE(PaintArea_HScrollPos)
PROMPT('Vert:'),AT(74,116)
STRING(@s6),AT(94,116),USE(PaintArea_VScrollPos)
END
!*************************************************************************************************
CODE
OPEN(PaintArea:Win)
Level1 = 1
Level2 = 2
Level3 = 3
Level4 = 4
add (DataQueue)
?List{PROP:From} = DataQueue
! PaintArea_hWnd = ?PaintArea:Image{PROP:Handle}
PaintArea_hWnd = ?List{PROP:Handle}
! Сабклассинг области просмотра
PaintArea_WndProc_Addr = SetWindowLong(PaintArea_hWnd, GWL_WNDPROC, ADDRESS(PaintArea_WndProc))
! Цикл работы с окном
ACCEPT
END
CLOSE(PaintArea:Win)
!*************************************************************************************************
PaintArea_WndProc PROCEDURE(HWND hWnd, UNSIGNED wMsg, WPARAM wParam, LPARAM lParam)
hDC HDC
hWndDC HDC
!PStruct LIKE(PAINTSTRUCT)
!DrawRect LIKE(RECT) ! Координаты области для просмотра
PosX LONG ! Координаты левого верхнего угла
PosY LONG ! отображаемой части картинки
res BYTE
CODE
CASE wMsg
OF WM_CTLCOLORSCROLLBAR!WM_HSCROLL
! Просто для информации позиция скролбара
!SetScrollRange (hWnd, SB_HORZ, 0, 255, TRUE)
PaintArea_HScrollPos = GetScrollPos(hWnd, SB_HORZ)
PaintArea_HScrollPos = SetScrollPos(hWnd, SB_HORZ,20,true)
PaintArea_VScrollPos = GetScrollPos(hWnd, SB_VERT)
PaintArea_HScrollPos = SetScrollPos(hWnd, SB_VERT,40,true)
! PaintArea_VScrollPos = GetScrollPos(hWnd, SB)
! PaintArea_HScrollPos = SetScrollPos(hWnd, SB,40,true)
DISPLAY(?PaintArea_HScrollPos)
DISPLAY(?PaintArea_VScrollPos)
RETURN FALSE
END
RETURN CallWindowProc(PaintArea_WndProc_Addr, hWnd, wMsg, wParam, lParam)
Вот слегка изменный код одного примера с сайта (там был ?image). Если изменить положение вертикального бегунка и потом мышой выделить горионтальный, т.е. сгенерировать событие WM_HSCROLL, то положение вертикального бегунка станет 40. А отобразит на экране значение последнего его положения, до 40. (причем почему то для горизонтального значение будет тоже самое) На горизонтальный влиять не удается. А если раскомментировать !SetScrollRange (hWnd, SB_HORZ, 0, 255, TRUE), то появится еще один горионтальный скролл) не рабочий. Пробовал с событием WM_CTLCOLORSCROLLBAR. То же самое. А еще у меня горизонтальный скролл отрисован как в win95 - без теней и полутонов, в отличие от вертикального. Такое чуйство, что клара его где то сама ловит параллельно со мной и свою логику вкладывает.