Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.68/50: Рейтинг темы: голосов - 50, средняя оценка - 4.68
 Аватар для Jafa
51 / 51 / 13
Регистрация: 05.06.2008
Сообщений: 139

Анимация ожидания

17.05.2010, 01:04. Показов 10812. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У меня в приложении есть длительные процессы, например подключение к удаленной базе данных, обычно в таких случаях я вывожу надпись типа "ждите", в этот раз я решил вывести gif-анимацию в TImage, но она во время выполнения процесса останавливается, пробовал играться с дочерним процессом - тоже не помогло, может кто подскажет как ее оживить во время выполнения процесса?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.05.2010, 01:04
Ответы с готовыми решениями:

Потоки и таймеры ожидания
Есть вот такая задача: Пользователь задает список, каждый элемент которого включает дату и время. Количество (пар дата / время) не...

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

Анимация ожидания
Здравствуйте! В приложении работаю с Picasso, на загрузке стоит заглушка ,можно поменять png на gif? Если да, то как? При прямолобной...

30
3 / 3 / 1
Регистрация: 31.01.2010
Сообщений: 10
17.05.2010, 17:33
Через поток делать надо.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
03.02.2011, 09:31
У меня такая же постановка задачи, но мне нужно вывести не просто картинку, а анимацию в иконке окна (то, что в левом верхнем углу, если неправильно обозвал). Ну и нарыл похожую тему: Анимация кнопки через ресурсы

1. Почему рекомендуют делать анимацию через поток? Ведь работать с VCL-компонентами через поток нельзя. Точнее, можно (ибо кто запретит), но код при этом может подглючивать.
2. Какая всё-таки общая технология? Работать по таймеру и обновлять ручками? Случай, когда приложение ничего не делает и просто рисует анимационный gif через TGIFImage я не рассматриваю, ибо постановка задачи сводится к прорисовке анимации на фоне работы программы. Мне казалось, что правильным было бы "долгий" процесс пустить в потоке, а отрисовку анимации делать в главном процессе по таймеру. Можно и не по таймеру, а через интерфейсы ожидания завершения потока по таймауту (где можно более точно настраивать интервалы, чем с таймером) - принципиальной роли нет. Суть в том, что отрисовка делается ручками через интервалы времени. Или всё-таки есть какие-то продвинутые методы (а то и встроенные)?
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
03.02.2011, 13:21
1. ProgressBar
2. Запуск анимации в цикле в соответствии с какими-то параметрами выполняемого действия и break; по условию по окончании оного.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
03.02.2011, 13:36
LK, ты точно понял постановку вопроса?
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
03.02.2011, 14:24
Да, а ты ?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
03.02.2011, 14:26
Цитата Сообщение от LK Посмотреть сообщение
Да, а ты ?
Свои вопросы я обычно понимаю. Или ты отвечалне мне?
0
03.02.2011, 14:31

Не по теме:

Тогда ты спрашивал не у меня :) .

0
Эксперт С++
 Аватар для MikeSoft
3957 / 1812 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
03.02.2011, 15:14
Цитата Сообщение от Evg Посмотреть сообщение
Ведь работать с VCL-компонентами через поток нельзя. Точнее, можно (ибо кто запретит), но код при этом может подглючивать.
Никаких "подглючиваний" не будет, если код чётко и правильно выполняет поставленную цель.

Цитата Сообщение от Evg Посмотреть сообщение
Почему рекомендуют делать анимацию через поток?
Потому что при использовании постоянной отрисовки в основном потоке будет только одна особенность: полная потеря производительности.

Теперь, что касается обновления канвы из потока.
Да, Canvas изначально создан, как потоконебезопасный, но это не должно останавливать программиста в его использовании.
Есть методы Lock, TryLock, Unlock, LockCount, которые позволяют устанавливать, снимать и получать состояние блокировки.
Зачем нужна такая блокировка? Изменение содержимого должно происходить только из одного потока.
При установке блокировки обновление из других потоков запрещается.

Пример использования:
C++
1
2
3
4
5
if (Canvas->TryLock()) {
  DrawTestRect(Canvas,Width,Height);
  DrawText(Canvas,Width,Height,IntToStr(MainControl->LoadPercent) + "% Percent Complete...");
  Canvas->Unlock();
}
Для того, чтобы было наглядное представление я набросал минимальное приложение, в котором идёт цикл заполнения массива случайными числами, в то время как другой поток перерисовывает небольшой рисунок. Проект прикрепляю (создан в RAD Studio XE).
Вложения
Тип файла: rar ProgressShow.rar (565.8 Кб, 164 просмотров)
3
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
03.02.2011, 15:34
Висит на 98%, Вынь7.
0
Эксперт С++
 Аватар для MikeSoft
3957 / 1812 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
03.02.2011, 15:39
LK, у меня нормально отрабатывает, проверял на WinXP и Win7.

Собственно говоря, из этого проекта нужно подчеркнуть только работу с канвой из потока, для этого я его и набросал.
1
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
03.02.2011, 15:45
MikeSoft, я понял . Просто запустил, посмотрел, за запусков десять только один раз таск_комплит, вот и написал, исходники не смотрел пока, но вещь нужная .
0
Эксперт С++
 Аватар для MikeSoft
3957 / 1812 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
03.02.2011, 15:48
LK, если найдёте ошибки - пишите или в ЛС, или в этой теме.


Также, в исходник можно добавить проверку количества блокировок с помощью чтения свойства LockCount.
Если LockCount равен нулю - остальные потоки имеют право изменять содержимое.
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
03.02.2011, 15:53
Цитата Сообщение от MikeSoft Посмотреть сообщение
LK, если найдёте ошибки - пишите или в ЛС, или в этой теме.
- уж не сомневайтесь, уважаемый MikeSoft .
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
03.02.2011, 17:21
MikeSoft, в параллельной теме высказал свои соображения: https://www.cyberforum.ru/post1339292.html Т.е. я был неправ или как?

Всякие TryLock и прочее - а внутри кодов VCL это делается или не делается? Потому что если при перерисовке каждой компоненты будет постояно делать lock-unlock, то это пипец какие накладные расходы получаются

Цитата Сообщение от MikeSoft Посмотреть сообщение
Потому что при использовании постоянной отрисовки в основном потоке будет только одна особенность: полная потеря производительности.
Какая разница, производительность будет в потоке теряться или в главном процессе? Мне вообще казалось, чтоглавный процесс должен только gui обслуживать, а вся "тяжёлые" процессы исполняться в потоке. Потому что в противном случае в момент выполнени долгого процесса ты окно даже перетащить не сможешь, потому что главный процесс у тебя висит на рассчёте. Либо я что-то не так понимаю

Добавлено через 24 минуты
Цитата Сообщение от MikeSoft Посмотреть сообщение
Для того, чтобы было наглядное представление я набросал минимальное приложение, в котором идёт цикл заполнения массива случайными числами, в то время как другой поток перерисовывает небольшой рисунок. Проект прикрепляю (создан в RAD Studio XE).
Собственно такая реализация меня как раз НЕ устраивает. Если в процессе подсчёта начать, к примеру, перетаскивать окно, то подсчёт остановится. Из-за Application->ProseccMesages. А теперь вместо подсчёта поставь sleep(5) для эмуляции, к примеру, прокачивания данных из сети, или работу с удалённой базой данных, где нельзя (а точнее, негде) дёрнуть Application->ProseccMesages - получим программу с тормозящим GUI: пока мы висим на "долгом" процессе скачивания, программа не реагирует на внешние раздражители. Именно поэтому я считаю, что долгие вычисления должны делаться в потоке, а обслуживанием gui должен заниматься главный процесс

Добавлено через 4 минуты
Цитата Сообщение от Evg Посмотреть сообщение
sleep(5)
Ну или что там правильно подать. Я имел в виду задержку на 5 секунд

Добавлено через 5 минут
И вот ещё, немного отвлечённый вопрос. У Canvas есть методы TryLock и прочее. Но ведь у самих компонент этого нет. Т.е. если к примеру, было бы нужно обновить из потока свойства кнопки или ещё что-то, то лочить нечего. Или фишка именно в том, что проблемы из потока могут возникнуть именно с Canvas'ом, и обусловлены они возможно перерисовкой компоненты по тем или иным событиям из главного потока?

И ещё одно. Invalidate что делает?
0
Эксперт С++
 Аватар для MikeSoft
3957 / 1812 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
03.02.2011, 17:40
Цитата Сообщение от Evg Посмотреть сообщение
MikeSoft, в параллельной теме высказал свои соображения: https://www.cyberforum.ru/post1339292.html Т.е. я был неправ или как?
По поводу "серого квадратика" - явно в коде где-то ошибка была.
По поводу StringGrid'a - неплохо было бы увидеть описанный пример.

Цитата Сообщение от Evg Посмотреть сообщение
Какая разница, производительность будет в потоке теряться или в главном процессе?
При выполнении в главном потоке будет задержка на время отрисовки.
В случае с отдельным потоком будет имитирована псевдопараллельность (с учётом приоритета потока и других факторов и ограничений, существующих в железной части, прорисовывающихся в ОС).
Собственно говоря, из-за такой семафорной псевдопараллельности и возникают неприятные нюансы при доступе к некоторым объектам. Кстати говоря, для решения подобных проблем придумали ещё критические секции (TCriticalSection).

Цитата Сообщение от Evg Посмотреть сообщение
Потому что в противном случае в момент выполнени долгого процесса ты окно даже перетащить не сможешь, потому что главный процесс у тебя висит на рассчёте.
Хе... ну так извини меня, подход кто будет продумывать?
Нужно же разработать бизнес-логику, продумать, где тебе необходимо отдавать приоритеты графической части, а где заставить процессор перегреваться от постоянной "калькуляции"...

Нужен нетормозящий подсчёт и прорисовка? Два потока, минимальные изменения и готово (проект в аттаче).
Вложения
Тип файла: rar ProgressShow.rar (570.2 Кб, 52 просмотров)
1
Эксперт С++
 Аватар для MikeSoft
3957 / 1812 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
03.02.2011, 17:48
Цитата Сообщение от Evg Посмотреть сообщение
Т.е. если к примеру, было бы нужно обновить из потока свойства кнопки или ещё что-то, то лочить нечего.
Кнопка не имеет графического места для рисования, поэтому, ей и WM_SETTEXT вполне хватит.
Изображения, которые присутствуют на "дополненных экземплярах" (таких, как TSpeedButton и других) также отрисовываются на канве.
К проблемным местам потоков относятся все части приложения, которые способны перерисовываться, но не могут следить за правами доступа. Здесь уж проблема в том, что защитные механизмы либо плохо освещаются, либо плохо реализованы ("плохо" - с точки зрения интуитивной доступности).

Цитата Сообщение от Evg Посмотреть сообщение
И ещё одно. Invalidate что делает?
Invalidate сообщает системе, что необходимая область компонента недействительна и нуждается в перерисовке. Границы можно задавать через InvalidateRect.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
03.02.2011, 18:16
Цитата Сообщение от MikeSoft Посмотреть сообщение
При выполнении в главном потоке будет задержка на время отрисовки
Вот именно потому я и считаю, что главный процесс должен только отрабатывать gui и делать какие-то "лёгкие" вещи (заблокировать кнопку, изменить изображение на кнопке и т.п.) - т.е. НЕ счётные и НЕ висящие (сетевые и тому подобное) задачи

Цитата Сообщение от MikeSoft Посмотреть сообщение
Хе... ну так извини меня, подход кто будет продумывать?
Я и предложил подход - полезные дела делать в потоке, а гуёвые - в главном процессе. Хочу понять, это "правильный" подход (или хотя бы "хорошоий") или нет?

Цитата Сообщение от MikeSoft Посмотреть сообщение
Два потока, минимальные изменения и готово (проект в аттаче)
Ну вот у тебя практически пришли к тому же самому. Счётная подзадача ушла в поток. Теперь есть ещё и графическая подзадача - "тяжёлая прорисовка", которую действительно нужно отправлять в поток. Собственно, за познания про Canvas->Locak и иже с ним - спасибо. В будующем пригодится.

Но в настоящем у меня нет "тяжёлой" прорисовки. У меня есть лёгкая прорисовка - грубо говоря 5 раз в секунду обновить иконку окна. Картинка маленькая, задержки между прорисовками большие (сотни миллионов тактов). Я правильно понимаю, что при таком раскладе нормальным (а то и оптимальным) решением будет обновление картинки по таймеру в главном процессе? Т.е. пример по сути дела твой, но вместо второго потока (который "графический") будет таймер в главном процессе

Цитата Сообщение от MikeSoft Посмотреть сообщение
Кнопка не имеет графического места для рисования
Но как-то же она прорисывывается при перерисовке окна? Хотя ладно... щас это неважно, а то уйдём ещё далеко в дебри

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

Цитата Сообщение от MikeSoft Посмотреть сообщение
Invalidate сообщает системе, что необходимая область компонента недействительна и нуждается в перерисовке. Границы можно задавать через InvalidateRect
Вот это я и никак не могу понять. Что значит "недействительна и нуждается в прорисовке"?

Добавлено через 2 минуты
Цитата Сообщение от MikeSoft Посмотреть сообщение
По поводу StringGrid'a - неплохо было бы увидеть описанный пример
Примера нет, потому что, как уже писал, от таких действий избаился. Но всё росло из читерской реализации разноцветного Grid'а (пример из инета, который раздублирован на мильёне сайтов, базируется на OnDrawCell, или как онотам правильно называется). В чём конкртено была проблема - толком не помню. Но просто тот факт, что при прорисовке из потока возбуждалось событие в главном процессе, меня тогда поставило в тупик каким-то неочевидным из этого следствием
0
Эксперт С++
 Аватар для MikeSoft
3957 / 1812 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
03.02.2011, 20:41
Цитата Сообщение от Evg Посмотреть сообщение
Я и предложил подход - полезные дела делать в потоке, а гуёвые - в главном процессе
Если так посудить, обновление изображения в Image - тоже дело главного потока. А может вылиться в проблему.
Я с этой проблемой столкнулся, когда разрабатывал систему удалённого управления рабочими станциями.
Сначала подумал: получение изменившегося участка изображения + его отрисовка = должно занять время, не меньшее, чем 7-20 мс. Ну и думаю: заставлю-ка я главный поток активировать объект класса TTimer, в котором и сделаю прорисовку нужного региона, заодно и не буду мучатся с блокировками канвы. Так и сделал! В итоге, были заметны явные "рывки" при активации таймера, тратилось время на создание потока, на его остановку... после чего у меня у меня возник вопрос: "А зачем мне все эти прелести?". Оформил отдельный поток и проблема исчезла.
Цитата Сообщение от Evg Посмотреть сообщение
У меня есть лёгкая прорисовка - грубо говоря 5 раз в секунду обновить иконку окна. Картинка маленькая, задержки между прорисовками большие (сотни миллионов тактов). Я правильно понимаю, что при таком раскладе нормальным (а то и оптимальным) решением будет обновление картинки по таймеру в главном процессе?
Оптимальным, думаю, такое решение не будет. Почему - объяснил выше.
Но в целом - подход нормальный, меньше возни с блокировками, но чуть большая нагрузка, а если учитывать, что операция не такая уж и ёмкая - то решение: использовать можно

Цитата Сообщение от Evg Посмотреть сообщение
Вот это я и никак не могу понять. Что значит "недействительна и нуждается в прорисовке"?
Заставить обновить указанную область при следующем поступлении сообщения WM_PAINT.

Цитата Сообщение от Evg Посмотреть сообщение
Примера нет, потому что, как уже писал, от таких действий избаился. Но всё росло из читерской реализации разноцветного Grid'а (пример из инета, который раздублирован на мильёне сайтов, базируется на OnDrawCell, или как онотам правильно называется).
Я так подозреваю, что-то похожее на это: Прорисовка чекбоксов в ListView.
Но опять же, мне сложно представить проблему... обидно, что нет примера, интересно было бы посмотреть, разобраться.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
03.02.2011, 22:15
Цитата Сообщение от MikeSoft Посмотреть сообщение
Так и сделал! В итоге, были заметны явные "рывки" при активации таймера, тратилось время на создание потока, на его остановку... после чего у меня у меня возник вопрос: "А зачем мне все эти прелести?". Оформил отдельный поток и проблема исчезла
Поток будет создаваться в любом случае. Скачивание данных из инета - только через поток и никак больше. Точнее, можно как-то с неблокируемыми сокетами, но в таком коде быстро утонешь, особенно когда несколько соединений. Поэтому "тратилось время на создание потока" к делу особенно не относится. Надо будет поэкспериментировать, но не думаю, что будут рывки.

Да, забыл сказать. Суть то в чём. Данные слизываются из инета в потоке, а затем просто отображаются в таблицу на форму. Отображение на форму уже выполняется в главном процессе. Такой вариант, как удержание постоянного соединения в моём случае отсутствует. Что-то не подумал о том, что сие надо рассказать, дабы понималось, о чём идёт речь. Короче, в моём случае главная форма занимается только отрисовкой таблички, обслуживением меню, галочек-кнопочек и т.п. Т.е. вот примерно в такой модели всё это дело требуется

Цитата Сообщение от MikeSoft Посмотреть сообщение
Заставить обновить указанную область при следующем поступлении сообщения WM_PAINT
"Недействительная" - имелось в виду то, что текущее графическое изображение недействительно?

Цитата Сообщение от MikeSoft Посмотреть сообщение
обидно, что нет примера, интересно было бы посмотреть, разобраться
Да вот как-то не думал о том, что "неправильные" решения тоже надо бы сохранять. Да и лениво было бы: по-хорошему пришлось бы отрезать часть проекта, минимально необходимую для воспроизведения ситуации

Добавлено через 1 минуту
Цитата Сообщение от MikeSoft Посмотреть сообщение
Я так подозреваю, что-то похожее на это: Прорисовка чекбоксов в ListView.
Там была ссылка на тему со StringGrid'ом - по сути одна из модификаций этого самого. Только обновление (вызов RePaint, или как там оно) шёл из потока

Добавлено через 1 час 10 минут
Попробовал с ручным обновлением иконки из главного процесса. Действительно, если начать перетаскивать окно, то можно наблюсти некоторое торможение. И оно понятно - при перетаскивании мышкой окна постоянно фигачат события по перерисовке, а потому события от таймера приходят не вовремя.

Решил сравнить с двумя приложенными кодами ProgressShow. У меня Windows 7 Home Basic (32)

Первый код как-то ещё работает, однако если в процессе рассчётов нажать на крестик (закрытие формы), то реакции нет и окно закрывается только по окончании подсчёта. Заметны периодические мерцания (за всё время 2-3 раза какое-то мерцание, как будто форма вся затёрлась и перерисовалась заново). Если потаскать окно в процессе рассчёта, то при повторном нажатии StartProgress программа попросту перестаёт работать (обновлять содержимое окна), а если её подвинуть, то содержимое вообще стирается

Во втором варианте (когда два потока) вообще не работает. При нажатии на "Start" отображается счётчик 0, а потом тишина. По завершении расчёта кнопка появляется снова, но содержимое окна так и осталось неперерисованным.

Для полного счастья надо бы этот же вариант программы, но чтобы вся перерисовка шла из главного процесса (без потоков). Чисто чтобы понять, проблема из-за прорисовки в потоке, или компилятор нагенерил код, который по каким-то причинам коряво работает под Windows 7
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.02.2011, 22:15
Помогаю со студенческими работами здесь

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

Анимация ожидания ответа запроса от сервера
Помогите ребят Нигде не могу найти как сделать анимацию Допустим я ввожу логин и пароль Нажимаю кнопку В то время пока запрос...

Анимация ожидания ответа ajax запроса
Можно ли сделать анимацию загрузки такую как на этом видео: тыЦ это анимация из samsung touchwiz android 5.0 Как сделать такую на...

Анимация ожидания Ajax ответа на кнопках
Добрый вечер форумчане. Захотелось сделать универсальную функцию: после нажатия на кнопку (ДАННУЮ), сменить его содержимое анимацией, а...

Анимация в OpenGL, а где собсно, анимация?
// Bounce.cpp // Demonstrates a simple animated rectangle program with GLUT // OpenGL SuperBible, 3rd Edition // Richard S. Wright...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru