![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вопрос про GetKeyState [D6]
Суслик © (2005-11-14 15:45:00)Добный день.
1. При получении контролом фокуса мне нужно определить, каким образом к нему попал фокус. Мне нужно вычленить случаи получения фокуса по TAB и по SHIFT+TAB. Получение фокуса иными способами (мышь, CTRL+TAB, ALT+TAB и пр. не интересуют).
В обработчике сообщения WM_SETFOCUS я пытался делать так
if (GetKeyState(VK_TAB) < 0)
and (GetKeyState(VK_CONTROL) >= 0)
and (GetKeyState(VK_MENU) >= 0) then
begin
Forward := GetKeyState(VK_SHIFT) >= 0; (**)
end;
В итогде переменная Forward содержит true, если фокус получен по tab и false - по shift+tab.
При тестировании обнаружил, что иногда (не всегда) управление доходит до строки (**) если я нажимал alt+tab. При детальном анализе действия своих рук понял, что я alt отпускаю несколько раньше, чем управление доходит до проверки GetKeyState(VK_MENU) >= 0.
2. Почитав про GetKeyState я не понял (наверное, трудности перевода) в какой момент определяется значение GetKeyState. Точно не в момент вызова (для этого есть другая функция GetAsyncKeyState).
Вопросы:
1. Как решить задачу из п. 1?
2. В какой момент определяется значение GetKeyState?
Спасибо.
Игорь Шевченко (2005-11-18 12:11:00) [21]Суслик © (18.11.05 11:35) [13]
А разве обычный грид с включенными опциями goTabs и goAlwaysShowEditor ведет себя не так, как тебе надо ?
Суслик (2005-11-18 11:35:00) [22]
> Вообще, если только два контрола, следет ли отличать направление
> ?
Надо.
ДЛЯ ВСЕХ поясню еще раз задачу.
1. Есть некое извращение, в котором прощу коллег помочь.
2. Представьте себе контрол (некий СВОЙгрид), который некоторыеячейки прорисовывает функцией winapi DrawFrame таким образом, что он внешне НЕ ОТЛИЧИМЫот TEdit.
3. Т.е. при взгляде на grid кажется как будто на нем набросано несколько TEdit, хотя реально TWinControl один - сам Grid.
4. В отношении редактирования ячеек мой грид организован также как TStringGrid - есть InplaceEdit. При входе на ячейку, которая редактируема (и, как было сказано в п.2 внешне неотличима от TEdit) появлятеся InplaceEdit.
5. При этом есть желание клавиши TAB и SHIFT+TAB заставить работать внутри грида таким образом, что как будто редактируемые ячейки не просто прорисованы как TEdit, а TEdit'ом и является, т.е. получают фокус по TAB и SHIFT+TAB.
6. Перемещение по TAB не представляет проблем. Для этого гриду достаточно обрабатывать:
* WM_GETDLGCODE, возвращая DLGC_WANTTAB,
* KeyDown - при нажатии на vk_tab искать следующую (вправо вниз или влево вврех, если shift+tab) редактируему ячейку. Если дошли до конца то вызывать SelectNext.
7. В итоге получает полнейшая имитация TEdit'ов. Т.е. внешне отличить мое творчество от группы TEdit'ов сложно.
8. Но есть одно НО. В случае получения gridом фокуса хотелось бы знать спереди или сзади он пришел. Если спереди, то нужно фокусировать редактируемую первую ячейку, если сзади, то последнюю.
Задача состоит в том, чтобы как гарантировано понять, что фокус пришел спереди или сзади, т.е. по TAB или по SHIFT+TAB?
PS. Т.к. смену фокуса делает родительская форма в CMDialogKey, то можно было бы написать своего потомка формы. Но хотелось бы обойтись без этих извращений. Т.е. направление фокуса должен уметь определять сам грид.
Заранее огромное спасибо за ответ.
GuAV (2005-11-17 20:00:00) [23]
> но если подумать, то это способ не работает в случае
> когда всего два контола, способных получать фокус.
В продолжение извращений, можно создать невидимый контрол, в его обработчике SETFOCUS передавать фокус далее, направление определять этим же способом. Чтобы это работало при наличии только одного грида, делать таких контролов два.
Вообще, если только два контрола, следет ли отличать направление ?
=======
- Что это вы мне принесли - борщ или помои ?
- А вы что, сами не можете определить ?
- Нет !
- Тогда какая вам разница ?
Суслик (2005-11-17 11:12:00) [24]я сначала так и сделал :) рад был!
но если подумать, то это способ не работает в случае когда всего два контола, способных получать фокус.
GuAV (2005-11-16 21:01:00) [25]В WM_SETFOCUS передаётся бывший владелец фокуса как параметр.
Т.е. можно использовать разность TabOrder для определения направления смены фокуса.
Leonid Troyanovsky (2005-11-14 17:04:00) [26]
> Суслик © (14.11.05 16:50) [6]
> смысл в имитации, как будто редактируемые поля сделаны отдельностоящми
> editaми, тогда как они сделаны посредствов специальной прорисовки
> ячеек + inplace editor в момент перехода к ячейке.
А..
Может я опять не понял, но тебе нужна собс-ная реализация Editor.
А раз так, то надо погуглить CreateEditor TInplaceEdit and so on.
--
Regards, LVT.
Игорь Шевченко (2005-11-14 16:56:00) [27]Суслик © (14.11.05 16:50) [6]
А эта...если в обычном гриде поставить AlwaysShowEditor то вроде будет аналогичное поведение ? Заодно и посмотри, как там сделано.
Или объясни подробнее, а то, честно говоря, непонятно.
Leonid Troyanovsky (2005-11-14 16:55:00) [28]
> Суслик © (14.11.05 16:32) [4]
> OnSelectCell тут проде ни при чем. Мне как раз надо клавиатурой.
Дык, фокус перемещенный клавиатурой с другого контрола
OnSelectCell не вызовет.
> из описания GetKeyState. Т.е. значение GetKeyState определяется
> в момент вызова GetMessage или PeekMessage? И если поток
> не читает очередь, то значение GetKeyState не меняется?
Ну, если не читает, то и не меняется.
Только, то время, когда какие-то изменения имели место, например,
при изменении фокуса (путем нажатия Tab), как раз подходит для
GetKeyState (vs GetAsyncKeyState).
--
Regards, LVT.
Суслик (2005-11-14 16:50:00) [29]смысл в имитации, как будто редактируемые поля сделаны отдельностоящми editaми, тогда как они сделаны посредствов специальной прорисовки ячеек + inplace editor в момент перехода к ячейке.
Это сейчас уже есть - внешне не отличишь. Но вот то,что перебор по tab и shift+tab работает неверно выдает подмену.
Игорь Шевченко (2005-11-14 16:38:00) [30]Суслик © (14.11.05 16:16) [2]
Про то, что есть грид, я понял. А вот дальше увы не понял, какой именно смысл узнавания каким образом грид получил фокус.
Суслик (2005-11-14 16:32:00) [31]OnSelectCell тут проде ни при чем. Мне как раз надо клавиатурой.
bad-bad design. Согласен.
Я даже почти от этого отказался.
Вообще вопрос стал уже более теоретический. С какой момент определяется результат выполнения GetKeyState. Насколько я понимаю все кроется в этой фразе
The key status returned from this function changes as a thread reads key messages from its message queue.
из описания GetKeyState. Т.е. значение GetKeyState определяется в момент вызова GetMessage или PeekMessage? И если поток не читает очередь, то значение GetKeyState не меняется?
Leonid Troyanovsky (2005-11-14 16:28:00) [32]
> Суслик © (14.11.05 16:16) [2]
> 5 Хочу сделать так, чтобы при попадании фокуса на грид выбиралась
> нужная ячейка - либо первая с конца, либо первая сначала.
OnSelectCell (сработает, если мышью).
Хотя, все это смахивает на bad design.
Если, конечно, я чего-то понял.
--
Regards, LVT.
Суслик (2005-11-14 16:16:00) [33]можно.
1 Есть грид (свой, но по мотивам TCustomGrid)
2 В гриде есть inplace editor.
3 Editor появляется только в момент редактирования ячейки.
4 Визуально ячейка, в которой может появить editor выглядит неотличимо от editor (т.е. рисуется с такой же рамкой).
5 Хочу сделать так, чтобы при попадании фокуса на грид выбиралась нужная ячейка - либо первая с конца, либо первая сначала.
Игорь Шевченко (2005-11-14 16:08:00) [34]
> 1. При получении контролом фокуса мне нужно определить,
> каким образом к нему попал фокус. Мне нужно вычленить случаи
> получения фокуса по TAB и по SHIFT+TAB.
Можно узнать, зачем требуется определить, как попал фокус ?