Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.07.2013, 03:34   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
Вопрос TComboBox с TLabel как TLabeledEdit, есть у кого?

Доброго времени суток!

Видел ли кто-нибудь реализацию TComboBox + TLabel?

Пробовал сам:
Код:
unit arhComboBox;

interface

uses System.SysUtils,System.Classes,Vcl.Controls,Vcl.StdCtrls,Vcl.ExtCtrls,Winapi.Messages, Winapi.Windows;

type
  TArhComboBox = class(TComboBox)
  private
    FEditLabel: TBoundLabel;
    FLabelPosition: TLabelPosition;
    FLabelSpacing: Integer;
    procedure SetLabelPosition(const Value: TLabelPosition);
    procedure SetLabelSpacing(const Value: Integer);
  protected
    procedure SetParent(AParent: TWinControl); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation);
      override;
    procedure SetName(const Value: TComponentName); override;
    procedure CMVisiblechanged(var Message: TMessage); message CM_VISIBLECHANGED;
    procedure CMEnabledchanged(var Message: TMessage); message CM_ENABLEDCHANGED;
    procedure CMBidimodechanged(var Message: TMessage); message CM_BIDIMODECHANGED;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer;
      AHeight: Integer); override;
    procedure SetupInternalLabel;
  published
    property EditLabel: TBoundLabel read FEditLabel;
    property LabelPosition: TLabelPosition read FLabelPosition
      write SetLabelPosition default lpAbove;
    property LabelSpacing: Integer read FLabelSpacing write SetLabelSpacing
      default 3;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Standard', [TArhComboBox]);
end;

constructor TArhComboBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FLabelPosition := lpAbove;
  FLabelSpacing := 3;
  SetupInternalLabel;
end;

procedure TArhComboBox.CMBidimodechanged(var Message: TMessage);
begin
  inherited;
  if FEditLabel <> nil then
    FEditLabel.BiDiMode := BiDiMode;
end;

procedure TArhComboBox.CMEnabledchanged(var Message: TMessage);
begin
  inherited;
  if FEditLabel <> nil then
    FEditLabel.Enabled := Enabled;
end;

procedure TArhComboBox.CMVisiblechanged(var Message: TMessage);
begin
  inherited;
  if FEditLabel <> nil then
    FEditLabel.Visible := Visible;
end;

procedure TArhComboBox.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (AComponent = FEditLabel) and (Operation = opRemove) then
    FEditLabel := nil;
end;

procedure TArhComboBox.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
  inherited SetBounds(ALeft, ATop, AWidth, AHeight);
  SetLabelPosition(FLabelPosition);
end;

procedure TArhComboBox.SetLabelPosition(const Value: TLabelPosition);
var
  P: TPoint;
begin
  if FEditLabel = nil then
    Exit;
  FLabelPosition := Value;
  case Value of
    lpAbove:
      P := Point(Left, Top - FEditLabel.Height - FLabelSpacing);
    lpBelow:
      P := Point(Left, Top + Height + FLabelSpacing);

    lpLeft:
      P := Point(Left - FEditLabel.Width - FLabelSpacing,
        Top + ((Height - FEditLabel.Height) div 2));

    lpRight:
      P := Point(Left + Width + FLabelSpacing,
        Top + ((Height - FEditLabel.Height) div 2));
  end;
  FEditLabel.SetBounds(P.x, P.y, FEditLabel.Width, FEditLabel.Height);
end;

procedure TArhComboBox.SetLabelSpacing(const Value: Integer);
begin
  FLabelSpacing := Value;
  SetLabelPosition(FLabelPosition);
end;

procedure TArhComboBox.SetName(const Value: TComponentName);
var
  LClearText: Boolean;
begin
  if (csDesigning in ComponentState) and (FEditLabel <> nil) and
    ((FEditLabel.GetTextLen = 0) or (CompareText(FEditLabel.Caption, Name) = 0))
  then
    FEditLabel.Caption := Value;
  LClearText := (csDesigning in ComponentState) and (Text = '');
  inherited SetName(Value);
  if LClearText then
    Text := '';
end;

procedure TArhComboBox.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);
  if FEditLabel = nil then
    Exit;
  FEditLabel.Parent := AParent;
  FEditLabel.Visible := True;
end;

procedure TArhComboBox.SetupInternalLabel;
begin
  if Assigned(FEditLabel) then
    Exit;
  FEditLabel := TBoundLabel.Create(Self);
  FEditLabel.FreeNotification(Self);
end;

end.
Просто взяв код TLabeledEdit.

Компонент получился, но работает не так, как мне надо.

Суть бага:
Пускай компонент лежит в 5 пикселях от правого края формы, текст. метка находится слева от компонента.

Если я в Run-time меняю текст метки на длинный текст,
то сдвигается сам компонент вправо и залезает за край формы.

Получается что текст. метка двигает компонент, вместо того, чтобы самой подвинуться влево так чтобы вместился текст, но не двигать компонент за края формы.


Как от этого избавиться?

Стандартный TLabeledEdit реагирует на это как мне нужно, почему с ComboBox'ом не получилось - не знаю
Человек_Борща вне форума Ответить с цитированием
Старый 18.07.2013, 08:21   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Никогда такого сам не делал, а если бы делал, то скорее всего фреймами.
У тебя при изменении текста нет никакого обработчика - сделай. И в нем пропиши сдвиг лабели(или получается всего компонента) на Canvas.TextWidth(Добавленный текст). Это как вариант.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 18.07.2013, 11:26   #3
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Нет, все проще.
Я наследовал свой BoundLabel от TBoundLabel и переопределил protected метод AjustBounds в которых идет проверка на наличие Owner'а как TLabeledEdit а затем вызов AjustBounds компонента, и добавил проверку на свой компонент.

Problem solved.

Последний раз редактировалось Человек_Борща; 18.07.2013 в 11:29.
Человек_Борща вне форума Ответить с цитированием
Старый 18.07.2013, 14:37   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Да-а-а... На твоих темах учится можно...
Прям Тейксеру переплюнуть можешь )
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 18.07.2013, 18:53   #5
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Да я не жадный =)
Одно дело понять написанное и самостоятельно повторить, и совсем другое "у этого чувака работает, возьму его код, будет у меня работать".
Код:
type
  TArhBoundLabel = class(TBoundLabel)
  protected
    procedure AdjustBounds; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property BiDiMode;
    property Caption;
    property Color;
    property DragCursor;
    property DragKind;
    property DragMode;
    property Font;
    property Height;
    property Left;
    property ParentBiDiMode;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowAccelChar;
    property ShowHint;
    property Top;
    property Touch;
    property Transparent;
    property Layout;
    property WordWrap;
    property Width;
    property OnClick;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnGesture;
    property OnMouseActivate;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDock;
    property OnStartDrag;
  end;

....
{ TArhBoundLabel }

constructor TArhBoundLabel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Name := 'SubLabel';
  SetSubComponent(True);
  if Assigned(AOwner) then
    Caption := AOwner.Name;
end;

procedure TArhBoundLabel.AdjustBounds;
begin
  inherited AdjustBounds;
  if (Owner is TArhComboBox) then
    with (Owner as TArhComboBox) do
      SetLabelPosition(LabelPosition);
end;
Человек_Борща вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ЛЮДИ!!!!!есть добрые люди??ОЧЕНь МАЛО ВРЕМЕНИ ДО СДАЧИ ОСТАЛОСЬ.. У КОГО ЕСТЬ ВОЗМОЖНОСТЬ отпишитессь!!!БУДУ ОЧЕНЬ ПРИЗНАТЕЛЕН... SwAAAte83 Паскаль, Turbo Pascal, PascalABC.NET 3 20.01.2012 06:09
есть ошибки? (протестите у кого С++ есть) Юлия_Ф Помощь студентам 11 07.10.2011 10:42
Как решать японские кроссворды или судоку? Может у кого-нибудь есть идеи? TwiX Свободное общение 2 16.08.2009 07:56
У кого есть исходник ALEKS_STRELOK Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 17.03.2009 19:53
FRAPS - У кого есть??? PAVEL315 Софт 1 28.11.2007 05:32