Форум программистов, компьютерный форум, киберфорум
PascalABC.NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
7 / 7 / 0
Регистрация: 03.10.2014
Сообщений: 313

Как программно вызвать событие Windows.Forms ?

15.04.2020, 15:05. Показов 3310. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Прошу помощи.

На форме есть ползунок trackBar1 с предустановленными значениями (в Unit1.Form1.inc):

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
        // trackBar1
        // 
        self.trackBar1.AutoSize := false;
        self.trackBar1.LargeChange := 1;
        self.trackBar1.Location := new System.Drawing.Point(112, 201);
        self.trackBar1.Maximum := 0;
        self.trackBar1.Minimum := -1;
        self.trackBar1.Name := 'trackBar1';
        self.trackBar1.Orientation := System.Windows.Forms.Orientation.Vertical;
        self.trackBar1.Size := new System.Drawing.Size(26, 53);
        self.trackBar1.TabIndex := 60;
        self.trackBar1.Value := -1;
        self.trackBar1.Scroll += trackBar1_Scroll;
Есть событие в Unit1.pas (проще говоря, пользуюсь встроенным в оболочку редактором форм):

Pascal
1
2
3
4
5
6
7
procedure Form1.trackBar1_Scroll(sender: Object; e: EventArgs);
begin
  EN_DIM := abs(trackBar1.Value); // Из-за особенностей элемента управления
  ConsoleTB.AppendText('EN DIM = ' + EN_DIM.ToString + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write((4000 + EN_DIM).ToString);
end;
Как это событие вызвать программно?
Нужно при загрузке формы (Form1.Form1_Load) передавать в COM значения нескольких её элементов: полей ввода, ползунка и т.д. - их значения пересчитываются в процедурах событий, отдельные процедуры очень бы не хотелось писать, теряется читаемость кода.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.04.2020, 15:05
Ответы с готовыми решениями:

Как в Windows Forms вызвать свое событие?
Никак не могу понять, как вызывать собственное событие (именно свои, а не стандартные). Вот, например, хочу создать событие, наведения...

Как программно вызвать событие Click?
Если имя контрола известно на момент написания кода - то без проблем: Call Check1_Click (к примеру). А если не известно? Например:...

Как программно вызвать событие формы Paint?
Ситуация: при завершении перетаскивания текстбокса необходимо вызвать событие Paint, чтобы чертреж перерисовал линии под текстбокс. Как...

16
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
15.04.2020, 16:06
Цитата Сообщение от denismix Посмотреть сообщение
Из-за особенностей элемента управления
Это костыль. Если .Value может быть отрицательным "из-за особенностей элемента управления" - ожидается что вы это значение как то по-особому обработаете, а не тупо заткнёте ошибку.

Цитата Сообщение от denismix Посмотреть сообщение
'EN DIM = ' + EN_DIM.ToString + NewLine
Сложения >2 строк это медленно. Используйте или Concat, или форматную строку:
Pascal
1
$'EN DIM = {EN_DIM}{NewLine}'
---

Теперь к главному вопросу:
Цитата Сообщение от denismix Посмотреть сообщение
Как это событие вызвать программно?
Лучший вариант - это таки делать отдельные подпрограммы. Если у вас это убивает читабельность - вы как то не так пишете. Наверное, вы даже не знаете про короткую запись подпрограмм:
Pascal
1
2
3
4
5
6
7
procedure ОбщийКод;
begin
  //ToDo
end;
 
procedure Form1.trackBar1_Scroll(sender: Object; e: EventArgs) := ОбщийКод;
procedure Form1.trackBar2_Scroll(sender: Object; e: EventArgs) := ОбщийКод;
А событие должно вызываться только когда что то происходит. К примеру событие Scroll должно вызываться только при прокрутке мышки и только для определённого элемента управления.
Иначе вы будете плодить у себя баги + код, в котором их сложно отлавливать.

Ну и, раз речь идёт про пересчёт каких то значений - вам ничего не мешает написать свои события.
1
7 / 7 / 0
Регистрация: 03.10.2014
Сообщений: 313
15.04.2020, 16:35  [ТС]
Цитата Сообщение от Sun Serega Посмотреть сообщение
Это костыль. Если .Value может быть отрицательным "из-за особенностей элемента управления"
Мне просто нужно, чтобы у ползунка "1" была внизу, а "0" наверху - так нагляднее в интерфейсе.
Мог конечно преобразовать 0 в 1 и 1 в 0, но раз с -1 работает, то почему бы не использовать.
Про то, что trackBar1 не может принимать отрицательные значения, никогда не слышал - спасибо, учту.

Цитата Сообщение от Sun Serega Посмотреть сообщение
Сложения >2 строк это медленно. Используйте или Concat
Опять же учту, но в данном коде это совершенно не принципиально - вывод в COM само по себе "медленное" действие, тут точно скорость не требуется.

Теперь к главному:
Цитата Сообщение от Sun Serega Посмотреть сообщение
А событие должно вызываться только когда что то происходит.
Windows.Form официально позволяют вызывать события программно, это точно нигде не запрещено, а мне так удобнее.
Я несомненно приму к сведению ваш совет по поводу возможной нестабильной работы, но все же мне как минимум для общего развития, очень бы хотелось увидеть Паскалевский аналог Си-шного:
C#
1
this.trackBar1.Scroll += new System.EventHandler(this.trackBar1_Scroll);
или я неверно понял, и этот код только сопоставляет методу конкретную процедуру?

И потом, для кнопок же вполне себе существует .Click - и сроду не глючило...
0
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
16.04.2020, 01:52
Цитата Сообщение от denismix Посмотреть сообщение
Мне просто нужно, чтобы у ползунка "1" была внизу, а "0" наверху
Ну тогда надо -Value а не Abs(Value), нет?

Цитата Сообщение от denismix Посмотреть сообщение
Про то, что trackBar1 не может принимать отрицательные значения
Я такого не говорил. Я сам не знаю может ли.

Цитата Сообщение от denismix Посмотреть сообщение
Windows.Form официально позволяют вызывать события программно
Вы про методы вроде .OnScroll? Это должно использоваться только ради расширения функционала, когда нет доступа к коду, описывающему подпрограмму-обработчик события.

Цитата Сообщение от denismix Посмотреть сообщение
очень бы хотелось увидеть Паскалевский аналог Си-шного:
Pascal
1
self.trackBar1.Scroll += System.EventHandler(self.trackBar1_Scroll);
А вообще:
Pascal
1
self.trackBar1.Scroll += self.trackBar1_Scroll;
А если ещё и по-современному - тут и отдельная подпрограмма не нужна:
Pascal
1
2
3
4
self.trackBar1.Scroll += (o,e)->
being
  //ToDo тут код обработчика
end;
Тут лямбды как никогда кстати, потому что не надо засорять пространство имён одноразовыми подпрограммами.

Вот только вам это всё не надо, потому что редактор сам генерирует строчку с self.trackBar1.Scroll +=.
Посмотрите на последнюю строчку самого первого кода что вы сами скинули.

Добавлено через 3 минуты
Цитата Сообщение от denismix Посмотреть сообщение
Windows.Form официально позволяют вызывать события программно
P.S. Вы случаем не называете добавление обработчика - вызовом?
Вызов это вызов, в случае событий - вызов всех подпрограмм-обработчиков.
А добавление обработчика это, в крайнем случае, вызов аддера события (или только System.Delegate.Combine если аддера нет).
0
7 / 7 / 0
Регистрация: 03.10.2014
Сообщений: 313
16.04.2020, 15:50  [ТС]
Цитата Сообщение от Sun Serega Посмотреть сообщение
Ну тогда надо -Value а не Abs(Value), нет?
Просто Abs(Value),первое, что пришло в голову =) конечно проще и правильнее -Value
Мне показалось, что про "костыль" вы именно в ключе "так не положено и может привести к глюками" говорили, сори, не понял вашу мысль, уже разобрался.

Цитата Сообщение от Sun Serega Посмотреть сообщение
Pascal
1
self.trackBar1.Scroll += self.trackBar1_Scroll;
Я как раз думал, что аналог на Си вызывает событие, а не добавляет его обработчик - когда сам пробовал написать как в этом вашем примере, событие начинало отрабатывать по два раза =) - может кому пригодится, кстати - но я то думал, что просто неправильно перетранслировал код Си

Цитата Сообщение от Sun Serega Посмотреть сообщение
self.trackBar1.Scroll += (o,e)->
Буду вам очень признателен, если вы опишите подробно, что значит эта "конструкция" в частности оператор "->"
Так же не совсем понятно, что это за параметры (o,e) и
когда требуется использовать self. ?
В хелпе слишком кратко, а в форумах очень не внятно и примеры не пойми о чем.



======================================== =====
И всё же вернувшись к основному вопросу =)

Есть ли возможность в Паскале именно программно вызывать событие trackBar1.Scroll по аналогии с простейшим и часто употребляемым в коде (даже в официальных примерах используется) button1.Click ?
Ведь по сути, событие это обычная процедура, по семантике отличающаяся только требованием указать в параметрах специфические данные.
Вернувшись к button1.Click - это же просто вызов события как процедуры? Или именно .Click описан в объектной модели и библиотеках как то иначе, чем другие события и позволяет себя вызывать программно без указания параметров?

Очень жду ответ именно на этот вопрос!!! Уж прошу прощения за настойчивость.
======================================== =====



Добавлено через 6 минут
Цитата Сообщение от Sun Serega Посмотреть сообщение
P.S. Вы случаем не называете добавление обработчика - вызовом?
Да, так и получилось - но я не со зла =)) думал, что это именно вызов события - в Хелпе от Майкософт это "не разжевано" к сожалению, а по структуре кода в примерах на C# с первого раза не разобрался...
0
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
17.04.2020, 06:09
Цитата Сообщение от denismix Посмотреть сообщение
в ключе "так не положено и может привести к глюками"
Ну так то да. Костыли только тем и плохи, что когда мусорный код накапливается - сами собой начинают появлятся неожиданные фичи)

Цитата Сообщение от denismix Посмотреть сообщение
Я как раз думал, что аналог на Си вызывает событие, а не добавляет его обработчик
1. Наоборот. В C# как раз добавляет обработчик. Ещё раз, вызов это self.trackBar1.Scroll(...) (только вам не даст так вызвать, потому что это неправильно), так же как с любой подпрограммой. += это по определению добавление чего то. Вообще этот оператор изначально для чисел придуман:
Pascal
1
2
3
var x := 3;
x += 5;
// тут x=8
Но так же работает для добавления элемента в список, добавления обработчика к событию и т.п.

2. C,C++ и C# - совершенно разные языки, не путайте. C++ это оч продвинутая надстройка над C. А C# вообще из другой семьи. Он больше на джаву похоже чем на C/C++.
Правда есть ещё гомункул C++CLI, который сразу и C++ и C#. Хотя он конечно очень полезен в своей области применения. Ну, его я упомянул потому, что если будете путать C и C# - в итоге ещё больше запутаетесь наткнувшись на примеры C++CLI вместо C#.

Цитата Сообщение от denismix Посмотреть сообщение
Буду вам очень признателен, если вы опишите подробно, что значит эта "конструкция" в частности оператор "->"
Зайдите на главный сайт паскаля:
http://pascalabc.net
Там есть кнопочка презентации. -> это знак лямбд (лямбда-выражений). Вот презентация с ними вам в первую очередь нужна.
Но вообще все презентации коротенькие и рассказывают много интересного, так что лучше прочитайте все на досуге.

Цитата Сообщение от denismix Посмотреть сообщение
Есть ли возможность в Паскале именно программно вызывать событие trackBar1.Scroll
Вы всё ещё пытаетесь неправильно использовать события.
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
type
  t1 = class
    private _x: real;
    
    // объявление события
    // как обычное поле, но со словом event
    public event x_updated: procedure(prev, val: real);
    
    public property X: real read _x write
    begin
      // событие должно вызываться только изнутри класса, где объявлено
      // и только тогда, когда произошло то, зачем оно объявлено
      x_updated(_x, value);
      _x := value;
    end;
    
  end;
  
begin
  var a := new t1;
  a.x_updated += (prev, val)->Writeln($'X было ={prev}, а затем изменено на {val}');
  a.X := 3;
  a.X := 5;
end.
События должны использоваться для того, чтоб избежать постоянных проверок в отдельном потоке, вроде таких:
Pascal
1
2
3
4
5
6
7
8
9
10
var prev_x := self._x;
while true do
begin
  var new_x := self._x;
  if prev_x<>new_x then
  begin
    Writeln('бла бла бла');
    prev_x := new_x;
  end;
end;
События выполняют код только когда что то произошло, таким образом значительно экономя время процессора.

А когда вам надо вызвать обработчик события "не по делу" - у вас неправильная архитектура кода. Если есть какое то общее действие, какое то обновление которое должно происходить и в обработчике, и в другой части кода - надо писать подпрограмму. Так же как в любом другом случае, когда в 2 частях программы нужен одинаковый участок кода.

Цитата Сообщение от denismix Посмотреть сообщение
чем другие события и позволяет себя вызывать программно без указания параметров?
Где вы в официальных примерах видели событие, которое позволяет себя вызывать? Хоть одно? Ну, не считая событий GraphABC, они не настоящие события, потому что слово event не даёт применить глобальным переменным.
1
7 / 7 / 0
Регистрация: 03.10.2014
Сообщений: 313
17.04.2020, 12:31  [ТС]
Цитата Сообщение от Sun Serega Посмотреть сообщение
А когда вам надо вызвать обработчик события "не по делу" - у вас неправильная архитектура кода. Если есть какое то общее действие, какое то обновление которое должно происходить и в обработчике, и в другой части кода - надо писать подпрограмму. Так же как в любом другом случае, когда в 2 частях программы нужен одинаковый участок кода.
Спасибо! все ваши советы мне действительно очень помогают!

Прежде всего я уже оформил всё в виде функций, т.е. сделал "как положено" =)

Что касается "неправильной архитектуры кода" :
и чего я так прицепился к программному вызову Событий

Хочу внести некоторую ясность почему я так настойчив в поисках удобства, а не оптимизации кода.
Как я понимаю, вы привыкли писать код по ТЗ, т.е. для вас возможно выглядит странным вся эта моя "вошкатня" с удобством доступа, Визуал-редактором, читаемостью кода, которые будут описаны чуть ниже.

Но у меня идет разработка "с нуля" по сопряжению компьютера, с внешним Контроллером (очень капризным и не имеющим нормального описания, к слову) и самодельным координатным станком, в который тоже постоянно вносятся чисто механические изменения.
Сделать ТЗ в сколь-либо законченном виде не представляется возможным по сути.

К слову, станок уже работает и даже делает то, что задумано - сейчас идет оптимизация его работы, подбор оптимальных параметров.
Что делает станок вы можете посмотреть вот тут: https://www.facebook.com/denis... 7560959858


Настройки приходится по 10 раз в час менять на лету, постоянно менять параметры, вводить новые и т.д. - а значит работать с полями формы и их "базовыми" событиями. Тут сейчас важна именно простота доступа к нужному событию кнопки прямо с формы.

В общем это скорее творческий инженерный процесс, чем программирование =)
Возможно это объяснит, почему на этом этапе для меня так важны именно удобство доступа, а не "правильность" и оптимальность кода
- на этом этапе важно приладить вентилятор к Карлсону, как безопасно приземляться придумаем позже =))

Добавлено через 13 минут
Работа по отладке происходит примерно так:
Открыл код,
Поменял значения поля или добавил новое поле,
При необходимости поменял обработку передачи в COM в процедуре события (например изменил способ формирования префикса именно для этого поля),
Запустил программу из оболочка Паскаля,
Внес изменения в код программы контроллера,
Перезагрузил внешний Контроллер,
Установил соединение по COM,
Отюстировал станок,
Сделал пробный прогон,
Выяснил, что что то работает не оптимально (заранее не угадаешь)
Перенастроил механику станка,
... пошел по второму кругу.

Как видите, тут не до вдумчивого поиска процедур в тексте кода и даже не до оптимизации - нужно как можно скорее и проще подобрать параметры, а уже потом оптимизировать код управляющей программы.

В общем, тут я сейчас выступаю скорее как "инженер", чем как программист.
И я конечно же не пишу код "от души", без комментов и соблюдения структуры и на сплошных костылях - просто сейчас мне действительно очень важен разумный компромисс между удобством и рациональностью.
Надеюсь на ваше понимание!

ПО СУТИ ТЕМЫ.

Так вот, я работаю с помощью встроенного в оболочку Pascal ABC "драг анд дроп редактора"
1. Создал Form1,
2. На нее положил с десяток разнородных элементов: trackBar, numericUpDown, radioButton, button(с изменяющейся программно иконкой)... ну и т.д.

ВАЖНО, что начальные значения я задавал им не в коде, а через Редактор, в таблице свойств.
И хочу и далее пользоваться именно встроенным Редактором, а не "описывать элементы ручками".
Т.е. стиль работы именно через встроенный Редактор форм!


3. Каждый элемент формы содержит предустановленное через таблицу Редактора значение и ограничения, по "основному" Событию для этого элемента (для кнопки это .Click, для trackBar Scroll) я передаю в COM порт текущие значения этого элемента (иногда перед передачей происходит дополнительная проверка, нормирование значений, формирование префикса для правильного распознавания на другой стороне COM) - в общем много разнородных и уникальных для каждого элемента формы действий.
Выносить это в отдельную процедуру для каждого элемента управления, а потом тупо вызывать эти процедуры через События, видится предельно странным. Что мешает сразу написать весь нужный код именно в процедуре самого события?

Так и быстро перейти к коду очень просто - клик в редакторе на нужный элемент,
и читаемость кода предельно простая - в процедуре События элемента сразу описывается что оно делает

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

Мне видится, что в такой ситуации проще всего, в событии Load формы просто вызвать "базовые" события для всех нужных полей формы - .Click .Scroll и т.д.

Постоянно искать в коде нужные "дополнительные" процедуры и менять код в них - очень не удобно, я их иногда в корне меняю несколько раз за 15 минут.


+ В коде более 1000 строк и Редактор Pascal ABC просто иногда подвисает при скроллинге текста, а то и просто "вылетает" (слабоват компьютер, если честно)

Спасибо за ваше долготерпение и всё же надеюсь на толковый совет по поводу вызова событий элементов при загрузке Формы.
0
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
17.04.2020, 16:11
Цитата Сообщение от denismix Посмотреть сообщение
Как я понимаю, вы привыкли писать код по ТЗ
С чего вдруг? Да и если бы и так, с чего мне быть против удобств написания? Проблема того что вы пытались сделать - только в том, что это неправильное использование средств, которое может привести к говнокоду и всему с ним связанному.

То есть, к примеру, можно писать код вообще без подпрограмм. Всё в begin-end., с кучей дублей кода.
А массивы заменять 100500 переменными.
Но когда такого кода наберётся 500-1000 строк, поддерживать его и исправлять баги станет нереально.

Так же и при вызове событий откуда попало.

---

Ну и насчёт "привыкли писать код по ТЗ" - вообще большинство проектов над которыми я работаю - это игры и для себя. На этом форуме я обычно провожу где то по 30 минут в день с простенькими задачками, типа зарядка. Ну, от необычных случаев, вроде вашего, я тоже не откажусь.

Цитата Сообщение от denismix Посмотреть сообщение
Сделать ТЗ в сколь-либо законченном виде не представляется возможным по сути.
Это так не работает. Конечно, ТЗ как в школьной задачке не составить, но если вы знаете что вы делаете - вы можете и объяснить это. И ничего страшного если какие то вещи станут устаревшими уже завтра.
Проблема только в том, что вы не пытались.

Ну, сказав этого - я, собственно, и не думал ни в один момент что ТЗ не хватает. Иначе я бы так и написал. Наверное, не помешало бы, но объяснять как используются события - мне в любом случае пришлось бы.

Цитата Сообщение от denismix Посмотреть сообщение
почему на этом этапе для меня так важны именно удобство доступа, а не "правильность" и оптимальность кода
Не путайте:

1. Архитектура кода - это каркас. Общая структура кода, которую вы придумываете перед тем как вообще что то делать. Если вы сначала взяли говно и палки и закрыли дырки смолой чтоб получился дом - вы можете потом покрыть смолу чем то на что смотреть будет на сколько то приятно, но говно и палки вы уже не замените, без полного сноса.

2. Оптимальность кода это отдельная вещь. Вы можете сортировать целый массив чтоб найти 1 максимальный элемент. Это потом можно исправить. Но как показывает практика - у вас вряд ли дойдут руки до того, чтоб нормально разобраться.

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

Обычно оптимизация кода - это как раз такие мелочи. Та же сортировка ради 1 элемента - это как первый вариант что приходит в голову. Но не надо и секунды чтоб задуматься, а ведь сортировка сверяет друг с другом сразу все элементы. Если нужно достать 1 - должен быть отдельный метод. И таки есть, .Max и .Min . И, главное, искать его придётся только 1 раз. В следующий раз вы сразу правильно напишете.

Я понимаю что у вас уже успел сформироваться образ мышления "лучше сначала хоть как то сделать", но на практике это не сделает вашу работу быстрее. Вы ещё дольше будете разбираться с тем что сразу недопоняли, и исправлять то что вначале накодили. А думать над написанием кода - надо не минутами, но и не пол секунды.

Цитата Сообщение от denismix Посмотреть сообщение
Работа по отладке происходит примерно так:
А сколько вы думали над оптимизацией каждого из шагов, на сколько можно? Раз станок самодельный - резет наверняка вы же можете себе доделать. Раз вы делаете это чаще - сэкономите кучу времени. Да и делать что то новое - всегда интереснее чем повторять одни и те же действия 100 раз.

=====
Цитата Сообщение от denismix Посмотреть сообщение
ПО СУТИ
=====

Цитата Сообщение от denismix Посмотреть сообщение
Так и быстро перейти к коду очень просто - клик в редакторе на нужный элемент,
Хотя бы регионы (наберите reg на пустом месте и нажмите Shift+Space) используете, для быстрого перехода по коду то?
Обработчики событий надо не в 1 кучу сувать, как редактор их создаёт, а перемещать так, чтоб вам было удобней и логичнее, при этом группирую регионами.

А Ctrl+тык на имена своих подпрограмм пробовали использовать? А Shift+F2, F2 и Alt+F2?
Да и вообще, зайдите в настройки и включите панель навигации.

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

А как вызывать код из событий - я вам уже прямо успел сказал, но скажу ещё более прямо: Вы сейчас пытаетесь сделать фигню вроде этой:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{$reference System.Windows.Forms.dll}
uses System.Windows.Forms;
 
label l1;
begin
  var MainForm := new Form;
  
  MainForm.Click += (o,e)->
  begin
    l1:
    // кот
  end;
  
  MainForm.Load += (o,e)->
  begin
    goto l1;
  end;
  
  Application.Run(MainForm);
end.
А потом начинаете жаловаться что не работает.

Вызов событий на самом деле возможно устроить, но для этого надо куча нечитабельных костылей.

Как я и сказал выше - методы вызова событий это только для расширений кода, который вам не принадлежит. Точнее для тех, которые эмулируют нажатий клавиш и т.п. Всё равно не для тех, которые просто пытаются вызвать конкретный функционал конкретного обработчика. Когда надо вызвать конкретный функционал - его всегда надо вызывать именно отдельно.
Отдельно от события и его параметров, как номера кнопки мышки, которой тыкнули кнопку, и т.п. Если вы будете писать такое расширение - лучшим вариантом будет скопировать тот кусок кода, содержащий нужный вам функционал, если не получается вызвать отдельно от того, что вам не надо.
1
7 / 7 / 0
Регистрация: 03.10.2014
Сообщений: 313
17.04.2020, 19:24  [ТС]
Все же я надеюсь, что есть какой то более рациональный способ, чем из процедуры в процедуру скакать по меткам.
Я, если честно, думал, что вы шутите... вы же даже точку возвата не проставили - как вернуться обратно то? =)))

Про клавиши навигации по коду знаю, и конечно же пользуюсь "закладками" и Панелью навигации, но это в десятки раз медленнее перехода по клику на элемент из Редактора форм.

Что касается умения структурировать код, то проще один раз показать.
Да, он не идеальный, но и написан меньше чем за неделю, параллельно с работой над станком.

Это одна из трех составляющих,
Интерфейс такой:


Pascal
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
unit Unit1;
 
interface
 
uses System, System.Drawing, System.Windows.Forms, System.Threading, System.IO.Ports;
 
type
  Form1 = class(Form)
    procedure Form1_Load(sender: Object; e: EventArgs);
    procedure button1_Click(sender: Object; e: EventArgs);
    procedure button3_Click(sender: Object; e: EventArgs);
    procedure button2_Click(sender: Object; e: EventArgs);
    procedure button5_Click(sender: Object; e: EventArgs);
    procedure button4_Click(sender: Object; e: EventArgs);
    procedure button7_Click(sender: Object; e: EventArgs);
    procedure button6_Click(sender: Object; e: EventArgs);
    procedure button8_Click(sender: Object; e: EventArgs);
    procedure button9_Click(sender: Object; e: EventArgs);
    procedure button2_MouseEnter(sender: Object; e: EventArgs);
    procedure button2_MouseLeave(sender: Object; e: EventArgs);
    procedure button5_MouseEnter(sender: Object; e: EventArgs);
    procedure button5_MouseLeave(sender: Object; e: EventArgs);
    procedure button4_MouseEnter(sender: Object; e: EventArgs);
    procedure button4_MouseLeave(sender: Object; e: EventArgs);
    procedure button8_MouseEnter(sender: Object; e: EventArgs);
    procedure button8_MouseLeave(sender: Object; e: EventArgs);
    procedure button3_MouseEnter(sender: Object; e: EventArgs);
    procedure button3_MouseLeave(sender: Object; e: EventArgs);
    procedure button7_MouseEnter(sender: Object; e: EventArgs);
    procedure button7_MouseLeave(sender: Object; e: EventArgs);
    procedure button9_MouseEnter(sender: Object; e: EventArgs);
    procedure button9_MouseLeave(sender: Object; e: EventArgs);
    procedure button6_MouseEnter(sender: Object; e: EventArgs);
    procedure button6_MouseLeave(sender: Object; e: EventArgs);
    procedure button1_MouseEnter(sender: Object; e: EventArgs);
    procedure button1_MouseLeave(sender: Object; e: EventArgs);
    procedure button10_MouseEnter(sender: Object; e: EventArgs);
    procedure button10_MouseLeave(sender: Object; e: EventArgs);
    procedure button10_Click(sender: Object; e: EventArgs);
    procedure button11_Click(sender: Object; e: EventArgs);
    procedure button11_MouseEnter(sender: Object; e: EventArgs);
    procedure button11_MouseLeave(sender: Object; e: EventArgs);
    procedure ConsoleTB_TextChanged(sender: Object; e: EventArgs);
    procedure button12_MouseEnter(sender: Object; e: EventArgs);
    procedure button12_MouseLeave(sender: Object; e: EventArgs);
    procedure button12_Click(sender: Object; e: EventArgs);
    procedure button13_Click(sender: Object; e: EventArgs);
    procedure button14_Click(sender: Object; e: EventArgs);
    procedure button14_MouseEnter(sender: Object; e: EventArgs);
    procedure button14_MouseLeave(sender: Object; e: EventArgs);
    procedure button13_MouseEnter(sender: Object; e: EventArgs);
    procedure button13_MouseLeave(sender: Object; e: EventArgs);
    procedure button15_Click(sender: Object; e: EventArgs);
    procedure button15_MouseEnter(sender: Object; e: EventArgs);
    procedure button15_MouseLeave(sender: Object; e: EventArgs);
    procedure button16_Click(sender: Object; e: EventArgs);
    procedure button16_MouseEnter(sender: Object; e: EventArgs);
    procedure button16_MouseLeave(sender: Object; e: EventArgs);
    procedure numericUpDown1_ValueChanged(sender: Object; e: EventArgs);
    procedure numericUpDown2_ValueChanged(sender: Object; e: EventArgs);
    procedure numericUpDown3_ValueChanged(sender: Object; e: EventArgs);
    procedure button17_Click(sender: Object; e: EventArgs);
    procedure Form1_FormClosed(sender: Object; e: FormClosedEventArgs);
    procedure button17_MouseEnter(sender: Object; e: EventArgs);
    procedure button17_MouseLeave(sender: Object; e: EventArgs);
    procedure trackBar1_Scroll(sender: Object; e: EventArgs);
  {$region FormDesigner}
  private
    {$resource Unit1.Form1.resources}
    components: System.ComponentModel.IContainer;
    ConsoleTB: RichTextBox;
    button1: Button;
    label1: &Label;
    button2: Button;
    button3: Button;
    button4: Button;
    button5: Button;
    label2: &Label;
    label3: &Label;
    label4: &Label;
    label5: &Label;
    button6: Button;
    button7: Button;
    button8: Button;
    label6: &Label;
    label7: &Label;
    label8: &Label;
    button9: Button;
    label9: &Label;
    label10: &Label;
    label11: &Label;
    button10: Button;
    label12: &Label;
    button11: Button;
    label13: &Label;
    label14: &Label;
    label15: &Label;
    label16: &Label;
    label17: &Label;
    label18: &Label;
    label19: &Label;
    label20: &Label;
    label21: &Label;
    label22: &Label;
    label23: &Label;
    label24: &Label;
    button12: Button;
    label25: &Label;
    label26: &Label;
    label27: &Label;
    label28: &Label;
    label29: &Label;
    label30: &Label;
    button13: Button;
    label31: &Label;
    label32: &Label;
    button14: Button;
    label33: &Label;
    label34: &Label;
    button15: Button;
    label35: &Label;
    label36: &Label;
    button16: Button;
    label37: &Label;
    label38: &Label;
    numericUpDown1: NumericUpDown;
    label39: &Label;
    numericUpDown2: NumericUpDown;
    label40: &Label;
    numericUpDown3: NumericUpDown;
    button17: Button;
    notifyIcon1: NotifyIcon;
    label41: &Label;
    panel1: Panel;
    trackBar1: TrackBar;
    label42: &Label;
    label43: &Label;
    label44: &Label;
    panel2: Panel;
    serialPort1: System.IO.Ports.SerialPort;
    {$include Unit1.Form1.inc}
  {$endregion FormDesigner}
  public
    constructor;
    begin
      InitializeComponent;
    end;
  end;
 
var
  ConText: string; // Для вывода в консоль
  PortOpenErrFl := false;// Флаг ошибки открытия порта
  PortEhoFl := false;// Устанавливаем флаг эхо
  th: Thread; // Переменная потока чтения COM порта
  Form2: Form; // Форма подтверждения действия
  EN_DIM: integer; // Значение микропереключателя Драйвера шагового двигателя
 
implementation
 
// Автоскролл окна консоли
procedure Form1.ConsoleTB_TextChanged(sender: Object; e: EventArgs);
begin
  ConsoleTB.SelectionStart := ConsoleTB.Text.Length;
  ConsoleTB.ScrollToCaret();
end;
 
procedure Form1.Form1_Load(sender: Object; e: EventArgs);
begin
  // Инициализируем первый доступный порт, чтобы не зависал Поток
  serialPort1 := new SerialPort(SerialPort.GetPortNames[0]);
  
  //Создаем параллельный поток, читающий из COM порта
  th := new Thread(() -> begin
    while true do
    begin
      
    // Оборачиваем чтение из порта в исключение ошибок
    try
      if serialPort1.IsOpen then
        if serialPort1.BytesToRead <> 0 then
        begin
          ConText := serialPort1.ReadLine; //ReadLine; //.ReadExisting
          //sleep(50);
          if ((PortEhoFL) and (ConText <> '')) then
            if ConText.Chars[1] = '~' then 
              case ConText.Chars[2] of
                'S': label26.Text := ConText.Substring(1);
                'M': label25.Text := ConText.Substring(1);
                'R': label27.Text := ConText.Substring(1);
                'D': label28.Text := ConText.Substring(1);
              end
            else ConsoleTB.AppendText('>> ' + ConText);
        end;
    except
      ConsoleTB.AppendText('COM порт недоступен.' + NewLine);
    end;
 
    end;
  end);
  
  ConsoleTB.AppendText('Открываем поток чтения из COM порта' + NewLine);
  th.Start; // Активаируем выполнения потока
  ConsoleTB.AppendText('Ok - поток чтения из COM порта открыт' + NewLine);
end;
 
 
 
// Подключаем COM порт
procedure Form1.button1_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.Clear;
  ConsoleTB.AppendText('Список доступных портов:');
  foreach var x in SerialPort.GetPortNames do
  begin
    ConsoleTB.AppendText(' ' + x);
  end;
  
  foreach var x in SerialPort.GetPortNames do
  begin
    PortEhoFl := false; // Сбрасываем флаг эхо
    PortOpenErrFl := false; // Сбрасываем флаг ошибки открытия порта
    serialPort1.Close; // Закрываем текущий COM порт
    
    // Выводим список всех доступных портов
    ConsoleTB.AppendText(NewLine + 'Порт: ' + x);
    serialPort1 := new SerialPort(x);
    
    application.DoEvents;
    // Оборачиваем открытие порта в исключение ошибок
    try
      serialPort1.Open;
    except
      PortOpenErrFl := true;
    end;
    
    sleep(200);
    application.DoEvents;
    
    if ConText.Contains('ArduinoMega_Mix') then break;
    serialPort1.Close;
    ConsoleTB.AppendText(' - мимо.');
    if PortOpenErrFl then
      ConsoleTB.AppendText(NewLine + 'Порт: ' + x + ' недоступен.');
  end;
  if serialPort1.IsOpen then 
  begin
    ConsoleTB.AppendText(NewLine + 'Ардуино подключен к ' + serialPort1.PortName + NewLine + NewLine);
    Label1.Text := 'Подключен к ' + serialPort1.PortName;
    if serialPort1.IsOpen then
      serialPort1.Write('1234');
    while true do 
      if ConText.Contains('OK, connect is open.') then
      begin
        ConsoleTB.AppendText('>> OK, connect is open.' + NewLine); //Выводим сообщение о подключении в консоль
        serialPort1.DiscardInBuffer; // Очищаем буфер COM
        serialPort1.DiscardOutBuffer;
        ConText := '';
        PortEhoFl := true; // Поднимаем флаг эхо
        button1.Enabled := false; // Отключаем кнопку подключения COM порта
        button17.Enabled := true; // Включаем кнопку Освободить COM
        
        // Ждем ответа от Ардуино
        //while ConText <> 'Arduino test message.' do ;
        sleep(1000);
        
        // Передаем в COM значения из Интерфейса Формы
        ConsoleTB.AppendText(NewLine + 'Передаем а Ардуино настройки:' + NewLine);
        // Положение микропереключателя Драйвера шагового двигателя
        EN_DIM := abs(trackBar1.Value); // Пересчитываем из-за особенностей элемента управления
        ConsoleTB.AppendText('EN DIM = ' + EN_DIM.ToString + NewLine);
        if serialPort1.IsOpen then
          serialPort1.Write((4000 + EN_DIM).ToString);
        sleep(200);
        
        // Значения углов поворота для Серво
        ConsoleTB.AppendText('IN =' + numericUpDown1.Value.ToString + NewLine);
        if serialPort1.IsOpen then
          serialPort1.Write((1000 + numericUpDown1.Value).ToString);
        sleep(200);
        ConsoleTB.AppendText('MID =' + numericUpDown2.Value.ToString + NewLine);
        if serialPort1.IsOpen then
          serialPort1.Write((2000 + numericUpDown2.Value).ToString);
        sleep(200);
        ConsoleTB.AppendText('OUT =' + numericUpDown3.Value.ToString + NewLine);
        if serialPort1.IsOpen then
          serialPort1.Write((3000 + numericUpDown3.Value).ToString);
        sleep(200);
        
        break;
      end;
  end
  else
  begin
    ConsoleTB.AppendText(NewLine + 'Порт Ардуино не найден' + NewLine);  
    Label1.Text := 'Нет подключения';
  end;
end;
 
 
// Сбрасываем COM порт
procedure Form1.button17_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Сбрасываем COM порт' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('17');
  sleep(3000); // Ждем ответа от Ардуино
  application.DoEvents;
  
  // Оборачиваем закрытие COM порта в исключение ошибок
  try
    serialPort1.Close; // Отключаем COM
    ConsoleTB.AppendText('Ok - выполнен сброс COM порта' + NewLine);
    button17.Enabled := false; // Отключаем кнопку Освободить COM
  except
    ConsoleTB.AppendText('Err - открытый COM порт не обнаружен' + NewLine);  
  end;
  
  button1.Enabled := true; // Включаем кнопку Подключить COM
end;
 
procedure Form1.button17_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Закрываем соединение по COM порту' + #13#10 + 'и перезагружаем Ардуино.';
end;
 
procedure Form1.button17_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
 
 
procedure Form1.button2_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Шаг против часовой' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('1');
end;
 
procedure Form1.button2_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Шаг против часовой';
end;
 
procedure Form1.button2_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
procedure Form1.button5_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Шаг по часовой' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('2');
end;
 
procedure Form1.button5_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Шаг по часовой';
end;
 
procedure Form1.button5_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
procedure Form1.button4_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Нитеводитель в центр' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('3');
end;
 
procedure Form1.button4_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Нитеводитель в центр';
end;
 
procedure Form1.button4_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
procedure Form1.button3_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Подвигать нитеводителем' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('4');
end;
 
procedure Form1.button3_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Подвигать нитеводителем';
end;
 
procedure Form1.button3_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
procedure Form1.button8_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Переход к следующему пину' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('5');
end;
 
procedure Form1.button8_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Переход к следующему пину';
end;
 
procedure Form1.button8_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
procedure Form1.button7_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Переход к предыдущему пину' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('6');
end;
 
procedure Form1.button7_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Переход к предыдущему пину';
end;
 
procedure Form1.button7_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
procedure Form1.button9_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Обвести текущий пин' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('7');
end;
 
procedure Form1.button9_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Обвести текущий пин';
end;
 
procedure Form1.button9_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
procedure Form1.button6_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Сохранить поправку' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('8');
end;
 
procedure Form1.button6_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Сохранить поправку в массив на Ардуино' + #13#10 + 'array[ST] = MS';
end;
 
procedure Form1.button6_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
procedure Form1.button10_Click(sender: Object; e: EventArgs);
begin
  //Запрашиваем подтверждение действия
  if MessageBox.Show('Уверен?','Внимание!',MessageBoxButtons.YesNo,MessageBoxIcon.Question).ToString <> 'Yes' then exit;
  
  ConsoleTB.AppendText('ЗАПУСК' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('9');
end;
 
procedure Form1.button10_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Запуск основного процесса.' + #13#10 + 'С клавиатуры [Shift + P]';
end;
 
procedure Form1.button10_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
procedure Form1.button11_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('ПАУЗА' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('11');
end;
 
procedure Form1.button11_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Пауза основного процесса.' + #13#10 + 'Не реализовано!!!';
end;
 
procedure Form1.button11_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
procedure Form1.button12_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Нитеводитель в круг' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('10');
end;
 
procedure Form1.button12_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Перевод нитеводителя в круг';
end;
 
procedure Form1.button12_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
 
procedure Form1.button14_Click(sender: Object; e: EventArgs);
begin
  //Запрашиваем подтверждение действия
  if MessageBox.Show('Уверен?','Внимание!',MessageBoxButtons.YesNo,MessageBoxIcon.Question).ToString <> 'Yes' then exit;
  
  ConsoleTB.AppendText('Полный тестовый цикл' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('12');
end;
 
procedure Form1.button14_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Полный тестовый цикл с обходом всех пинов по очереди';
end;
 
procedure Form1.button14_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
procedure Form1.button13_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Вывести массив с поправками в консоль' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('14');
end;
 
procedure Form1.button13_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Вывести массив с поправками в консоль';
end;
 
procedure Form1.button13_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
// Подсказка для Подключить COM
procedure Form1.button1_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Автоматически подключить Ардуино к COM порту';
end;
 
procedure Form1.button1_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
procedure Form1.button15_Click(sender: Object; e: EventArgs);
begin
  //Запрашиваем подтверждение действия
  if MessageBox.Show('Уверен?','Внимание!',MessageBoxButtons.YesNo,MessageBoxIcon.Question).ToString <> 'Yes' then exit;
  
  ConsoleTB.AppendText('Сбросить положение на "0": ST=0, MS=0. ' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('15');
end;
 
procedure Form1.button15_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Сбросить положение на "0":' + #13#10 + 'ST=0, MS=0.' + #13#10 + 'С клавиатуры [Shift + O]';
end;
 
procedure Form1.button15_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
procedure Form1.button16_Click(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('Отключить шаговый двигатель' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('16');
end;
 
procedure Form1.button16_MouseEnter(sender: Object; e: EventArgs);
begin
  label10.Text := 'Отключить шаговый двигатель.' + #13#10 + 'Один раз подается команда на отключение.';
end;
 
procedure Form1.button16_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
 
 
// Передаем настройки углов для Серво. К значениям прибавляем 1000, 2000, 3000  для распознавания
procedure Form1.numericUpDown1_ValueChanged(sender: Object; e: EventArgs);
begin
    ConsoleTB.AppendText('IN =' + numericUpDown1.Value.ToString + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write((1000 + numericUpDown1.Value).ToString);
end;
 
procedure Form1.numericUpDown2_ValueChanged(sender: Object; e: EventArgs);
begin
    ConsoleTB.AppendText('MID =' + numericUpDown2.Value.ToString + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write((2000 + numericUpDown2.Value).ToString);
end;
 
procedure Form1.numericUpDown3_ValueChanged(sender: Object; e: EventArgs);
begin
  ConsoleTB.AppendText('OUT =' + numericUpDown3.Value.ToString + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write((3000 + numericUpDown3.Value).ToString);
end;
 
procedure Form1.Form1_FormClosed(sender: Object; e: FormClosedEventArgs);
begin
  ConsoleTB.AppendText('Сбрасываем COM порт' + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write('17');
  sleep(3000); // Ждем ответа от Ардуино
  application.DoEvents;
  
  // Закрываем COM, если открыт
  if serialPort1.IsOpen then
  begin
    serialPort1.Close; // Отключаем COM
    ConsoleTB.AppendText('Ok - выполнен сброс COM порта' + NewLine);
    button17.Enabled := false; // Отключаем кнопку Освободить COM
  end;
 
  ConsoleTB.AppendText('Ok - выполнен сброс COM порта' + NewLine);
  
  ConsoleTB.AppendText('Прерываем поток чтения из COM порта' + NewLine);
  th.Abort; // Прерываем поток чтения из COM порта
  ConsoleTB.AppendText('Ok - выполнена остановка потока' + NewLine);
  
  ConsoleTB.AppendText(NewLine);
  ConsoleTB.AppendText(NewLine);
  ConsoleTB.AppendText(NewLine);
  ConsoleTB.AppendText('=============================' + NewLine);
  ConsoleTB.AppendText(' >> ЗАВЕРШЕНИЕ ПРОГРАММЫ <<' + NewLine);
  ConsoleTB.AppendText('=============================' + NewLine);
end;
 
procedure Form1.trackBar1_Scroll(sender: Object; e: EventArgs);
begin
  EN_DIM := abs(trackBar1.Value); // Пересчитываем из-за особенностей элемента управления
  ConsoleTB.AppendText('EN DIM = ' + EN_DIM.ToString + NewLine);
  if serialPort1.IsOpen then
    serialPort1.Write((4000 + EN_DIM).ToString);
end;
 
 
end.
0
7 / 7 / 0
Регистрация: 03.10.2014
Сообщений: 313
17.04.2020, 19:32  [ТС]
UPD не нашел как удалить...
0
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
17.04.2020, 20:37
Цитата Сообщение от denismix Посмотреть сообщение
Все же я надеюсь, что есть какой то более рациональный способ, чем из процедуры в процедуру скакать по меткам.
Я, если честно, думал, что вы шутите... вы же даже точку возвата не проставили - как вернуться обратно то? =)))
Наверное всё же шучу. А точнее показал ещё более обскурный пример.
Прочитайте внимательно что я сразу после этого примера сказал.

Цитата Сообщение от denismix Посмотреть сообщение
Pascal
1
2
3
4
procedure Form1.button7_MouseLeave(sender: Object; e: EventArgs);
begin
  label10.Text := 'Для подсказки наведи указатель на элемент';
end;
Бож... что это? Ну вот такие вещи точно надо в отдельную процедуру. Хотя бы потому что волшебная строка, использованная как минимум несколько десятков раз.

И таки используйте короткие процедуры:
Pascal
1
2
procedure Form1.button7_MouseLeave(sender: Object; e: EventArgs) :=
label10.Text := 'Для подсказки наведи указатель на элемент';
Добавлено через 1 минуту
В остальном - регионов действительно не хватает. Но чего вам прямо так сложно ориентироваться - не понимаю.
0
7 / 7 / 0
Регистрация: 03.10.2014
Сообщений: 313
18.04.2020, 03:31  [ТС]
Цитата Сообщение от Sun Serega Посмотреть сообщение
Бож... что это? Ну вот такие вещи точно надо в отдельную процедуру.
Почему то был уверен, что вы обнаружите именно этот нюанс. Хорошо, что мне не 19, а вы не мой научный руководитель - хотя у вас очень похоже получилось =)))

1. Это писалось шаблоном
2. Если вдуматься, то вызов этой строки по объёму откомпилированного кода примерно такой же как вызов процедуры в которую я засунул бы эту строку.

Ну а если уж говорить о "правильности" нужно было сделать так,
это как бы стандарт в таких случаях и реально правильно со всех сторон: по компактности кода, по скорости обработки и по читаемости.

Pascal
1
2
3
4
5
6
7
8
9
const  
MSG := 'Для подсказки наведи указатель на элемент';
 
begin
 label10.Text := MSG;
 label22.Text := MSG;
 ...
 label100500.Text := MSG;
end.
Но во избежание дальнейших споров - это просто "заглушки", после отладки буду это менять на свойство самой Формы, что еще более правильно. Просто пока не знаю как будет выглядеть конечный вариант интерфейса.
0
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
18.04.2020, 08:24
Ну вот вы снова говорите что после отладки уже замените. Но при этом вы же говорили что ориентироваться в таком объёме кода - сложно.

Если сейчас взять все обработчики с одинаковым кодом в 1 кучу в конце файла, обернуть в регион и свернуть - это уже как минимум минус половина кода. Вы же вряд ли будете менять код в этих обработчиках. А значит и держать так же где всё остальное - нет смысла.

Вот такую сортировку кода я имел в виду.
0
7 / 7 / 0
Регистрация: 03.10.2014
Сообщений: 313
18.04.2020, 14:11  [ТС]
Так я сейчас именно с ними и работаю.
Именно эти самые обработчики кода (События) я и хотел бы вызывать программно, топик собственно об этом =))

А что значит "Опять потом..."? - Несомненно потом, потому, что сейчас рано.
Кроме того эти строки мне наоборот помогают ориентироваться в коде, собственно это основная причина, почему я их до сих пор не переделал точнее почему пользуюсь этим шаблоном.
Эти строки визуально отличный "разделитель" групп обработчиков .

И конечно же нет никакого смысла делать уже сейчас пусть даже коротенькую функцию по обработке строки подсказок и приаттачить это к форме (чтобы убрать эти одинаковые строки) - а вдруг я решу сделать на форме вкладки или разделю ее на блоки?
Что же тогда переписывать код заново просто потому, что "из принципа" сделал это раньше времени? =))

ИМХО, важно только, чтобы код на этапе разработки был правильно структурирован и такие "хвосты" были заметны и поддавались автоматической чистке по "Найти/Заменить".

У меня за плечами несколько довольно серьезных коммерческих и гос проектов с работой в группе из 10-20 коллег (интерфейсы и математические алгоритмы),
на этапе разработки такие вот "хвосты", если уметь с ними работать, только помогают.
Мне кажется, что вы иногда перегибаете палку в нравоучениях о чистоте кода и правильности его оформления.

При всем этом я вам искренне признателен за помощь и объяснения в неизведанных для меня уголках объектной модели Pascal ABC, толковее вас мало кто мне здесь что либо объяснял.
Ну и да, я несомненно отстал от последних веяний и не знаю новейшего синтаксиса - просто занимался несколько другими вещами, где это было совершенно не нужно.
0
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
18.04.2020, 15:45
Цитата Сообщение от denismix Посмотреть сообщение
Так я сейчас именно с ними и работаю.
Вы работаете с обработчиками событий, но не со всеми. На сколько вероятно что вы вскоре измените реализацию одного из обработчиков MouseLeave? По моему 0. Ну, не считая саму чистку.

Цитата Сообщение от denismix Посмотреть сообщение
а вдруг я решу сделать на форме вкладки или разделю ее на блоки?
Что же тогда переписывать код заново просто потому, что "из принципа" сделал это раньше времени? =))
А так как оно сейчас - по вашему будет надо меньше (и, что важнее, проще) переписывать? Код наоборот становится более модульным, при избавлении от дублей кода.
Модульность кода значит что если вы решите что то менять - вам надо будет менять не 100 строк а 10.

Цитата Сообщение от denismix Посмотреть сообщение
чтобы код на этапе разработки был правильно структурирован
Ну так а я говорю как раз что он у вас ужасно структурирован.

Я сразу прочитал что это текучий код и не начинал про красоту кода. Всё это время я говорил только про то, что практично.

Вещи которые кривые но быстро исправляются - есть и в моих проектах, во время разработки. Но выглядит это совершенно по-другому. По крайней мере у меня всегда всё оказывается разложено по порядку в несколько вложенных регионах, как только код занимает >200/300 строк.
И разделители у меня состоят не из того что так уж получилось что уже лежит там, а из комментариев или пустых строк (но обычно сворачивания регионов хватает).

Хотя когда то я тоже мог сказать что то такое про свой код
Цитата Сообщение от denismix Посмотреть сообщение
эти строки мне наоборот помогают ориентироваться в коде
Но, благо, я такое перерос года 3-4 назад.

---

Ну впрочем как раз эта последняя цитата - явно переход в защиту. Вы ведь просто использовали что оказалось под рукой не задумавшись, а теперь доказываете что это удобно и специально. Так что об этом бесполезно продолжать говорить.

Просто попробуйте несколько других способов организации кода, только тогда увидите в чём я прав, что я сам не знал, а что для вас не работает. Если не пробовать новое - можно так и остаться в каменном веке.
0
7 / 7 / 0
Регистрация: 03.10.2014
Сообщений: 313
18.04.2020, 21:57  [ТС]
Цитата Сообщение от Sun Serega Посмотреть сообщение
Вы работаете с обработчиками событий, но не со всеми.
В том и проблема, что в ходе отладки никогда не известно, с чем придется работать, поэтому все однотипное лежит в коде подряд, спорное или то с чем работаю кроме однотипных блоков - внизу. Тут же важно личное удобство, а не какие то правила =)

Цитата Сообщение от Sun Serega Посмотреть сообщение
А так как оно сейчас - по вашему будет надо меньше (и, что важнее, проще) переписывать?
Конечно проще! Если решу строку подсказки подвязывать к форме, просто кильну все события Mouse Live требующихся элементов интерфейса оптом, тупо выделив их с шифтом в Редакторе форм и удалив Событие для всех выделенных.
Если решу заменить на label10.Text := MSG; то простая Замена.
Я же говорю - у всех свои "фишки" в работе и все строят код под себя... а вы упорно настаиваете - делай как я...

Цитата Сообщение от Sun Serega Посмотреть сообщение
Ну впрочем как раз эта последняя цитата - явно переход в защиту.
Отчасти да, но это же наработанная привычка - просто знаю как с этим дальше работать удобно и быстро, вот и оставил такой формат рабочего кода. Да и проще, целый блок закопипастить подряд, чем выискивать по коду в разных местах.

Цитата Сообщение от Sun Serega Посмотреть сообщение
(но обычно сворачивания регионов хватает)
Пробовал сворачивать регионы, но у меня Редактор кода не запоминает, что было свернуто и при перезагрузке проекта (а мне приходится постоянно работать с двумя параллельными проектами), все "сворачивания" снова разворачиваются.
Может нужно где то галочку поставить, не подскажите?
0
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
19.04.2020, 04:18
Цитата Сообщение от denismix Посмотреть сообщение
но у меня Редактор кода не запоминает
Да, есть такое. Реализовывать эту фичу разработчики боятся. Ну, взамен дали кнопку под ПКМ для сворачивания все регионов сразу.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.04.2020, 04:18
Помогаю со студенческими работами здесь

Программно вызвать последнее событие
Привет всем. Стоит задача - восстановить состояние формы (только до последнего произошедшего события) по желанию пользователя (путем...

Программно вызвать событие ссылки
Добрый день. имеется необходимость организовать автоматическое нажатие на кнопки некоторой страницы html, нажимать нужно на элементы...

Как вызвать диалоговое окно Windows Forms с веб-страницы?
Есть веб-приложение. Есть страница его настройки. При нажатии одной из кнопок на этой странице должно вываливаться диалоговое окно...

Можно ли программно вызвать событие в Lotus?
Можно ли программно вызвать событие в Lotus? Например OnClick и т.п. И еще как выполнить на LotusScript следующее @Command(). Нужно...

Нужно вызвать событие в программно созданном SocketServer
Дело такое. Я организовываю чат через TSocketServer/client У меня идёт создание вотрой комнаты для чата и для неё нужно применить теже...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru