Конференция "Компоненты" » Создание компонента. MDI приложение.
 
  • Decoding (24.07.08 14:50) [0]
    Добрый день.
    Заканчиваю компонент, который представляет собой некий аналог виндового TaskBar'а, для дочерних окон MDIForm. Есть ряд задач (3 штуки), с которыми пока немогу справиться...

    1) Мне необходимо, чтобы во время разработки приложения этот компонент можно было "бросить" только на форму со стилем  FormStyle = MDIForm. Понятно, что нужно чтото написать в методе Create этого компонента, но вот что?

    2) Вопрос примерно из той же серии, что и первый. Нужно, чтобы на форме мог быть только один подобный компонент. Каким способом этого можно добиться?

    3) Третья задача заключается в отслеживании изменения заголовка дочерней MDI формы в RunTime, для того, чтобы соответствующим образом изменить текст на кнопке, ассоциированной с данным окном. Во время загрузки приложения компонент устанавливает хук
    procedure TMDIPanel.Loaded;
    begin
      inherited;
      ...
      WndProcHook := SetWindowsHookEx( WH_CALLWNDPROC, @CallWndHook, 0, GetCurrentThreadID );
      ...
    end;


    Но проблемы в том, что при смене текста в заголовке дочерней MDI формы, хук не перехватывает сообщение WM_SETTEXT (возможно оно и не генерируется...). Так вот, вопрос в следующем, каким образом можно отловить смену текста в дочернем MDI окне, используя хук?

    Если у кого есть идеи, с удовольствием выслушаю... Всем спасибо.
  • Медвежонок Пятачок © (24.07.08 15:00) [1]
    Понятно, что нужно чтото написать в методе Create этого компонента, но вот что?

    проверку что оунер это то что тебе надо
  • Olegz77 © (24.07.08 15:32) [2]
    1), 2)

    constructor TMegaTaskBar.Create(aOwner: TComponent);
    var I: Integer;
    begin
     inherited Create(aOwner);
     if Owner is TForm then
     begin
       if (TForm(Owner).FormStyle <> fsMDIForm) then
         raise Exception.Create('Руки оторву!!!');
     for I := 0 to TForm(Owner).ComponentCount - 1 do
       if TForm(Owner).Components[I] is TMegaTaskBar then
         raise Exception.Create('Ноги выдерну!!!');
     end;
    end;

  • DimaBr © (24.07.08 16:11) [3]
    if Owner is TForm then


    1. предлагаю заменить на поиск вверх подобно GetParentForm
    3. Зачем вешать хук ? На изменения заголовка формы CM_TEXTCHANGED послать сообщени главной форме

  • Decoding (24.07.08 16:14) [4]
    to Медвежонок Пятачок, Olegz77

    подобные идеи у меня уже были, но они не катят... Olegz77, приведенный тобой код не работает в дизайнере. Я спокойно могу положить свою панель на любой другой компонент (например TPanel), и добавить их сколько угодно...

    несколько иная картина наблюдается при трассировке приложения во время запуска. Не каком бы компоненте не лежала моя панель, условие if Owner is TForm then всегда срабатывает (вообще не врубаюсь почему...)

    Может есть другие идеи? или у Вас есть готовые примеры, в которых это реализовано и 100% работает верно? если есть, поделитесь, скиньте на decoding@yandex.ru
  • Медвежонок Пятачок © (24.07.08 16:16) [5]
    Я спокойно могу положить свою панель на любой другой компонент (например TPanel), и добавить их сколько угодно...

    И чего?
    Оунером то все равно не панель будет
  • Decoding (24.07.08 16:24) [6]

    > if Owner is TForm then
    > 1. предлагаю заменить на поиск вверх подобно GetParentForm
    > 3. Зачем вешать хук ? На изменения заголовка формы CM_TEXTCHANGED
    > послать сообщени главной форме


    1. попробую... хотя есть предположение, что в дизайнере это работать тоже не будет

    2. в компоненте 3 хука, на оконную процедуру, мышь и клаву... они решают много задач, например отслеживание изменение активной формы, создание, сворачивание и восстановление форм, для того, чтобы "нажать" на панели нужную кнопку. И уж раз они есть, то хотелось бы и эту задачу решить с их помошью... Понимаешь, мне бы не хотелось возлагать эту задачу на разработчика (в противном случае можно сделать у компонента публичный метод для этих целей). Вся идея в том и заключается, чтобы возложить эту задачу на компонент, и чтобы разработчик в дальнейшем этим не замарачивался...
  • DimaBr © (24.07.08 16:26) [7]

    constructor TMegaTaskBar.Create(AOwner: TComponent);
    var C: TComponent;
    begin
     C := AOwner;
     while Assigned(C.Owner) do C := C.Owner;
     if C is TForm then begin
      if (TForm(C).FormStyle <> fsMDIForm) then raise Exception.Create('Руки оторву!!!');
    end;

  • Decoding (24.07.08 16:27) [8]

    > И чего?
    > Оунером то все равно не панель будет


    я же пояснил, в дизайнере этот код не работает вообще (а мне именно в дизайнере и надо), а в RunTime условие if Owner is TForm then непонятно почему срабатывает всегда, даже если компонент лежит не на форме, а на панели.
  • DimaBr © (24.07.08 16:28) [9]
    Странно возлагать на MDIPanel управление заголовком окна !!!
  • Медвежонок Пятачок © (24.07.08 16:28) [10]
    интересно как можно в дизайне умудриться сделать оунером не форму на которую кидают мегатаскбар
  • Медвежонок Пятачок © (24.07.08 16:29) [11]
    я же пояснил, в дизайнере этот код не работает вообще (а мне именно в дизайнере и надо),

    Это еще с каких щей он не работает в дизайне?
  • DimaBr © (24.07.08 16:31) [12]
    В конструкторе Owner = nil, поскольку компонент только создаётся. Вот тут и присваивается.

    procedure TComponent.Insert(AComponent: TComponent);
    begin
     if FComponents = nil then FComponents := TList.Create;
     FComponents.Add(AComponent);
     AComponent.FOwner := Self;
    end;



    Скорее всего автор имел ввиду AOwner
  • Медвежонок Пятачок © (24.07.08 16:32) [13]
    а в RunTime условие if Owner is TForm then непонятно почему срабатывает всегда, даже если компонент лежит не на форме, а на панели.

    Оунером и будет форма. Парентом будет панель.
    Ку?
  • Медвежонок Пятачок © (24.07.08 16:34) [14]
    В конструкторе Owner = nil, поскольку компонент только создаётся. Вот тут и присваивается.

    Абалдеть.
  • Медвежонок Пятачок © (24.07.08 16:34) [15]
    А в параметре конструктора тоже нил "потому что тока создается"?
    :)
  • Decoding (24.07.08 16:38) [16]

    > constructor TMegaTaskBar.Create(AOwner: TComponent);
    > var C: TComponent;
    > begin
    >  C := AOwner;
    >  while Assigned(C.Owner) do C := C.Owner;
    >  if C is TForm then begin
    >   if (TForm(C).FormStyle <> fsMDIForm) then raise Exception.
    > Create('Руки оторву!!!');
    > end;


    и что сделает этот код? он пройдет по всей цепочке, дойдя до самого ее верхнего уровня, найдет форму, и условие
    if C is TForm then

    обязательно сработает. мне же нужно, чтобы если я кидаю компонент например на панель, компонент не позволил бы мне этого сделать... Причем обращаю ваше внимание, это нужно делать именно в DesignTime.
  • Медвежонок Пятачок © (24.07.08 16:40) [17]
    Дядя! При чем здесь твоя панель?
    Оунером будет форма на которой лежит панель.
    И у формы есть знание мдичайлд ли она.
    И список контролов и их типы у нее есть.
  • Медвежонок Пятачок © (24.07.08 16:44) [18]
    мне же нужно, чтобы если я кидаю компонент например на панель, компонент не позволил бы мне этого сделать...

    Установку парента лови. А вообще лучше подумай от кого наследоваться чтобы на панель не попасть автоматом
  • DimaBr © (24.07.08 16:45) [19]
    Вы сами себе противоречите

    > 1) Мне необходимо, чтобы во время разработки приложения этот компонент можно было "бросить" только на форму со стилем  FormStyle = MDIForm.



    >  мне же нужно, чтобы если я кидаю компонент например на панель, компонент не позволил бы мне этого сделать
 
Конференция "Компоненты" » Создание компонента. MDI приложение.
Есть новые Нет новых   [134464   +62][b:0][p:0.002]