![]() |
Модераторы: Snowy, MetalFan, bems, Poseidon |
![]() ![]() ![]() |
|
boobie |
|
||||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 162 Регистрация: 16.9.2011 Репутация: нет Всего: нет |
Здравствуйте! Как заставить программу понимать одновременное нажате двух и более клавиш? Т.е. задача, например, такая: 9 (например) Label-ов, при нажатии на клавишу "1" - происходит
при нажатии на "2":
и так далее... При одновременном нажатии на 1 и 3 и 6, например, к соответствующему label-у "прибавляется" 1, 3, 6. Вот код моего решения на примере двух label-ов:
Я создал 2 потока, каждый поток использует функцию getasynckeystate() чтобы определить клавишу, нажатую в данный момент. Если нажата нужная - выполняем изменение строки. 1. Можно ли как-нибудь обойтись без getasynckeystate(), а только силами TForm1.FormKeyPress(Sender: TObject; var Key: Char)? Как сделать так, чтобы данная процедура стала как-бы многопоточной? 2. Обработать нажатие более 3 клавищ в данном случае не получится? |
||||||||
|
|||||||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 22 Всего: 72 |
SetWindowsHookEx + WH_KEYBOARD_LL + google должно помочь
![]() Потоки не нужны. Обращение к визуальным компонентам из потока = глюк, баг и иже с ними. Добавлено через 1 минуту и 34 секунды это в том случае, если нужно ловить клавиши вне зависимости от активности своего окна. |
|||
|
||||
boobie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 162 Регистрация: 16.9.2011 Репутация: нет Всего: нет |
Я изучаю работу потоков... Сам придумываю такие вот задачки...
КАК? ПОЧЕМУ? И что, простейшие программки (любую простенькую игрушку, типа "Морской бой" или простейшую коммерческую прогу) писать на WinApi? На**** зачем тогда VCL нужна в таком виде? |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 22 Всего: 72 |
Я, наверное, не совсем корректно написал. Потоки не нужны в рамках рассматриваемой задачи, тут вполне справится VCL-поток самостоятельно. Если же рассматривать работу потоков "в общем", то мое высказывание
остается в силе. В потоке можно осуществлять дополнительные действия, производить вычисления и т.д. Результат работы потока (промежуточный или окончательный) в основной поток нужно сообщать (или забирать самостоятельно) каким-либо из потокобезопасных методов. Простейшим для начала будет TThread.Synchronize. Но он далеко не единственный и далеко не оптимальный. Хотя - смотря какая задача. Добавлено через 1 минуту и 34 секунды Не надо так категорично ![]() ![]() |
|||
|
||||
Poseidon |
|
||||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 9 Всего: 133 |
Начните изучение потоков вот с этой статьи: Многопоточность - как это делается в Дельфи -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
||||
|
|||||
boobie |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 162 Регистрация: 16.9.2011 Репутация: нет Всего: нет |
Т.е. для обращения к компонентам VCL нужно использовать один из способов синхронизации потоков? Исользовать метод Synchronize, критическую секцию или что-нибудь в этом роде?
Получается, что вся проблема состоит в синхронизации потоков? И только по этой причине нельзя использовать визуальные компоненты в многопоточном приложении? Способов синхронизации потоков достаточно много...
Да, похоже это единственная статья о многопоточности на весь рунет. ![]()
Это сообщение отредактировал(а) boobie - 23.5.2013, 10:53 |
||||
|
|||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 22 Всего: 72 |
нет. Критические секции в этом случае, как и (например) мьютексы не пойдут. К визуальным компонентам можно обращаться только из своего, VCL- потока. Т.е. - Synchronize или (к примеру) собственные аналоги на Send|PostMessage. Я в последнее время перешел на SendMessageTimeout с SMTO_BLOCK. |
|||
|
||||
boobie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 162 Регистрация: 16.9.2011 Репутация: нет Всего: нет |
kami, спасибо, теперь понятно. Т.е. Synchronize необходим для любого обращения к визуальному компоненту из потока. Критические секции, семафоры и мьютексы - синхронизация потоков.
WinApi? Чем Synchronize так плох? |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 22 Всего: 72 |
Он не позволяет передать параметры вызываемому. А в SendMessage я могу запихать всё, что угодно, включая объекты. Смесь ![]() Добавлено через 4 минуты и 51 секунду да, и самое главное забыл - SMTO_BLOCK не допустит вложенного вызова, а с синхронайзом такое возможно. |
|||
|
||||
boobie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 162 Регистрация: 16.9.2011 Репутация: нет Всего: нет |
Хорошо. А как заставить каждый поток обрабатывать нажатие клавиш? Только с помощью getasynckeystate() и других winapi функций?
Дело в том, что потоки будут обрабатывать любое нажате клавиши, вне зависимости от фокуса ввода. Это сообщение отредактировал(а) boobie - 23.5.2013, 14:11 |
|||
|
||||
Poseidon |
|
||||||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 9 Всего: 133 |
Очень плохо прочли, либо не внимательно. Еще раз просмотрите главу 3. И очень внимательно раздел "Дополнительные проблемы с VCL." Судя по вопросам, Вы эту статью бегло просмотрели, а не прочли. Досканальное изучение этой статьи отбросит 99% возможных вопросов по потокам. И не нужно будет выдумывать нереальных задач. -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
||||||
|
|||||||
boobie |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 162 Регистрация: 16.9.2011 Репутация: нет Всего: нет |
Да, только после публикации темы понял зачем нужен метод Synchronize.
Вот код с учетом ошибок и примененным методом Synchronize:
Код формы:
Но вопросы остались без ответа ![]() |
||||
|
|||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 22 Всего: 72 |
Без какого ответа? Да, в потоках неприменимы всякие OnKeyPress и т.п. В той же статье пишется, что не стоит плодить потоки только ради потоков. Ну какой смысл в обработке несколькими потоками одного и того же? У каждого из них будет уникальный алгоритм обработки? Имхо, вполне достаточно будет VCL-потока и |
|||
|
||||
boobie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 162 Регистрация: 16.9.2011 Репутация: нет Всего: нет |
Хорошо, все ясно. Просто я изучаю потоки, для наглядности решил сделать так...
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |