Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (до версии 2009) - часть 5

Модерирует : ShIvADeSt

ShIvADeSt (19-05-2010 05:14): Продолжаем тут http://forum.ru-board.com/topic.cgi?forum=33&topic=11215  Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

   

ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Продолжение темы Вопросы по Delphi (до версии 2009) - часть 4

Познаем сами, помогаем другим...
Обсуждаем вопросы, не связанные с юникоидными версиями Delphi - для этого есть соответствующая тема (см. ссылки ниже).

Правила топика:
    Прежде чем спрашивать:
  1. Желательно изучить вопрос, попытаться найти ответ в прилагаемых мануалах, хелпах и анализируя исходники.
  2. Выполнить поиск по топику (открыть "Версия для печати" и поискать ответ там).
  3. Применить фильтр по разделу "Прикладное программирование". Ответы на многие старые вопросы могли быть даны в отдельных темах.
  4. Продумайте вопрос. На поверхностные вопросы вы получите поверхностные ответы, или вообще ответов не получите.
  5. Желательно указывать версии используемого компилятора и операционной системы.
    Прежде чем отвечать:
  1. Если не можете помочь, не мешайте.
  2. Если уж вы отвечаете на вопрос, давайте ответ по сути.
  3. Если вы не уверены, так и говорите! Ошибочный, но авторитетно звучащий ответ хуже, чем отсутствие ответа.
  4. Задавайте дополнительные вопросы, чтобы получить больше информации.
  • Отсутствие ответа не равносильно игнорированию - иногда участники форума просто не знают ответ. Повторная посылка вопроса не приветствуется. Посты типа "неужели никто не знает ответа..." или "может мне все-таки кто-нибудь ответит" недопустимы.  
  • Все большие куски кода (более 5 строк) оформляем в тег [morе] дабы уменьшить размер поста. FAQ по тегу [morе].

  • Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:09 28-06-2009 | Исправлено: psa1974, 12:00 02-02-2010
    JDEE

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    NOwlar

    Цитата:
    По-моему, это не будет работать.  

     
    Еще как будет.
    Это вариант если нужен клик по самой форме тоже. В вашем варианте клик по форме работать не будет.

    Всего записей: 59 | Зарегистр. 30-11-2004 | Отправлено: 19:10 23-11-2009
    mdid

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    scroollocker

    Цитата:
     
    Здравствуйте, подскжите пожалуйста, как можно Замутить перемещение окошка программы без панельки (на которой, еще есть кнопочки:закрыть, минимизировать.., за которую обычно и перемещают окошко)  
    Знаю функцию SetWindowPos, но как узнать, на сколько пользователь переташил окно?
     

    ложите допустим на форму TImage и в обработке OnMouseDown

    Код:
     
      ReleaseCapture;
      Perform(WM_SYSCOMMAND, $F012, 0);
     
     
    по моему все..еси ничего не забыл
     
    psa1974
    пасиб...ща буду ковырять

    Всего записей: 1298 | Зарегистр. 13-02-2006 | Отправлено: 19:40 23-11-2009 | Исправлено: mdid, 19:58 23-11-2009
    scroollocker

    Newbie
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    mdid
    Спасиба!

    Всего записей: 5 | Зарегистр. 10-10-2007 | Отправлено: 09:32 24-11-2009
    mdid

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    блин все равно не выходит

    Код:
     
        if folder='-1' then  
        begin  
          if Assigned(TPopupMenu(Sender).Items[4].OnClick) then  
            ShowMessage('Таки обработчик назначен ');  
          TPopupMenu(Sender).Items[4].Insert(i,mi);  
        end;  
        else  
          TMenuItem(Sender).Insert(i,mi);
     

    это не срабатывает
    а если делать

    Код:
     
    //    if folder<>'-1' then
        mi.OnClick:=ReplaceItem;
     

    то не срабатывают вообще клики по объектам

    Всего записей: 1298 | Зарегистр. 13-02-2006 | Отправлено: 10:32 25-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mdid
    Я честно говоря не до конца просёк твой алгоритм - не понятно от чего зависит значение folder и на что оно влияет, и сейчас приглядевшись, заметил один нюанс. Давай разбираться...
    1. Из твоего кода

    Код:
     if folder='-1' then  
          TPopupMenu(Sender).Items[4].Insert(i,mi)  
        else  
          TMenuItem(Sender).Insert(i,mi);
     

    следует что:  

    • при folder='-1' обработчик вызывается для события OnPopup объекта PopupMenu, поскольку в этом случае Sender является объектом типа TPopupMenu и приведение типа TPopupMenu(Sender) верно. При этом ты создаешь пункты субменю для пункта меню с индексом 4, созданному элементу ты назначаешь обработчик ReplaceItem - тут всё пучком.
       
    • при folder<>'-1' обработчик вызывается СОВСЕМ НЕ для события OnPopup объекта PopupMenu! Об этом говорит приведение TMenuItem(Sender) - если бы это был обработчик OnPopup, Sender являлся бы объектом типа TPopupMenu и приведение типа TMenuItem(Sender) вызвало бы эксцепшен.Но у тебя экцепшена не происходит, стало быть в этом случае обработчик вызывается не для события OnPopup объекта PopupMenu, а, вероятнее всего для события OnClick ПУНКТОВ твоего PopupMenu (элементов TMenuItem).
       
    • при folder<>'-1' ты просто опечатался и вместо TPopupMenu(Sender) написал TMenuItem(Sender). Поскольку эксцепшена не происходит а также принимая во внимание твое утверждение: что если назначать mi.OnClick:=ReplaceItem; только  при folder<>'-1', то не срабатывают вообще клики по объектам, то это означает, что ситуация folder<>'-1' тупо не возникает никогда вообще.

    Так что твой алгоритм не совсем прозрачен Тут у тебя присутствует "два в уме" Если пришлешь форму, будет проще проанализировать... А пока вот пример на базе твоего случая, в котором все работает так, как требуется: Ссылка
     

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 13:22 25-11-2009 | Исправлено: psa1974, 13:24 25-11-2009
    mdid

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    пасиб...та прислать не могу ибо это толстый проект с выбором элементов справочника и групп из удаленной БД...пасиб за пример
     
    блин то ли лыжи не едут то ли...в общем проблема в том что  ни add ни insert не возвращают индекс созданного элемента посему при добавлении одного уровня ваш пример работает отлично

    Код:
     
    var
      MI  : TMenuItem;
      i   : Integer;
    begin
      TPopupMenu(Sender).Items[4].Clear;
      for I:=0 to 3 do
      begin
        mi:=TMenuItem.Create(self);
        mi.Caption:= IntToStr(i);
        mi.Tag:=i;
        mi.OnClick:=ReplaceItem;
        TPopupMenu(Sender).Items[4].Insert(i,mi);
      end;
     

    а вот что делать если надо в созданном пункте меню еще подпункт создать?  
    TPopupMenu(Sender).Items.IndexOf(mi) возвращает -1
    а после создания меню
    showmess(PopupMenu1.Items.Items[6].Caption); выдает ексепшн..тоесть индексы не последовательны..иль хз..

    Всего записей: 1298 | Зарегистр. 13-02-2006 | Отправлено: 13:34 25-11-2009 | Исправлено: mdid, 14:10 25-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mdid
    Вот оно что! Оказывается ты делаешь пункт меню, для него подпункт, для этого подпункта еще подпункт, и т.д. Вот де собака порылась!
    Поехали дальше
    Во-первых для каждого подменю индексы начинаются с нуля.
    Во-вторых, пункт подменю принадлежит тому элементу меню/подменю, в куда он вставлен/добавлен и не принадлежит другим пунктам меню.
    Следствие:

    Цитата:
    TPopupMenu(Sender).Items.IndexOf(mi)
    возвращает индекс пункта в ОСНОВНОМ меню. Если ты mi вставлял не в корень меню а в какой-то пункт, создавая тем самым подменю, то этот mi в самом меню будет отсутствовать. Но будет присутствовать в подменю...
    Бери пример, компильни и посмотри текст, выводимый в метке на форме... Test
    Обрати внимание, что перед созданием субменю второго уровня вложенности я у элемента, которому сопоставляю это субменю, удаляю обработчик...

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 16:31 25-11-2009 | Исправлено: psa1974, 16:34 25-11-2009
    mdid

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    почти оно..но проблема в том что подменю которое открывается тоже должно быть кликабельным...просто есть вариант что сама ОС делает клик при открытии подменю...хотя тут уже можно в первый пункт подменю вставить что то типа "Выбрать"..в общем спасибо..наверно это лучший вариант в данной ситуации

    Всего записей: 1298 | Зарегистр. 13-02-2006 | Отправлено: 16:57 25-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mdid

    Цитата:
    проблема в том что подменю которое открывается тоже должно быть кликабельным

    Не вопрос! Если как у меня в примере основные пункты меню созданы в режиме разработки, и им назначен обработчик, то можно его так написать:

    Цитата:
    procedure TForm3.N151Click(Sender: TObject);
    begin
      // этот обработчик прописан в инспекторе объектов для всех основных пунктов N111  N121  N131  N141  N151
      if (Sender is TMenuItem) then
        if (Sender as TMenuItem).Count = 0 then
          бла-бла-бла;
    end;
     

    Вместо N151Click можно прописать в инспекторе твой ReplaceItem.
     
    И, кстати, это очень даже НЕПЛОХАЯ мысль - такой обработчик можно назначать всем без разбора пунктам и подпунктам - и всё, что вместо бла-бла-бла, будет работать только для пунктов, не имеющих подпунктов!
     
    Если же и основные пункты меню создаются динамически, то поступаешь так же, как я в примере для второго субменю, т.е. считай что субменю первого уровня моего примера - это твое меню. Само собой, это только пример, будут нюансы, но все реализуемо

    Цитата:
    есть вариант что сама ОС делает клик при открытии подменю

    Неа, делать ОС больше нечего Опять же ссылаюсь на свой пример - у меня не происходит клика на подпунктах, у которых есть свои подпункты. Так что - не делает она ничего! Она делает только то, что ты ей расскажешь делать.  

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 17:35 25-11-2009 | Исправлено: psa1974, 17:41 25-11-2009
    Tualan



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Такой вот вопрос...
    Если во время выполнения кода конструктора объекта возникает исключительная ситуация (Exception) и выполнение кода прерывается, выделяется ли под объект память ?

    Всего записей: 88 | Зарегистр. 27-04-2005 | Отправлено: 12:04 26-11-2009
    grimoor

    Newbie
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Ошибка в конструкторе приводит к автоматическому вызову деструктора.

    Всего записей: 7 | Зарегистр. 25-11-2009 | Отправлено: 12:05 26-11-2009
    Tualan



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    А в деструкторе нужно проверять какие объекты создались, а какие нет?

    Всего записей: 88 | Зарегистр. 27-04-2005 | Отправлено: 12:08 26-11-2009
    data man



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    grimoor
    Tualan
    Для чата есть ПМ.  
    Это и про ваше обсуждение по компонентам.

    ----------
    Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
    Кекс. Антибиотики. Ламбада.

    Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 12:14 26-11-2009
    Tualan



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    data man
    Извините пожалуйста, я думал тема будет интересна не только мне

    Всего записей: 88 | Зарегистр. 27-04-2005 | Отправлено: 15:31 26-11-2009
    ShIvADeSt



    Moderator
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    data man

    Цитата:
    Для чата есть ПМ.  
    Это и про ваше обсуждение по компонентам.

    В данном случае Вы не правы тут у многих чат идет, главное чтобы в оффтоп и флуд не ушли.  
    Tualan
    grimoor
    продолжайте самообразовываться.

    ----------
    И создал Бог женщину... Существо получилось злобное, но забавное...

    Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 04:27 27-11-2009
    Kursist



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Есть собственный класс, объекты которого создаются динамически  
     
    TapButton=class(TapRegion)
       private
        FOnMouseUpEvent: TNotifyEvent;
        FOnMouseClickEvent: TNotifyEvent;
       ....
       public
       ....
        procedure MouseUp(X,Y:Integer);
        procedure MouseClick(X,Y:Integer);
        property OnMouseUp: TNotifyEvent read FOnMouseUpEvent write FOnMouseUpEvent;
        property OnMouseClick: TNotifyEvent read FOnMouseClickEvent write FOnMouseClickEvent;
    ....
     
    На форме, в событии OnClick есть такой код:
     if (TapList.Items(index) is TapButton) then
     (TapList.Items(index) as TapButton).MouseClick(mX,mY);
     
    в процедуре TapButton.MouseClick(X, Y: Integer);
    естественно, есть такой код:
     if assigned(FOnMouseClickEvent) then FOnMouseClickEvent(self);
     
    Объекты типа TapButton создаются по мере надобности из файла.
    В течение работы программы объекты будут многократно удаляться и загружаться=создаваться новые.
     
    Подскажите, как правильнее присваивать процедуру типа TNotifyEvent?
    Например, такая процедура, в теле которой есть программный код:
     
    index:=TapList.Add; {создаем в списке объект класса TapButton}
     if (TapList.Items(index) is TapButton) then
     (TapList.Items(index) as TapButton).OnMouseClick:=...(тут - откуда взять процедуру для присваивания?);
     
    Спасибо.

    Всего записей: 137 | Зарегистр. 12-07-2004 | Отправлено: 10:21 27-11-2009
    ppkp

    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Kursist

    Цитата:
    (TapList.Items(index) as TapButton).OnMouseClick:=...(тут - откуда взять процедуру для присваивания?);  

     
    В разделе private объявляете
    procedure MyMouseClick(X,Y:Integer);
     
    В секции implementation пишите свой обработчик событий
    procedure MyForm.MyMouseClick(X,Y:Integer);
    begin
    ........
    end;
    И потом
    (TapList.Items(index) as TapButton).OnMouseClick:=MyMouseClick;

    Всего записей: 480 | Зарегистр. 13-04-2006 | Отправлено: 16:36 27-11-2009
    MrZeRo



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    удалено

    ----------
    ... не это главное ...

    Всего записей: 831 | Зарегистр. 30-01-2002 | Отправлено: 16:38 27-11-2009 | Исправлено: MrZeRo, 16:40 27-11-2009
    Kursist



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Спасибо за ответы.
     
    1. Только что решил проблему иным способом (если кому интересно):
     создал метод  
    function TapButton.MouseClick(X, Y: Integer):Boolean;
    Там проверяется был ли клик (координаты мыши) в области TRect объекта.
    А на форме пишу - если произошел клик - то сделать всё что хочу. И не надо использовать TNotifyEvent.
     
    2. На тему TNotifyEvent нашел инфу:
    "Обработчики событий нельзя сделать просто процедурами — они обязательно должны быть чьими-то методами.Но их можно "отдать" какому-либо другому объекту. Более того, для этих целей можно описать и создать специальный объект. Его единственное предназначение — быть носителем методов, которые затем делегируются другим объектам."
    http://delphi-masters.ru/one/11926.htm
     
     

    Всего записей: 137 | Зарегистр. 12-07-2004 | Отправлено: 17:46 27-11-2009
    data man



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Kursist

    Цитата:
    Обработчики событий нельзя сделать просто процедурами — они обязательно должны быть чьими-то методами

     
    Не совсем так. К примеру эта статья и её обсуждение  О назначении пользовательского TNotifyEvent

    ----------
    Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
    Кекс. Антибиотики. Ламбада.

    Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 17:57 27-11-2009
       

    Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (до версии 2009) - часть 5
    ShIvADeSt (19-05-2010 05:14): Продолжаем тут http://forum.ru-board.com/topic.cgi?forum=33&topic=11215


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2024

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru