Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.10.14;
Скачать: [xml.tar.bz2];

Вниз

ListBox, ComboBox и т.д.   Найти похожие ветки 

 
Dim!S   (2002-10-04 12:29) [0]

Уважаемые мастера, подскажите, пожалуйста, как в ListBox и подобных компонентах вставить черту-разделитель как в меню. Необходимо несколько пунктов сделать постоянными, не зависимо от пользователя и их отделить тонкой чертой. Спасибо.


 
Best Before 2024   (2002-10-04 12:34) [1]

OnDrawItem ?


 
Игорь Шевченко   (2002-10-04 12:38) [2]

Часть 1
{
Расширение компонента TCustomComboBox, позволяющее запрещать выбор отдельных
элементов списка и имеющее список ассоциированных значений.
Стиль этого компонента может быть только csDropDownList, csOwnerDrawFixed
или csOwnerDrawVariable.
08.04.2002
Добавлено событие рисования прямоугольника фокуса отдельной процедурой

07.04.2002
(С) 2002, Игорь Шевченко, HyperSoft
}

unit HSComboBox;

interface
uses
Windows, Messages, Classes, Controls, StdCtrls;

type
TOnCanSelectEvent = procedure (Sender : TObject; Index : Integer;
var CanSelect : Boolean) of object;
TOnDrawFocusRectEvent = procedure (Sender : TObject;
const Rect : TRect;
State: TOwnerDrawState) of object;
TFocusRectKind = (frStandard, frCustom);

THSComboBox = class(TCustomComboBox)
private
{ Список ассоциированных значений }
FValues : TStrings;
FLastKey : Integer;
FOnCanSelect: TOnCanSelectEvent;
FFocusRectKind: TFocusRectKind;
FOnDrawFocusRect: TOnDrawFocusRectEvent;
function CanSelectItem (AItemIndex : Integer) : Boolean;
function GetValue: String;
procedure SetValue(const Value: String);
procedure SetValues(const Value: TStrings);
procedure SetFocusRectKind(const Value: TFocusRectKind);
procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
protected
{ Обработчик события определения доступности элемента списка }
{ Сделан виртуальным для возможности переопределения в наследниках компонента}
procedure DoCanSelect (AItemIndex : Integer; var CanSelect : Boolean); dynamic;
{ Отрисовка FocusRect }
procedure DoDrawFocusRect (const Rect : TRect;
State: TOwnerDrawState); dynamic;
procedure Change; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure SetStyle (Value : TComboBoxStyle); override;
{ Для рисования разделительных строк не надо
вызывать процедуру пользователя }
procedure DrawItem(Index: Integer; Rect: TRect;
State: TOwnerDrawState); override;
public
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
{ Ассоциированное с элементом списка значение из списка значений.
Сделано только в runtime, так как в design-time оно не имеет смысла }
property Value : String read GetValue write SetValue;
published
property Style; {Must be published before Items}
property Anchors;
property BiDiMode;
property Color;
property Constraints;
property Ctl3D;
property DragCursor;
property DragKind;
property DragMode;
property DropDownCount;
property Enabled;
property Font;
property ImeMode;
property ImeName;
property ItemHeight;
property MaxLength;
property ParentBiDiMode;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Sorted;
property TabOrder;
property TabStop;
property Text;
property Visible;
{ Список ассоциированных значений для редактирования, копирования и т.д. }
property Values : TStrings read FValues write SetValues;
{ Тип прямоугольника фокуса }
property FocusRectKind : TFocusRectKind
read FFocusRectKind write SetFocusRectKind default frStandard;
{ События }
property OnChange;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnDrawItem;
property OnDropDown;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMeasureItem;
property OnStartDock;
property OnStartDrag;

property Items; { Must be published after OnMeasureItem }
{ Событие для определения доступности элемента списка ComboBox"а }
property OnCanSelect : TOnCanSelectEvent read FOnCanSelect
write FOnCanSelect;
{ Событие для отрисовки FocusRect,когда компонент имеет фокус }
{ Вызывается только в случае установки FocusRectKind в frCustom }
property OnDrawFocusRect : TOnDrawFocusRectEvent read FOnDrawFocusRect
write FOnDrawFocusRect;

end;

{TODO: Перенести в отдельный unit и включить его в design-time package }
procedure Register;

implementation
uses
Graphics, SysUtils;

{ THSComboBox }



 
Игорь Шевченко   (2002-10-04 12:38) [3]

Часть 2
function THSComboBox.CanSelectItem(AItemIndex: Integer): Boolean;
var
CanSelect : Boolean;
begin
DoCanSelect (AItemIndex, CanSelect);
Result := CanSelect;
end;

procedure THSComboBox.Change;
var
OldIndex, NewIndex : Integer;
begin
OldIndex := ItemIndex;
NewIndex := OldIndex;
while NOT CanSelectItem(NewIndex) do
if FLastKey = VK_UP then begin
Dec(NewIndex);
if NewIndex < 0 then
FLastKey := VK_DOWN;
end else begin
Inc(NewIndex);
if NewIndex > Pred(Items.Count) then
FLastKey := VK_UP;
end;
if NewIndex <> OldIndex then
ItemIndex := NewIndex;
inherited;
end;

{ Переписано с небольшими исправлениями из TCustomComboBox.CNDrawItem }
procedure THSComboBox.CNDrawItem(var Message: TWMDrawItem);
var
State: TOwnerDrawState;
begin
with Message.DrawItemStruct^ do begin
State := TOwnerDrawState(LongRec(itemState).Lo);
if itemState and ODS_COMBOBOXEDIT <> 0 then
Include(State, odComboBoxEdit);
if itemState and ODS_DEFAULT <> 0 then
Include(State, odDefault);
Canvas.Handle := hDC;
Canvas.Font := Font;
Canvas.Brush := Brush;
if (Integer(itemID) >= 0) and (odSelected in State) then begin
Canvas.Brush.Color := clHighlight;
Canvas.Font.Color := clHighlightText
end;
if Integer(itemID) >= 0 then
DrawItem(itemID, rcItem, State)
else
Canvas.FillRect(rcItem);
if odFocused in State then
DoDrawFocusRect(rcItem, State);
Canvas.Handle := 0;
end;
end;

constructor THSComboBox.Create(AOwner: TComponent);
begin
inherited;
FValues := TStringList.Create;
FLastKey := VK_DOWN; { По умолчанию, последнее движение было вниз, при выборе
недоступного элемента фокус автоматически перемещается на следующий
доступный элемент }
FFocusRectKind := frStandard;
end;

destructor THSComboBox.Destroy;
begin
FValues.Free();
inherited;
end;

procedure THSComboBox.DoCanSelect(AItemIndex: Integer;
var CanSelect: Boolean);
begin
CanSelect := NOT ((Style = csOwnerDrawFixed) AND (Items[AItemIndex] = "-"));
if Assigned(FOnCanSelect) then
FOnCanSelect (Self, AItemIndex, CanSelect);
end;

procedure THSComboBox.DoDrawFocusRect(const Rect: TRect;
State: TOwnerDrawState);
begin
case FFocusRectKind of
frStandard:
Windows.DrawFocusRect(Canvas.Handle, Rect);
frCustom:
if Assigned(OnDrawFocusRect) then
FOnDrawFocusRect(Self, Rect, State);
end;
end;

procedure THSComboBox.DrawItem(Index: Integer; Rect: TRect;
State: TOwnerDrawState);
begin
if (Style = csOwnerDrawFixed) AND (Items[Index] = "-") AND
NOT (odComboBoxEdit in State) then begin
{ Нарисовать разделительную линию }
with TControlCanvas(Canvas) do begin
FillRect(Rect);
if odFocused in State then
Pen.Color := clWhite
else
Pen.Color := clBlack;
Pen.Width := 1;
MoveTo (Rect.Left, Rect.Top + (Rect.Bottom - Rect.Top) DIV 2);
LineTo (Rect.Right, Rect.Top + (Rect.Bottom - Rect.Top) DIV 2);
end;
end else
inherited;
end;

{ Вернуть ассоциированное с текущим элементом списка значение }
function THSComboBox.GetValue: String;
begin
Result := "";
if (ItemIndex >= 0) AND (ItemIndex < FValues.Count) then
Result := FValues[ItemIndex];
end;

procedure THSComboBox.KeyDown(var Key: Word; Shift: TShiftState);
begin
{ Для определения того, в какую сторону двигаться, если выбран недоступный
элемент, запоминаем последнюю нажатую клавишу. }
FLastKey := Key;
inherited;
end;

{ Установить новый стиль с запретом стилей csSimple,csDropDown. }
procedure THSComboBox.SetFocusRectKind(const Value: TFocusRectKind);
begin
if (FFocusRectKind <> Value) then begin
FFocusRectKind := Value;
Invalidate();
end;
end;

procedure THSComboBox.SetStyle(Value: TComboBoxStyle);
begin
if Value in [csSimple, csDropDown] then
Value := csDropDownList;
inherited SetStyle(Value);
end;

{ Установить элемент списка, с которым ассоциируется значение.
Если нового значения нет в списке, то установить выбранный индекс в -1 }
procedure THSComboBox.SetValue(const Value: String);
var NewIndex : Integer;
begin
NewIndex := FValues.IndexOf(Value);
if NewIndex > Pred(Items.Count) then
NewIndex := -1;
ItemIndex := NewIndex;
Change();
end;

procedure THSComboBox.SetValues(const Value: TStrings);
begin
FValues.Assign(Value);
end;

{TODO: Перенести в отдельный unit и включить его в design-time package }
procedure Register;
begin
RegisterComponents("HyperSoft", [THSComboBox]);
end;

end.


 
Dim!S   (2002-10-04 12:54) [4]

Спасибо, но не совсем то, что надо.
Я использую OnDrawItem, но отделительная линия хоть и тонкая, но занимает по высоте размер одного элемента, а надо как в меню...


 
Игорь Шевченко   (2002-10-04 12:57) [5]

Dim!S (04.10.02 12:54)

Добавить в OnMeasureItem код, установить стиль csOwnerDrawVariable


 
Dim!S   (2002-10-04 13:00) [6]

Посмотрю, спасибо.



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

Форум: "Основная";
Текущий архив: 2002.10.14;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.011 c
1-45443
glina
2002-10-03 17:23
2002.10.14
Подскажите неопытному


3-45175
Осирис
2002-09-20 13:58
2002.10.14
ADOConnection


1-45359
^SANYA
2002-10-05 01:15
2002.10.14
Шифрование...


14-45507
diww
2002-09-18 11:06
2002.10.14
подскажите хороший форум по NT


1-45369
Deke
2002-10-05 17:14
2002.10.14
Работа с DLL в Delphi. Помогите С-программеру.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский