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

Вниз

ComboBox с выпадающей формой TForm   Найти похожие ветки 

 
AlexGreG   (2004-06-25 09:17) [0]

Привет программистам.

Сделал компоненту "комбо-бокс с выпадающей формой"
Но проблема в публикации свойства DropDownForm:

property DropDownForm: TForm read FDropDownForm write SetDropDownForm;

При открытии в Инспекторе объектов списка доступных форм, отображаются все подключенные формы к модулю, в котором компонента расположена. Так и должно быть. Но при выборе какой либо формы, Дельфи ругается, мол Invalid property value.

Бросаю это дело (установку свойства в инспекторе объектов) и пытаюсь установить свойство
в run-time. Успешно. И работает всё как задумал (выпадает форма и прячется когда надо).

В чём подвох? Никак не могу разобраться.
Подскажите, в каком направлении искать ответ и решение.
Если можно, на почту киньте весточку AlexGreG@Yandex.ru


 
wisekaa ©   (2004-06-25 12:01) [1]

Посмотри как реализован TCheckListEdit у фирмы TMS, входит в компелек TMS Edits


 
dm ©   (2004-06-25 12:09) [2]

unit CustomEdit22;

interface

uses Types, Windows, Messages, Graphics,
 SysUtils, Classes, Controls, StdCtrls, forms, Dialogs;

type

 TCustomEdit22 = class(TCustomEdit)
 private
   FDropDownForm: TForm;
   procedure SetDropDownForm(const Value: TForm);
 protected
     
 public
   constructor Create(aOwner:TComponent); override;
   destructor Destroy; override;

   procedure DropDown;
   procedure CloseUp;
 published
   property DropDownForm: TForm read FDropDownForm write SetDropDownForm;
 end;

procedure Register;

implementation

procedure Register;
begin
 RegisterComponents("CustComp", [TCustomEdit22]);
end;

{ TCustomEdit22 }

procedure TCustomEdit22.CloseUp;
begin
   if Assigned(FDropDownForm) then
   FDropDownForm.Hide;
end;

constructor TCustomEdit22.Create(aOwner: TComponent);
begin
 inherited;
end;

destructor TCustomEdit22.Destroy;
begin
 if Assigned(DropDownForm)then DropDownForm.Free;
 inherited;
end;

procedure TCustomEdit22.DropDown;
var
 P: TPoint;
 Y: Integer;
begin
 P := Parent.ClientToScreen(Point(Left,Top));
 Y := P.Y + Height;
 if Y + DropDownForm.Height > Screen.Height then Y := P.Y - DropDownForm.Height;
 DropDownForm.top:=y;
 DropDownForm.left:=p.x;
 DropDownForm.Show;
end;

procedure TCustomEdit22.SetDropDownForm(const Value: TForm);
begin
 if Assigned(value)and (not Assigned(FDropDownForm))
 then begin
   FDropDownForm:=Value.CreateNew(self);
   FDropDownForm.Name:=name+"_ddf";
   FDropDownForm.Color:= clBtnFace;
 end;
end;

end


 
wisekaa ©   (2004-06-25 15:42) [3]


> procedure TCustomEdit22.SetDropDownForm(const Value: TForm);
> begin
>  if Assigned(value)and (not Assigned(FDropDownForm))
>  then begin
>    FDropDownForm:=Value.CreateNew(self);
>    FDropDownForm.Name:=name+"_ddf";
>    FDropDownForm.Color:= clBtnFace;
>  end;
> end;

Твоя ошибка в этом куске кода!


 
Юрий Зотов ©   (2004-06-25 17:42) [4]

> dm ©   (25.06.04 12:09) [2]


procedure TCustomEdit22.SetDropDownForm(const Value: TForm);
begin
 ...
 FDropDownForm := Value.CreateNew(self);


То есть, Вы вызываете конструктор через ссылку на ЭКЗЕМПЛЯР класса, а не на САМ класс. Такой вызов нового объекта не создает.

В свойстве нужно хранить КЛАСС формы, а не ссылку на ее экземпляр. И хранить этот класс можно в строковом виде. То есть, получится примерно следующее (все не имеющее прямого отношения к сабжу опущено):


type
TCustomEdit22 = class(TCustomEdit)
private
  FDropDownForm: TForm;
  function GetDropDownForm: string;
  procedure SetDropDownForm(const Value: string);
...
published
  property DropDownForm: string
    read GetDropDownForm write SetDropDownForm;
end;

function TCustomEdit22.GetDropDownForm: string;
begin
 if FDropDownForm = nil then
   Result := ""
 else
   Result := FDropDownForm.ClassName
end;

procedure TCustomEdit22.SetDropDownForm(const Value: string);
var
 AClass: TClass;
begin
 if not SameText(DropDownForm, Value) then
   if Value <> "" then
   begin
     AClass := FindClass(Value);
     if not AClass.InheritsFrom(TForm) then
       raise Exception.Create(...);
     if FDropDownForm <> nil then
       FDropDownForm.Free;
     FDropDownForm := TFormClass(AClass).Create(Self)
   end
   else
     if FDropDownForm <> nil then
       FreeAndNil(FDropDownForm)
end;


Естественно, все классы возможных DropDown-форм должны быть зарегистрированы (cм. RegisterClasses) и должны находиться в design-time пакете, а для свойства DropDownForm потребуется собственный редактор (чтобы отображать имена этих классов в выпадающем списке).


 
Petr V. Abramov ©   (2004-06-25 17:52) [5]

> должны находиться в design-time пакете,
 может, имелось в виду в run-time пакете???


 
Anatoly Podgoretsky ©   (2004-06-25 17:58) [6]

Petr V. Abramov ©   (25.06.04 17:52) [5]
в run-time инспектор объектов отсутвует


 
wisekaa ©   (2004-06-25 19:02) [7]


> Юрий Зотов ©

А вообще в принципе это возможно, из общения в чате я понял, что человек хочет сделать компонет Edit+Button(or DropDown) причем на действие повесить вывод, сделанной произвольной формы в дизайнере, а не заранее подготовленных в копоненте?


 
Колбасьев   (2004-06-25 21:36) [8]

Попутный вопрос к AlexGreG (и остальным):
Когда Ваша форма (DropDownForm) открывается, то загоровок родительского окна сереет (т.е. окно становиться неактивным)? У меня - да (сделал компонент - PopUpWindow - окно всплавает по команде PopUp обычно прописанной в OnClick кнопок и т.п.) что выглядит непривычно (сильно непривычно), так как при открытии выпадающей части ComboBox, меню и т.п. такого не наблюдается.

И как от этого избавиться? (В справке вообще сказано, что нельзя установить (и это так) стиль POPUP и CHILD одновременно)


 
Petr V. Abramov ©   (2004-06-26 15:30) [9]

> Anatoly Podgoretsky ©   (25.06.04 17:58) [6]
> в run-time инспектор объектов отсутвует
 Ну и что, да зачем он вообще нужен? :)

 Получится, что за приложением юзеру придется тащить design-time пакет, что не есть хорошо.
 Design-time пакет может (и должен) содержать только редакторы св-в и все, что с ними связано, и в requies содержать runtime пакет.
 Только не говори, что ты все это не знал :)


 
GrayFace ©   (2004-06-27 08:04) [10]

А зачем FDropDownForm := Value.CreateNew(self);, ссылкф на класс? Ведь отделить так созданную форму от изначальной все-равно не получится, ведь var"ы принадлежат классу.
В SetDropDownForm еще в вашем случае надо удалять старый объект.
Колбасьев
>И как от этого избавиться? (В справке вообще сказано, что нельзя установить (и это так) стиль POPUP и CHILD одновременно)
А зачем тебе WS_POPUP?... Че он вообще дает?


 
Колбасьев ©   (2004-06-27 13:06) [11]

>>   FDropDownForm:=Value.CreateNew(self);
Чушь какая-то! И дело даже не в Value. Когда устанавливается новая форма, надо просто хранить ссылку на нее, а не создавать новую.
То есть что получается: есть у меня две формы. На одной компонент. Беру я и выбираю в свойстве вторую форму, и тогда создается третья, пустая, в памяти... Зачем????

Если я что-то пропустил или не понял... объясните :-\]]

>>А зачем тебе WS_POPUP?... Че он вообще дает?
Процедурой (ф-ей) SetWindowLong с этим параметром устанавливаю стиль окна. Кажеться, зачем надо так делать, если есть св-во BorderStyle. Например, вот зачем: когда ставишь bsNone и Caption := "" и Height := CleintHeight, то у формы нет краев и заголовка. А если установить стиль WS_BORDER (и др. аналогичные значения, просто эффект будет немного другой), то не будит заголовка, но будет рамка вокруг окна. Причем она не считается клиентской областью, что может дать удобство, например при размещении компонентов на ней (они не "налезут" на нарисованную вручную рамку (если вы рисовали ее)).

Но, вы наверное это уже знаете ;-)


 
dm ©   (2004-06-28 12:04) [12]

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

Недостаток в том, что я не могу устанавливать свойства этой формы, как, например, при настрйке грида я могу устанавливать свойства датасета, а при настройке датасета - могу настраивать подключение к БД.

Вопрос в том, что необходимо сделать для решения этой задачи?
Ещё есть идея с фреймом поэкспериментировать. Но пока не добрался до него.


 
RagE ©   (2004-07-02 16:56) [13]

Народ обьясните мне почему нельзя сделать так
FDropDownForm := Value;



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

Форум: "Компоненты";
Текущий архив: 2005.07.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.049 c
1-1118610420
Kolan
2005-06-13 01:07
2005.07.11
Функция в потоке работает неверно. Помогите разобратся.


5-1089704943
doma
2004-07-13 11:49
2005.07.11
Сужение списка property в наследнике


9-1111903736
Yegorchic
2005-03-27 10:08
2005.07.11
Список обьекты в GLScene


14-1117999625
vecna
2005-06-05 23:27
2005.07.11
Где остановиться в Питере.


1-1118819243
dmitry501
2005-06-15 11:07
2005.07.11
Произвольное изменение региональных настроек





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский