-
Задача: написать визуальный компонент (), видимую область которого можно прокручивать его собственными скроллбарами.
Пояснения: компонент наследуется от TCustomControl'a, обладает свойством Align.
Вопрос: Что нужно сделать, чтобы у компонента появились виндузовские скроллбары? Есть мнение, что это свойство наследуется от WinControl'a, но не открыто...и что копать к тому же надо в сторону WinApi...
Очень хочется или подробного комментария, или не менее полезную ссылку. Заранее большое спасибо всем отклинувшимся.
-
> копать к тому же надо в сторону WinApi...
эт правильно. Нужно в CreateParams добавить два стилевых флага: WM_HSCROLL и WM_VSCROLL.
-
> Нужно в CreateParams добавить два стилевых флага
Это как-то так? procedure TMyComponent.CreateParams(var Params: TCreateParams);
begin
Params.Style := WM_HSCROLL;
end; Ругается, что параметр задан не верно... Не подскажите синтаксис установки параметров?
-
Эх... Никада не делал этого раньше... Я про CreateParams только слышал. Ваще мой тебе совет переходи на АПИ. А с этим погоди ща разберёмся.
-
Удалено модератором
-
> Тфу ёшкинсвет, не WM_, а WS_ !!!!!!!!!!! Прости великодушно. > ..
Круто! Заработало! Но чуточку не так, как я ожидал... Теперь мой компонент - отдельное окно... летает себе... но скролл появился!
И чего это он выпал из контейнера...
Отделение произошло из-за чего? Что не так с Controls'ами?
-
Разобрался! Вернул на место. Люди, не повторяйте моих ошибок! Свойство Params.Style задается в предке, не стоит его полностью изменять, если в этом нет нужды.
Полная картина выглядит так:
procedure TMyComponent.CreateParams(var Params: TCreateParams); begin inherited; Params.Style := Params.Style + WS_HSCROLL + WS_VSCROLL; end;
Dib@zol © - отдельное спасибо!
-
Дело вот в этом. Изини, тож забыл :) Params.Style := Params.Style + WM_HSCROLL;
-
> Люди, не повторяйте моих ошибок!
Уже повторили :) Надо ж блин, как совпало ;)
-
А вариант с WinApi как бы выглядел?
-
var ScrollHWND:HWND; WP : Pointer;
...
ScrollHWND:=CreateWindow(0, 'STATIC', '', WS_VISIBLE or WS_CHILD or WS_HSCROLL or WS_VSCROLL, 1, 1, 300, 300, Parent, 0, HInstance, nil); longInt(WP):=SetWindowLong(ScrollHWND, GWL_WNDPROC, LongInt(@NewWndProc));
Где Parent - хендл родительского окна. NewWndProc нужно?
-
> NewWndProc нужно?
Да!
-
function NewWndProc(hWnd : HWND; Msg, WParam, LParam : LongInt) : LongInt; stdcall; begin Result:=0; case Msg of
WM_COMMAND: begin // Здесь принимаются сообщения от дочерних контролов end;
WM_CTLCOLOR*: begin // Ответственные за перерисовку (WM_CTLCOLORSTATIC, WM_CTLCOLOREDIT итп) end;
// Да мало ли чего ещё сюда можно напихать! :) Эти - просто примеры.
else Result:=CallWindowProc(WP, hWnd, Msg, WParam, LParam); end; end;
-
Огромный Тенкс!!!!
Я думаю, что тема прикрыта, но не закрыта...
-
> EG (20.07.07 20:32) [13]
Ну, раз тема не закрыта, то предложу еще одно решение - взять стандартный TScrollBox.
:о)
-
> Юрий Зотов © (21.07.07 11:57) [14]
> Задача: написать визуальный компонент
-
> [15] Dib@zol © (21.07.07 12:17) > > > Юрий Зотов © (21.07.07 11:57) [14] > > > Задача: написать визуальный компонент
Зачем его писать, если он уже написан? :)
> EG Чем твоя задача отличается от [14]? Хотя может.... тогда уже наследуйся от него(TScrollBox)...или его предка (скролингвиндов)... имхо. Зачем с нуля "велик" делать?
-
> Dib@zol © (21.07.07 12:17) [15]
Довольно часто ЗАДАЧА возникает лишь по причине незнания того, что она уже давно ЗАДАЧЕЙ вовсе не является. :о)
-
Удалено модератором
-
> Dib@zol © (21.07.07 14:05) [18]
Один человек спросил у другого, где можно купить сигарет. Тот ответил, что их можно купить в магазине, который находится в 5 километрах.
А другой человек сказал, что такой же магазин находится за углом, в 50 метрах. И тогда первый человек возразил: "Ну так или иначе, я поццказал".
И ведь действительно подсказал. Но лучше бы он этого не делал.
-
Поверьте, велик делать никому не охота, а просто приходится... Причина проста: нужен компонент с нестандартной функциональностью. Точнее с такой, какой готовые варианты и решения не обладают в полной мере.
> Чем твоя задача отличается от [14]?
Тем, что компонент должен быть самодостаточным в своей функциональности.
Требуемый компонент - это не скроллбар. Скроллбар лишь одна из его видимых частей, реализующая определенную функциональность, в данном случае скроллирование видимой области.
-
> EG (23.07.07 18:33) [20]
А почему бы эту прокручиваемую область не сделать в виде агрегированного TScrollBox?
-
Хм... Ни разу не юзал эту вещь... может помочь в моей ситуации?
-
Если компонент оконный, а его прокручиваемая область по своей функциональности ничем не отличается от TScrollBox, то ее и надо делать этим самым TScrollBox-ом.
Компонент в своем конструкторе создает TScrollBox, его Owner-ом и Parent-ом ставит Self, выставляет позицию, размеры и прочие настройки TScrollBox-а. Вот и все.
Еще более простой вариант - взять фрейм, накидать на него все, что нужно, написать в нем необходимый код и зарегистрировать его в качестве компонента.
-
> Если компонент оконный, а его прокручиваемая область по > своей функциональности ничем не отличается от TScrollBox, > то ее и надо делать этим самым TScrollBox-ом
Если нечто выглядит как собака, лает как собака и кусается как собака, то это и есть собака.
Все компоненты с прокручваемой областью наследуются от TScrollingWinControl, все зависит от того, насколько область совпадает с желаемой клиентской областью. Если совпадает, как у TScrollBox/TForm/TFrame то проще наследоваться от них, если несовпадает, то проще создавать вложенный контрол, унаследованный от TScrollingWinControl.
-
> Все компоненты с прокручваемой областью наследуются от TScrollingWinControl, > все зависит от того, насколько область совпадает с желаемой > клиентской областью. Если совпадает, как у TScrollBox/TForm/TFrame > то проще наследоваться от них, если несовпадает, то проще > создавать вложенный контрол, унаследованный от TScrollingWinControl. >
Ну не надо так категорично. :) Не все. (TCustomGrid = class(TCustomControl)) При написании всяких гридов и т.п. особенно, если могут быть фиксируемые столбцы, гораздо логичнее использовать стандартные скроллы. А вот лепить туда вложенный контрол будет уже вырыванием гландов через известное место. :)
-
Макс Черных © (25.07.07 01:46) [25]
Не соглашусь хотя бы по той причине, что CustomGrid - довольно сложный компонент. И писать нечто подобное не для массового использования просто невыгодно.
-
HELP! Подскажите, как сказать системе, что сообщение WMVScroll(var Message: TWMVScroll) обработано? Или я не понимаю, что происходит: обрабатываю это сообщение с флагом SB_LINEUP, а мне после этого тут же валится еще одно сообщение с флагом SB_THUMBPOSITION.
-
На всякие пожарный привожу полный код: procedure TMyDocument.WMVScroll(var Message: TWMVScroll);
var
sbInfo : TSCROLLINFO;
ScrollDY : integer;
YScrollFullLength: integer;
DocumentDY: integer;
begin
case ( Message.ScrollCode ) of
0:
begin
sbInfo.fMask := SIF_POS or SIF_RANGE or SIF_TRACKPOS;
sbInfo.cbSize := sizeof(TSCROLLINFO);
GetScrollInfo( Handle, SB_VERT, sbInfo );
YScrollFullLength := sbInfo.nMax - sbInfo.nMin;
ScrollDY := YScrollFullLength div 100;
DocumentDY := ( ScrollDY * FDocumentHeight ) div YScrollFullLength;
MoveDocumentPosition( 0, DocumentDY );
Repaint();
sbInfo.cbSize := sizeof(TSCROLLINFO);
sbInfo.fMask := SIF_POS;
sbInfo.nPos := sbInfo.nPos - ScrollDY;
SetScrollInfo( Handle, SB_VERT, sbInfo, true );
end;
1:;
2:ShowMessage('');
3:;
else
begin
sbInfo.fMask := SIF_POS or SIF_RANGE or SIF_TRACKPOS;
sbInfo.cbSize := sizeof(TSCROLLINFO);
GetScrollInfo( Handle, SB_VERT, sbInfo );
if ( sbInfo.nPos <> sbInfo.nTrackPos )
then
begin
ScrollDY := sbInfo.nPos - sbInfo.nTrackPos;
YScrollFullLength := sbInfo.nMax - sbInfo.nMin;
DocumentDY := ( ScrollDY * FDocumentHeight ) div YScrollFullLength;
MoveDocumentPosition( 0, DocumentDY );
Repaint();
sbInfo.cbSize := sizeof(TSCROLLINFO);
sbInfo.fMask := SIF_POS;
sbInfo.nPos := sbInfo.nTrackPos;
SetScrollInfo( Handle, SB_VERT, sbInfo, true );
end;
end;
end;
end;
-
-
-
-
"Return Value
If an application processes this message, it should return zero. "
Значений Message.ScrollCode больше, чем Вы обрабатываете
-
> Lacmus © (01.08.07 21:05) [32] > > "Return Value > > If an application processes this message, it should return > zero. " > > Значений Message.ScrollCode больше, чем Вы обрабатываете
Да, я тупой. Спасибо. Помогло.
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
|