Как сгенерировать событие?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Как сгенерировать событие?

Сообщение Сквозняк » 14.11.2017 05:19:35

Необходимо в обработчике события Button1OnKeyDown создать событие клика по клавише энтер чтобы _штатным_ способом сработало событие Button1OnClick и в его обработчике сработала процедура CLOSE;

Такая запутанная система нужна из-за того, что если я в дочерней форме вызываю CLOSE; не из того места, то ломается стек, происходит ошибка 210 и т.д. Закрытие дочерней формы требует чтобы человек явно кликнул мышкой или по энтеру, нажал на крестик в заголовке формы, а если запрограммировать то же самое по нажатию эскейпа, то получите баг.

Добавлено спустя 43 минуты 18 секунд:
Обнаружил как обойти проблему. Вот такой обработчик стек не ломает:
Код: Выделить всё
procedure TForm9.Button1KeyPress(Sender: TObject; var Key: char);
begin
IF ORD(KEY)=27 THEN CLOSE;
end;

А в procedure TForm9.Button1KeyDown практически тоже самое - ломает.
Сквозняк
энтузиаст
 
Сообщения: 579
Зарегистрирован: 29.06.2006 22:08:32

Re: Как сгенерировать событие?

Сообщение Лекс Айрин » 14.11.2017 09:14:27

Сквозняк, а чем не устраивает стандартный SendMessage?
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4167
Зарегистрирован: 19.02.2013 16:54:51

Re: Как сгенерировать событие?

Сообщение zub » 14.11.2017 09:16:05

>>Такая запутанная система нужна из-за того
Токая странная система абсолютно ненужна.
Кучу раз на форуме говорилось что нельзя убивать контрол из обработчика его события. это нужно делать извне этого контрола.

>>то ломается стек
ломается не стек, происходит вызов метода уже уничтоженного класса
zub
долгожитель
 
Сообщения: 2275
Зарегистрирован: 14.11.2005 23:51:26

Re: Как сгенерировать событие?

Сообщение Сквозняк » 14.11.2017 10:47:40

Лекс Айрин писал(а):Сквозняк, а чем не устраивает стандартный SendMessage?

Так не знал про него. Сейчас в первый раз услышал.
Сквозняк
энтузиаст
 
Сообщения: 579
Зарегистрирован: 29.06.2006 22:08:32

Re: Как сгенерировать событие?

Сообщение vada » 14.11.2017 11:31:16

Здрасти! Основополагающая штука в объектно-ориентированных системах! SmallTalk только на нем и живет!
Аватара пользователя
vada
энтузиаст
 
Сообщения: 650
Зарегистрирован: 14.02.2006 13:43:17

Re: Как сгенерировать событие?

Сообщение Лекс Айрин » 14.11.2017 12:01:32

vada, не только в объектно, кстати, но и в процесс- и аспект- ориентированных... А то, что сейчас называют ООП, если уж на то пошло, скорее функциональное программирование, только усложненное.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4167
Зарегистрирован: 19.02.2013 16:54:51

Re: Как сгенерировать событие?

Сообщение Сквозняк » 14.11.2017 15:54:22

vada писал(а):Здрасти! Основополагающая штука в объектно-ориентированных системах! SmallTalk только на нем и живет!

Объясни это тем "умникам" что пишут книжки про программирование на паскале/лазарусе: вот вам форма, на которую набросаны элементы, как их прицеплять вам не расскажем, про паскаль всё, а теперь переходим к выводу на форму формул, про формулы вы будете читать до конца книжки! Теперь ещё про малый разговор гуглить...
Сквозняк
энтузиаст
 
Сообщения: 579
Зарегистрирован: 29.06.2006 22:08:32

Re: Как сгенерировать событие?

Сообщение zub » 14.11.2017 19:29:57

>> Вот такой обработчик стек не ломает
>>А в procedure TForm9.Button1KeyDown практически тоже самое - ломает.
А потом начнется - на этом виджесете первый ломает, второй нет... а в следующем релизе все начнет ломаться... или в этомже релизе но с другим компилятором
Просто не делай так, а не ищи объяснение случайным фактам
zub
долгожитель
 
Сообщения: 2275
Зарегистрирован: 14.11.2005 23:51:26

Re: Как сгенерировать событие?

Сообщение pupsik » 14.11.2017 20:03:08

Глупый, нубский вопрос:
KeyPress и KeyDown - это идентичные процедуры???
Тогда и KeyUp сюда допишем. А чё? :mrgreen:

Добавлено спустя 3 минуты 11 секунд:
а чем не устраивает стандартный SendMessage?
а он стандартный? Прям таки на всех системах?

Остальное вообще странный флуд.
pupsik
энтузиаст
 
Сообщения: 1014
Зарегистрирован: 20.08.2014 16:20:13

Re: Как сгенерировать событие?

Сообщение Лекс Айрин » 14.11.2017 21:33:40

pupsik писал(а):а он стандартный? Прям таки на всех системах?


Во всех, где есть окна, ибо его реализация в Лазаре:

Код: Выделить всё
function SendMessage(HandleWnd: HWND; Msg: Cardinal; WParam: WParam; LParam: LParam): LResult;
begin
  Result := WidgetSet.SendMessage(HandleWnd, Msg, WParam, LParam);
end;

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

Сквозняк писал(а):Необходимо в обработчике события Button1OnKeyDown создать событие клика по клавише энтер чтобы _штатным_ способом сработало событие Button1OnClick и в его обработчике сработала процедура CLOSE;


Кстати, что-то я притормозил... у меня прекрасно закрывается и без геморроя из обработчика события:

Код: Выделить всё
procedure TFTune.ButtonOKClick(Sender: TObject);
begin
     // настройка шрифта
    .....
     FTune.Hide;
     Edit.FEditors.Refresh;
end;   

procedure TFTune.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
...
  CloseAction:=caHide;// caFree;, если стоит выкинуть из памяти.
end;   


Есть небольшие проблемы при использовании Анхордокинга, но там немного другая реализация работы с окнами. Причем, вполне, как я понимаю, этот вопрос решаем.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4167
Зарегистрирован: 19.02.2013 16:54:51

Re: Как сгенерировать событие?

Сообщение Сквозняк » 14.11.2017 23:33:03

zub писал(а):А потом начнется - на этом виджесете первый ломает, второй нет... а в следующем релизе все начнет ломаться... или в этомже релизе но с другим компиляторомПросто не делай так, а не ищи объяснение случайным фактам

Именно так и есть - рабочий хак для программирования того, о чём не читал :D А правильно, это так понимаю, послать сообщение на главную форму через глобальную переменную, где её отловит Timer и сделает переменной через которую запускали окно Close, а потом Free, чтобы память не текла. Конечно, в консоли будет много ругани, но потребление памяти при включениях/выключениях окна стабилизируется на какой-то цифре, а не ползёт постоянно вверх. Вроде рабочий вариант. Тогда, что там рядом с Timer за "хрен с горы" IdleTimer? Вроде похожий компонент, но свойства у него непонятные - применишь его и сработает неизвестно когда как не так как ожидалось.
Сквозняк
энтузиаст
 
Сообщения: 579
Зарегистрирован: 29.06.2006 22:08:32

Re: Как сгенерировать событие?

Сообщение zub » 15.11.2017 00:54:05

Сквозняк
>>рабочий хак для
для вставки именно в то отверстие и причинения боли. фиксед.

Рассллабся и не занимайся херней. вбей в гугел Application.QueueAsyncCall - это самое элементарное решение твоей проблемы.
zub
долгожитель
 
Сообщения: 2275
Зарегистрирован: 14.11.2005 23:51:26

Re: Как сгенерировать событие?

Сообщение Сквозняк » 15.11.2017 03:00:33

Твой Application.QueueAsyncCall расслабиться, если заняться его тестированием и встройкой в приложение, точно не даст. Та дочерняя форма не просто выключается из кучи мест, но и память отжирает при старте, а значит её почистить надо снаружи 1 раз а не 2, а также шлёт сообщения родительской форме. На всё это потребуется куча обработчиков, которые ещё надо синхронизировать, а будильник-дурильник справляется со всем один, только в его обработчик надо вписать
Код: Выделить всё
begin
IF timer1zanato=1 THEN GOTO 100;
timer1zanato:=1;

...........................................

timer1zanato:=0;
100:
end;

чтобы их не запустилось 100500 штук параллельно. А похожее иногда и происходит, т.к. в обработчике присутствует SHOWMESSAGE Пока на окошко с сообщением кликнешь, запустится мнооого таких окошек и привет, глуши приложение. Но goto здесь спасает. Теоретически может и не спасти, но для этого нужно чтобы выполнение кода зависло или затормозило между двумя строками. То есть простой таймер освоился почти сходу, а твой асинхронный класс ещё кучу времени выжрет. Где-бы про не простой будильник на русском почитать, может он и без goto не плодиться умеет.
Сквозняк
энтузиаст
 
Сообщения: 579
Зарегистрирован: 29.06.2006 22:08:32

Re: Как сгенерировать событие?

Сообщение sign » 15.11.2017 07:04:34

:shock: :shock: :shock:
Зачем!!! Зачем GoTo?

Код: Выделить всё
var TimersNotStart: Boolean = True;
procedure LaLaLa;
begin
  if TimerNotStart then begin
    TimerNotStart := False;
...
    TimerNotTsart := True;
  end;
end;
sign
энтузиаст
 
Сообщения: 883
Зарегистрирован: 30.08.2009 09:20:53

Re: Как сгенерировать событие?

Сообщение Сквозняк » 15.11.2017 07:51:50

sign писал(а):Зачем!!! Зачем GoTo?

Затем что break не вызывает ощущения надёжности и комфорта, каждый раз когда его в своём коде видишь, подсознательно мучительно пересчитываешь, куда оно выплюнет выполнение программы. А goto красиво и изящно посылает хоть за три экрана на цифру, которую с процедурой не спутаешь, а этих вложенных блоков begin end на этих трёх экранах тоже, столько может быть... Особенно весело, если имена переменных со смыслом, то есть длинные, тогда эти begin end закопаны в горизонтально кустистом коде.

Вот нашли до чего докопаться в то время когда космические корабли бороздят Большой театр :D В это же самое время ширину менюшки неоткуда взять, и неизвестно какой ширины делать форму - поместится на ней правый край меню, или нет - это большая загадка.
Сквозняк
энтузиаст
 
Сообщения: 579
Зарегистрирован: 29.06.2006 22:08:32

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot], Yandex [Bot] и гости: 10

Рейтинг@Mail.ru