Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.10.21;
Скачать: CL | DM;

Вниз

TComboBox и его стили   Найти похожие ветки 

 
Толик ©   (2002-10-09 14:41) [0]

Уважаемые мастера. М.б. кто-то сможет взглянуть на проблему с иной стороны, чем я, и натолкнуть меня на верное решение.
Суть проблемы:

Есть форма, на ней самый обычный TComboBox со стилем csDropDown. Никакого кода. ComboBox содержит несколько строк, добавленных в design-time, длина которых заведомо больше видимой области выпадающего списка. Есть желание, чтобы выпадающий список ComboBox"а имел горизонтальный скроллер. Известно, что данная возможность достигается путём отсылки сообщения CB_SETHORIZONTALEXTENT, при этом окно должно иметь стиль WS_HSCROLL. Изначально ComboBox не имеет этого стиля. Казалось бы, WS_HSCROLL можно добавить через SetWindowLong с параметром GWL_STYLE. Но вот именно в этом и проблема:

SetWindowLong(ComboBox1.Handle, GWL_STYLE, GetWindowLong(ComboBox1.Handle, GWL_STYLE) or WS_HSCROLL);
if GetWindowLong(ComboBox1.Handle, GWL_STYLE) and WS_HSCROLL > 0 then
ShowMessage("WS_HSCROLL present!");

бодро выдаёт: "WS_HSCROLL present!", но последующая отсылка CB_SETHORIZONTALEXTENT скроллера не добавляет. (Очевидно, что параметр, определяющий ширину прокручиваемой области заведомо больше, чем ComboBоx1.Width)

Эксперименты с созданием окна класса COMBOBOX через CreateWindow показали, что скроллер появляется только в том случае, если стиль WS_HSCROLL входил в значение параметра dwStyle ф-и CreateWindow. В случае с добавлением этого стиля через SetWindowLong скроллер появлялся не у выпадающего списка, а у поля, содержащего кнопку выпадающего списка!!!

Одно из возможных решений - наследоваться от TComboBox и перекрыть CreateParams. В этом случае всё работает. А вот можно ли обойтись без наследования? Очень уж не хочется плодить компоненты ради одной не очень существенно возможности.
Буду благодарен за любые советы и предложения.


 
still ©   (2002-10-09 14:50) [1]


> Одно из возможных решений - наследоваться от TComboBox и
> перекрыть CreateParams

я бы так и сделал


 
Оля   (2002-10-09 14:56) [2]

Конечно ради "спортивного" интереса можно и голову поломать денек другой, а нельзя ли просто программно увеличивать размер Width только на то время пока открыт ComboBox?


 
REA ©   (2002-10-09 15:00) [3]

Выпадающая часть может быть больше самого бокса - там где-то свойство есть. Я обычно это и использую. Юзеру скроллировать напряжно.


 
Толик ©   (2002-10-09 15:13) [4]

to still © (09.10.02 14:50)
... и положить его на палитру компонентов...
Нет уж, намучался я в своё время со всякими "левыми" компонентами в проектах, тем более, что у нас в конторе существует жёстко оговоренный список компонентов для использования. Можно конечно его создавать в run-time, но тогда теряется концепция: что-то создаётся в run-time, что-то в design-time - винигрет какой-то.

to Оля (09.10.02 14:56)
Да, это вариант. CB_SETDROPPEDWIDTH работает. Но есть одно замечание: допустим этот список содержит довольно много коротких строк и одну довольно длинную. Ширина выпадающей области будет равна длине максимальной строки. Вот и получается, что ради одной строки будет вываливаться окно на пол-экрана. Неэстетично как-то. Хотя сейчас именно так и сделано :(

М.б. есть ещё какие-нибудь соображения?


 
Толик ©   (2002-10-09 16:07) [5]

поехали наверх.


 
Оля   (2002-10-09 17:07) [6]

А если разместить длинную строку в несколько строк и уложить в ComboBox, а чтоб пользователю было понятней сделать пробел до и после строки, например:
1. 5х0,5
2. 5х1,0
3. 6х1,0
4. 8х0,8
5. 8х1,0

6. 1111111111111
1111111111111
1111111111111
1111111111111
и т.д.

7. 10х0,8
8. 10х1,0
9. 10х1,5
10. 10х2,0
11. 15х2,5
И пусть программа реагирует на шестой пункт ComboBox1.ItemIndex от 6 до 10


 
still ©   (2002-10-09 17:14) [7]


> Оля (09.10.02 17:07)

слушай, грамотная мысль вообще-то

а можно еще так - показывать длиную строку урезанной
типа
111
222...
333
а при подведении курсора показывать tooltip"ом продолжение (ну типа как в treeview сделано)


 
Юрий Зотов ©   (2002-10-09 17:18) [8]

> И пусть программа реагирует на шестой пункт
> ComboBox1.ItemIndex от 6 до 10

Лучше рисовать текст Item"ов самому, хоть с WordWrap, хоть как угодно еще (см. DrawText). Тогда не придется мудрить с индексами.


 
han_malign ©   (2002-10-09 17:24) [9]

ComboBox дает Handle только для основного поля, получить handle на выпадающий список не возможно (я в свое время неделю прокалупался когда Checked combo box делал), соответственно ничего сверх того что Windows на с этого списка дает не получится (и свой сабклассинг не поможет)


 
MBo ©   (2002-10-09 17:29) [10]

>han_malign
>handle на выпадающий список не возможно

возможно


 
Толик ©   (2002-10-09 17:56) [11]

to All
Спасибо за участие в решении проблемы. Рисование руками item"ов - это выход. Но по поводу скроллера - это уже просто интересно: нигде ведь ничего не написано по этому поводу (по крайней мере мне не встречалось)

to MBo © (09.10.02 17:29)
если я ничего не путаю, то handle списка можно получить только для ComboBox"ов со стилем csSimple. Ну не считая конечно всяких извращенческих способов типа определения Handl"а окна под мышью и т.д. Или есть способ для произвольного стиля ComboBox"а найти Handle его выпадающей части?


 
MBo ©   (2002-10-09 18:01) [12]

>для произвольного стиля ComboBox"а найти Handle его выпадающей части
Если перекрыть windowproc для combobox, то при при отлове сообщений от выпадающей части LParam будет содержать нужный дескриптор


 
Кот Бегемот ©   (2002-10-09 18:19) [13]

Вот классный пример действительно правильно сформурированного вопроса :))) - на который ХОЧЕТЬСЯ ответить

Это же надо как человек обозвал самое обычное решение с плавающим Hintом для списков, я бы так точно не смог.
Похоже на научную работу. Класс :)

Я думаю уважаемый Толик © далеко пойдет по стезе программирования , пожелаем ему удачи :)


 
Макс Черных ©   (2002-10-09 23:38) [14]

2 Толик

> если я ничего не путаю, то handle списка можно получить
> только для ComboBox"ов со стилем csSimple

Путаешь.

2 MBo


> Если перекрыть windowproc для combobox, то при при отлове
> сообщений от выпадающей части LParam будет содержать нужный
> дескриптор

Как сказал бы Ю.Зотов - зачем табуреткой забивать гвозди?

Имеется простой способ получения Handle выпадающей части,
а именно функция API GetComboBoxInfo, для примера:

var CbInfo: TComboBoxInfo;
GetComboBoxInfo(ComboBox1.Handle, CbInfo);

Вот теперь в поле - CbIngo.hwndList и будет этот Handle








 
MBo ©   (2002-10-10 06:42) [15]

>Макс Черных
>GetComboBoxInfo
Спасибо, не знал об этом, полезная штука, в SDK Help отсутствует, но в MSDN есть, появилась в Win98

>Толик
http://www.delphikingdom.com/treasury/combo.htm


 
Толик ©   (2002-10-10 13:24) [16]

Спасибо большое всем, принявшим участие в решении проблемы.

to MBo © (09.10.02 18:01)
Стыдно мне, стыдно. Я сам должен был догадаться насчёт WndProc. Воистину, мастерство заключается не только в знании, но и в умении их применять :)

Особое спасибо Максу Черных © (09.10.02 23:38)
Вот уж воистину: век живи - век учись :) М-да, не знал о такой возможности, не знал...


 
Игорь Шевченко ©   (2002-10-10 13:37) [17]

Макс Черных © (09.10.02 23:38)

К сожалению, GetComboBoxInfo есть не во всех системах. А во всех системах работает перехват сообщения WM_PARENTNOTIFY или WM_CTLCOLORLISTBOX в оконной процедуре ComboBox"а.

С уважением,



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

Текущий архив: 2002.10.21;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.025 c
1-68697
.
2002-10-10 15:52
2002.10.21
http rfc


14-68950
cok
2002-09-22 11:12
2002.10.21
Я вернулся


1-68767
id_privin
2002-10-11 12:05
2002.10.21
Как загрузить иконку из ресурса?


1-68789
Dimedrol
2002-10-09 18:33
2002.10.21
DLL и компоненты доступа к БД


1-68690
AL2002
2002-10-10 19:17
2002.10.21
SendMessage? A kak?