application processmessages delphi что это

Application processmessages delphi что это

Метод Application.ProcessMessages необходимо применять в динамичных приложениях, требующих немедленного отображения выполненных в программе действий. Для повышения быстродействия программы сообщения (Messages!), которые объект Application посылает объектам программы, этими объектами выполняются не сразу после получения, а по мере накопления некоторой очереди.

Для иллюстрации работы метода Application.ProcessMessages рассмотрим процедуру, троекратным «мельканием» текста в строке ввода обращающего внимание пользователя на то, что данные не введены:

Аналогично, программа, выполняющая длительные вычисления, может выглядеть зависшей, так как даже сообщения на перемещение её окна или нажатия на кнопки не будут обработаны, пока вычисления не будут закончены. Поэтому нужно либо выполнять вычисления в отдельном потоке, либо периодически выполнять Application.ProcessMessages. Однако, в этом случае нужно учитывать, что выполнение этого метода несколько тормозит выполнение программы, и его вызов не должен быть слишком частым.

Другой пример, связанный с работой с графикой в Delphi. Динамика построения графиков функций, когда график рисуется постепенно, по мере вычисления очередной точки, выглядит в программе очень эффектно. Чтобы добиться такого эффекта, также необходимо применять метод Application.ProcessMessages. Вычисляя положение очередной точки, нужно после её выведения на холст:

Canvas.LineTo(X[n], Y[n]);
sleep(200);

Без применения последнего оператора мы получим сразу готовый график функции, и даже применение оператора задержки перед выводом очередной точки не поможет.

Источник

Application processmessages delphi что это

Метод Application.ProcessMessages необходимо применять в динамичных приложениях, требующих немедленного отображения выполненных в программе действий. Для повышения быстродействия программы сообщения (Messages!), которые объект Application посылает объектам программы, этими объектами выполняются не сразу после получения, а по мере накопления некоторой очереди.

Для иллюстрации работы метода Application.ProcessMessages рассмотрим процедуру, троекратным «мельканием» текста в строке ввода обращающего внимание пользователя на то, что данные не введены:

Аналогично, программа, выполняющая длительные вычисления, может выглядеть зависшей, так как даже сообщения на перемещение её окна или нажатия на кнопки не будут обработаны, пока вычисления не будут закончены. Поэтому нужно либо выполнять вычисления в отдельном потоке, либо периодически выполнять Application.ProcessMessages. Однако, в этом случае нужно учитывать, что выполнение этого метода несколько тормозит выполнение программы, и его вызов не должен быть слишком частым.

Другой пример, связанный с работой с графикой в Delphi. Динамика построения графиков функций, когда график рисуется постепенно, по мере вычисления очередной точки, выглядит в программе очень эффектно. Чтобы добиться такого эффекта, также необходимо применять метод Application.ProcessMessages. Вычисляя положение очередной точки, нужно после её выведения на холст:

Canvas.LineTo(X[n], Y[n]);
sleep(200);

Без применения последнего оператора мы получим сразу готовый график функции, и даже применение оператора задержки перед выводом очередной точки не поможет.

Источник

Delphi. Messages. Первые наивные пробы

Решил разобраться с устройством Windows, в частности с сообщениями. Народ в сети массово отправляет к Рихтеру и Русиновичу. Книги приобрел – начал читать. Что хочу сказать – первое впечатление – информация ценнейшая для разработки под Windows. Ещё и на русском языке. Но поскольку практика это лучший инструмент познания, решил сделать несколько простых примеров до основательного чтения этих книг. После чтения сделаю ещё несколько примеров, чтобы сравнить насколько лучше понимаю предмет.

Как отправить сообщение из приложения?

Рассмотрим на примере закрытия окна. Сообщение будет WM_CLOSE. Список всех сообщений для Windows можно посмотреть здесь.

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

Оба сообщения закроют окно c Handle равным Form2.Handle Первый параметр – Handle окна, второй параметр – собственно сообщения, а третий и четвертый – дополнительные параметры, которые задействуются или нет от случая к случаю, например координаты курсора. В приведенном примере оба параметра занулены. Если поместить эти инструкции, скажем в обработчик кнопки окна, то после нажатия в ядро Windows будет направлено сообщение о закрытии окна, а Windows, соответственно просто закроет окно.

Где найти полный список сообщений?

В принципе таких ресурсов много. Вот один из них.

Слушает ли Delphi программа сообщения?

Определенно да. Вот простой пример. Поймаем сообщение нажатия правой кнопкой мыши на любом из компонентов приложения.

Если нажмем правой клавишей мыши на любом компоненте приложения, то увидим

Здесь мы отлавливали сообщение о нажатии правой кнопки мыши. Таким же образом можно отлавливать любые другие сообщения из списка.

Как отправить “кастомное” сообщение?

Под кастомным сообщением я подразумеваю сообщение не из списка, а какое-то свое сообщение, например WM_USER+2001. Вот как можно отправить такое кастомное сообщение. Пример основан на официальной документации

Объявляем глобальную константу

Далее создаем и присваиваем обработчик

И последний штрих – отправляем сообщения

Ещё вариант отправки кастомного сообщения

Определяем свою константу (она должна быть прописана выше, чем метод, который её использует, то есть, например, до описания типов)

Далее определяем обработчик сообщения в методах класса формы, например, таким образом

Далее прописываем его

Далее отправляем PostMessage, скажем, по нажатию кнопки

Источник

I do not understand what Application.ProcessMessages in Delphi is doing [closed]

Want to improve this question? Update the question so it focuses on one problem only by editing this post.

I’m a noobie in Delphi, so sorry for any silly question.

My supervisor explained me that Application.ProcessMessages prevents freezing of the application and allocates some extra computing time. But in the docs of this command is always something explained about a queue system which is processed? Please can somebody explain me the context?

2 Answers 2

There is no short way to answer this question properly.

The primary means by which Windows applications interact with the operating system is via a messaging system. Everything that happens in a windows application happens in response to a message.

For example :

If you click on the screen, the operating system decides which application got clicked and posts a message to that application indicating that it has received a click (along with the location of that click).

Читайте также:  что такое гороно расшифровка

If a window is moved and reveals a part of your application beneath it, the operating system sends a message telling your application to repaint itself.

The list goes on. Everything that happens is driven by messages.

The Problem

You come along and start writing an application. You might write some code like this :

In the larger structure of the program, execution in the main thread looks like this:

So this loop is happily wizzing along when suddenly one of the associated handlers ( Button1Click above) starts taking a very long time to complete. Key to understand is that one message handler must complete before the next one can run. If you click a scrollbar, for example, and drag it, but you’ve attached a handler to OnClick of the scrollbar that takes 10s to complete, then the drag operation will not be seen by your application until that click handler completes. In the meantime, the message queue is filling up and the main thread is not doing anything about it.

Enter ProcessMessages

The lazy, terrible solution to not putting your long-running code into a thread

What you are doing when you are calling Application.ProcessMessages is, in the middle of one of these handlers, instructing the main thread to take a break to go back to check the message queue and empty any messages that have been piling up; to handle any clicks, window movements, inputs, keystrokes, to repaint itself if needed, etc.

This may seem superficially like a sensible thing to do since it allows you to keep the application responsive during a long-running loop. Ultimately, however, this style of programming is widely considered to be extremely poor practice for a large number of very good reasons. Suffice it to say that anywhere you are tempted to use Application.ProcessMessages is a solid case for moving that work to a background thread instead.

For more detail, let’s have a look at the actual code :

So when you make this call to Application.ProcessMessages you are running a loop that is, one by one, emptying messages from the message queue (and executing all of the code that is attached to handlers that are reacting to those messages) until it is empty. When it is empty and there are no more messages to process, control will return to the next line in your program.

The important point to take away is that the fluid, smooth interaction you experience when using a program is a complete illusion that depends exactly on this message loop being processed as quickly as possible. The smaller the time delay between a message being posted to your application and the message being handled, the more your application will feel like it is alive and responsive.

It is for this reason that all code that is attached to user-interface handlers should be fast running. Long running operations either need to be interrupted so that message handling can continue (ie: Application.ProcessMessages ) or those operations need to be moved to a separate thread where they can execute without tying up the main thread and taking it away from its primary responsibility (which is to keep the user-interface alive).

For a really good article on the topic, see :

A Key’s Odyssey by Peter Below

Abstract: This article follows the path of a keystroke message through the VCL. You will learn how the key processing is implemented, how the OnKey events work and what intervention points for the programmer can be found in the whole process. In addition, things like message processing are explained, and you will learn how to trace messages in the debugger from the message loop to their eventual destination.

Messaging

A Delphi VCL application is a Windows application and a lot of communication between Windows components (like forms, edit boxes, but also hidden things like timers) is done using things called messages.

These messages are used to notify controls that significant events have occurred within the program so they can respond appropriately. That concept of sending and responding to messages is the core principle of a paradigm known as event-driven programming.

Many modern operating systems are event-driven, such as Windows. In fact the Delphi VCL wraps a lot of Windows functionality, and many things you do will result in messages being sent between controls, which notify those controls of mouse clicks, keyboard presses, Windows-settings changing, application closing, control moving, etc.

Mainthread doesn’t process messages when executing code

Operating systems also allow programs to have things called threads. Threads are like small pieces of a program that appear to operate simultaneously (and in some cases actually do run simultaneously). An application can have more than one thread, but there is always the main thread, which is also the thread responsible for accepting incoming messages and updating the GUI.

When the main thread of the application is idle (not executing code), it will check the queue to see if there are messages and process them. While other unrelated code is executing, this cannot happen. Consider this example:

If you execute this code, you would expect the label to get a caption of ‘A’, which changes to ‘B’ five seconds later. But this is not true. Setting the caption of a label triggers a repaint of the control through a message. Because the main thread is still blocked by this code (even by the Sleep command), the message isn’t processed yet.

Читайте также:  какой мазью обработать прокол уха

Only when the 5 seconds have passed and the caption is set to ‘B’, the main thread becomes idle and will execute the repaints that we triggered by setting the caption. Also note that other interaction, like clicking a button or dragging the window are postponed until the 5 seconds have passed. The entire UI freezes while the main thread is executing that code.

Application.ProcessMessages to the rescue

Application.ProcessMessages will just force the application to empty its message queue, so you can ‘fix’ the code like this:

Usually there won’t be just a Sleep in your code, but a lot of actual processing. By using Application.ProcessMessage frequently, you can keep the interface of the application responding, even when you are executing code.

So the docs you read are right: Application.ProcessMessages will empty the message queue. Your supervisor is not exactly right. It doesn’t allocate extra processing time per say, but it just integrates the emptying of the message queue into the code that is executed, while normally the messages would remain in the queue until the application becomes idle.

Internals

It’s the processing that executes the code, for instance when a WM_MOUSECLICK message is processed, it will trigger (through some Delphi VCL magic), your Button1Click event handler. Since this is a single thread, everything runs sequentially, so you’ll understand that ProcessMessageFromTheQueue only returns when the event handler is finished. Delphi handles only one message at a time, and only does the next when processing the previous one is finished.

Application.ProcessMessages looks like this:

So it does almost the same as the application main loop: it picks a message from the queue and processes it. So this means, you can actually process the next messages while you are inside the processing of the last one. A convenient trick, but it can easily make your application messy and cause all kinds of unwanted side effects.

The right way: Threads

Most people consider it a better solution to use a separate thread for executing your code and just send signals to the main thread when it needs to update a label or a progress bar. That way, the main thread is idle all the time, and will keep responding to mouse clicks etc.

Threading is tough for a beginner, though. Some things to keep in mind:

Источник

Application processmessages delphi что это

Недавно прочитал в какой-то статье, посвященной программированию в среде Delphi, что в нормальном приложении Application.ProcessMessages вообще не должно быть. Видимо, имелось в виду, что нужно обходиться другими методами. Как бы вы прокомментировали это?


MBo ( 2004-01-06 18:44 ) [1]


YuRock ( 2004-01-06 18:49 ) [2]

ProcessMessages используется при необходимости выкрутить сообщения. При чем здесь «нормальное приложение», не понятно.


Тимохов ( 2004-01-06 18:50 ) [3]

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


jack128 ( 2004-01-06 19:00 ) [4]

Чем проще программа, тем лудше использовать Application.ProcessMessages, ибо нефиг излишне усложнять программу потоками.

jack128 © (06.01.04 19:00) [4]

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

Сухой остаток: юзать можно, но осторожно.


ИМХО ( 2004-01-06 19:02 ) [6]

А как это делать (насчет отдельных потоков)?

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


Vlad ( 2004-01-06 19:11 ) [7]

TThread + F1.
И еще в FAQ есть кое какая инфа, даже с кодом.


jack128 ( 2004-01-06 19:39 ) [8]


>
> Тимохов © (06.01.04 19:02) [5]
> jack128 © (06.01.04 19:00) [4]
>
> ProcessMessages все-таки коварная штука.
> Чессо слово тяжело сейчас строить пример, несмотря на то,
> что я его хорошо помню. Но уверен, что некоторое время он
> любого вы ввел в заблуждение.
Думаю пример был бы в том что несколько обработчиков сообщений изменяют одну и туже глобальную переменную.

например
var
obj: TMyClass = nil;

procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndNil(obj);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
obj := TMyClass.Create;
end;


Anatoly Podgoretsky ( 2004-01-06 19:49 ) [9]

Ну и какое отношение это глюкавый код имеет к якобы глюкавому Application.BrocessMessages.

Авторы хотят выглядеть святее, чем Папа Римский.
Так что читать такие статьи лучше с включенной головой.


jack128 ( 2004-01-06 19:52 ) [11]


> Anatoly Podgoretsky © (06.01.04 19:49) [9]
> Ну и какое отношение это глюкавый код имеет к якобы глюкавому
> Application.BrocessMessages.
Да водщем то никакого. Это доказательство того, что имея достаточно кривые руки можно написать глюкавый код в пять строк 😉


Тимохов ( 2004-01-06 19:54 ) [12]

Игорь Шевченко © (06.01.04 19:49) [10]
Немного грубовато имхо.

Всем.
в [8] есть пример ошибки. Может случить там, что obj отдестроиться, когда цикл еще не кончился.
У меня действительно была схожая ситуация, только такм был не цикл, а рекурсия.

jack128
Ценю проницательность 🙂


Anatoly Podgoretsky ( 2004-01-06 19:55 ) [13]

Конечно можно, но почти тотже код без Application.BrocessMessages даст тот же самый результат.

procedure TForm1.Button1Click(Sender: TObject);
begin
obj.SameMethod;
// нажать вторую кнопку, затем первую


Тимохов ( 2004-01-06 19:56 ) [14]

Anatoly Podgoretsky © (06.01.04 19:49) [9]
И вообще никто не говорил, что processmessages имеет глюки.
Просто он таит в себе определенные опасности при кривых, как было сказано выше, руках.

Читайте также:  le tigre deceptacon о чем

Anatoly Podgoretsky © (06.01.04 19:55) [13]
Думаю все-таки ясно в чем была суть примера. ИМХО Вы издеваетесь. 🙂


Anatoly Podgoretsky ( 2004-01-06 19:58 ) [16]


Тимохов ( 2004-01-06 20:01 ) [17]

Anatoly Podgoretsky © (06.01.04 19:58) [16]
Думаю надо согласиться на том, что данный пример подразумевает нажатие сначала первой кнопки. И пока там идет while нажатие второй кнопки. Думаю, что пример обладает некой недоделанностью. Но суть обсуждаемого вопроса показывает полностью.


Anatoly Podgoretsky ( 2004-01-06 20:10 ) [18]

Показывает только безобразно написаный код и не более.


Игорь Шевченко ( 2004-01-06 20:12 ) [19]

Тимохов © (06.01.04 19:56)


> никто не говорил, что processmessages имеет глюки.
> Просто он таит в себе определенные опасности при кривых,
> как было сказано выше, руках.

А при кривых руках, уважаемый, на помощь приходит выпрямитель рук, называемый отладчиком или WinSight»ом(для просмотра сообщений). Если вы молотком по пальцу попадете, забивая гвоздь, вы же не станете писать статью о вреде использования молотка 😉


Тимохов ( 2004-01-06 20:27 ) [20]

Игорь Шевченко © (06.01.04 20:12) [19]
Anatoly Podgoretsky © (06.01.04 20:10) [18]

Ладно, чтобы пояснить свою мысль прведу свой код.
Есть SomeAction выполняемая по клавише F5.
Пользователь нажимает на эту клавишу в течении одной минуты. Потом сразу нажимает крестик в углу форма (т.е. close)
Вот упрощенный код.

procedure tform1.SomeActionExecute(. )
begin
if SomeHeavyDatabaseQuery <> nil then
begin
Application.ProcessMessages();
SomeHeavyDatabaseQuery.Execute();
end;
end;

destructor tform1.Destroy();
begin
FreeAndNil(SomeHeavyDatabaseQuery);
end;

Что здесь происходит.
Когда пользователь жмет f5, то прога может дойти до Application.ProcessMessages(). После чего не пойдет дальше а снова попадет в этот же обработчик. И так раз сто. При этом образуется полноценный (т.е. дельфовый, а не ивентный) стек вызовов. Когда пользователь вызывает close, то он делается releasom, т.е. тоже через посыл сообщения. Этот ивент радостно отрабатывает, после чего выполнение программы возвращается на строку SomeHeavyDatabaseQuery.Execute(). Здесь и происходит АВ.

В примере можно задать не запрос, а любое занимающее время действие с обращением к полям объекта.

В описанной ситуации будет ошибка. Ясно, что это ошибка программиста, но все же она не вполне очевидна.


Бином Ньютоныч ( 2004-01-06 20:40 ) [21]

>нормальном приложении Application.ProcessMessages вообще не должно быть.


Anatoly Podgoretsky ( 2004-01-06 20:55 ) [22]

Она вполне очевидна, неверная последовательность операторов, если же нужна именно эта последовательность, то проверять надо после Application.ProcessMessages(); иначе получается некоторая самоуверенность, попытка использования переменной или поля с непредсказуемым содержимым.

Кривые руки никак не доказывают недостатков Application.ProcessMessages, народ умудряется работать с объектами вообще их не создавая. Данный метод ни чем не хуже других неверно используемых средств. Сам метод как раз и предусмотрен, чтобы обработать сообщения системы, еще с времен Windows 1.0, а многозадачная среда накладывает свой отпечаток.


Anatoly Podgoretsky ( 2004-01-06 20:58 ) [23]

Бином Ньютоныч (06.01.04 20:40) [21]
Ресурсоемкость да бог с ней, а вот с потоками столько ошибок наделают, что всю систему на колени поставят. Потоки нужны для выполнения паралельной работы.вычислений, но никак не для обработки сообщений.


Бином Ньютоныч ( 2004-01-06 21:13 ) [24]

>Anatoly Podgoretsky © (06.01.04 20:58) [23]
Ну вообще-то я имел в виду вариант с выносом ожидания в отдельный поток:) В смысле вовсе не всегда это оптимально


Anatoly Podgoretsky ( 2004-01-06 21:22 ) [25]

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


Тимохов ( 2004-01-08 11:26 ) [26]

Но, все-таки хочется подвести итог данному обсуждению.

Исходный вопрос автора был о нашем отношении к высказыванию некого автора некой статьи о том, что ProcessMessages вообще быть не должно.


Игорь Шевченко ( 2004-01-08 12:14 ) [27]

Тимохов © (08.01.04 11:26)


> использовать ProcessMessages можно, но осторожно


Тимохов ( 2004-01-08 12:19 ) [28]

Игорь Шевченко © (08.01.04 12:14) [27]

Смешного ничего здесь не вижу.
И вообще, обещаю, что в следующий раз при обсуждении не вполне очевидного момента после приведения ошибочного кода не буду давать комментарий почему он ошибочен. Интересно, сдюжат ли мастера прорюхать что к чему? :)))

И вообще, все, что нужно по данному вопросу счию уже сказано.


int64 ( 2004-01-09 12:17 ) [29]

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

Вот об этом и весь разговор: о преймуществе второго метода. 🙂


BlackTiger ( 2004-01-09 16:20 ) [30]

Чёй-то вы фигней тут, имхо, занимаетесь. ProcessMessages использовать НУЖНО, но только там, где нужно. Сколько раз мне помогал его VB-аналог «DoEvents»!

Он помогает НЕ ЗАВЕШИВАТЬ приложение (точнее его интерфейс) при большом количестве итераций или при медленных итерациях в цикле.


Тимохов ( 2004-01-09 16:27 ) [31]

BlackTiger © (09.01.04 16:20) [30]

Про «занимаетесь фигней», имхо считаю, что Вы не тактичны. Считаю, что скорее фигней занимаетесь Вы т.к. повотрили неоднократно выше приведенное утверждение.


Fantasist ( 2004-01-10 02:27 ) [32]


> использовать ProcessMessages можно, но осторожно.

Использовать потоки можно, но осторожно. Использовать RPC
можно, но осторожно. Использовать dll»ки можно, но осторожно.

Программировать можно, но осторожно. Ибо проблему можно создать везде, если не понимаешь с чем работаешь.


olookin ( 2004-01-10 10:26 ) [33]

(а почему ветка до сих пор не в Потрепаться? «Последняя половина» сообщений принимает характер личного обсуждения. )


Вован_ ( 2004-01-10 12:01 ) [34]

Источник

Сказочный портал