Re[12]: Программное переключение keyboard layout
От: CEMb  
Дата: 21.11.12 16:15
Оценка: 9 (1)
Здравствуйте, Carc, Вы писали:

CEM>>Не, там совсем вроде без хука, хотя написано что это типа как хук(так и есть, но) там события посылаются мессаджами подписанному окну. Т.е. не надо писать отдельную функцию для хука. Я у себя эту штуку внедрил сразу, программа сразу стала легче и шустрее(та, которая в соседней ветке).

C>Я про это и говорю: там в общем сводилось всё что-то вроде RegisterWindowMessage ("Чего_то_Shell_Hook_дай_мне_зараза_строка_вроде") и получаем сообщения в оконную. Но!!!

Эээ, стоп, погоди, к RegisterWindowMessage или всё-таки RegisterShellHookWindow? Вторая, которую я использовал, задокументирована и с ней вроде всё ок с 5-й НТи. Или вторая как-то сводится к первой?
Я ещё не зарелизился, но уже насторожился
Re[13]: Программное переключение keyboard layout
От: Carc Россия http://www.amlpages.com/home.php
Дата: 22.11.12 04:42
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Здравствуйте, Carc, Вы писали:


CEM>>>Не, там совсем вроде без хука, хотя написано что это типа как хук(так и есть, но) там события посылаются мессаджами подписанному окну. Т.е. не надо писать отдельную функцию для хука. Я у себя эту штуку внедрил сразу, программа сразу стала легче и шустрее(та, которая в соседней ветке).

C>>Я про это и говорю: там в общем сводилось всё что-то вроде RegisterWindowMessage ("Чего_то_Shell_Hook_дай_мне_зараза_строка_вроде") и получаем сообщения в оконную. Но!!!

CEM>Эээ, стоп, погоди, к RegisterWindowMessage или всё-таки RegisterShellHookWindow? Вторая, которую я использовал, задокументирована и с ней вроде всё ок с 5-й НТи. Или вторая как-то сводится к первой?

CEM>Я ещё не зарелизился, но уже насторожился
О!!! Век живи, век учись. А я это про эту новую приблуду RegisterShellHookWindow и не знал даже... Похоже они в 2К сделали документированный фасад к внутренней возможности. Сие уже совершенно друго-о-о-ое дело!
СПАСИБО за инфу!

Но кстати похоже что она, эта новая функция, по сути и делает то, что делала старая. Там тоже было надо регнуть мессагу через RegisterWindowMessage и именно с ней и получать инфу о смене языка... Я так, навскидку, строку для RegisterWindowMessage не помню, но что-то вроде того там и юзалось!
Aml Pages Home
Re[13]: Программное переключение keyboard layout
От: Carc Россия http://www.amlpages.com/home.php
Дата: 22.11.12 12:54
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Здравствуйте, Carc, Вы писали:


CEM>>>Не, там совсем вроде без хука, хотя написано что это типа как хук(так и есть, но) там события посылаются мессаджами подписанному окну. Т.е. не надо писать отдельную функцию для хука. Я у себя эту штуку внедрил сразу, программа сразу стала легче и шустрее(та, которая в соседней ветке).

C>>Я про это и говорю: там в общем сводилось всё что-то вроде RegisterWindowMessage ("Чего_то_Shell_Hook_дай_мне_зараза_строка_вроде") и получаем сообщения в оконную. Но!!!

CEM>Эээ, стоп, погоди, к RegisterWindowMessage или всё-таки RegisterShellHookWindow? Вторая, которую я использовал, задокументирована и с ней вроде всё ок с 5-й НТи. Или вторая как-то сводится к первой?

CEM>Я ещё не зарелизился, но уже насторожился
Вот что подозрительно...
В описании RegisterShellHookWindow нет славного и столь нужного параметра HSHELL_LANGUAGE, коий явно присутствует в hook-функции для ShellHook. Так что получится ли так отловить смену языка таким образом — непонятно!?! Настораживает это однако
Aml Pages Home
Re[14]: Программное переключение keyboard layout
От: CEMb  
Дата: 23.11.12 05:01
Оценка:
Здравствуйте, Carc, Вы писали:

CEM>>Я ещё не зарелизился, но уже насторожился

C>Вот что подозрительно...
C>В описании RegisterShellHookWindow нет славного и столь нужного параметра HSHELL_LANGUAGE, коий явно присутствует в hook-функции для ShellHook. Так что получится ли так отловить смену языка таким образом — непонятно!?! Настораживает это однако

Ага, непонятно. Но в хедере константа есть. (может просто в доке забыли описать, в мсдн-е много ошибок, особенно в коде, вчера ещё одну нашёл) Вобщем надо просто протестить этот момент и узнать, работает или нет. Всё упирается в топикстартера
Re[15]: Программное переключение keyboard layout
От: Carc Россия http://www.amlpages.com/home.php
Дата: 23.11.12 07:55
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Здравствуйте, Carc, Вы писали:


CEM>>>Я ещё не зарелизился, но уже насторожился

C>>Вот что подозрительно...
C>>В описании RegisterShellHookWindow нет славного и столь нужного параметра HSHELL_LANGUAGE, коий явно присутствует в hook-функции для ShellHook. Так что получится ли так отловить смену языка таким образом — непонятно!?! Настораживает это однако

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

Отрепортись плз, если пойдет и смена языка, ладно!?! Не в службу, а в дружбу...
Aml Pages Home
Re[16]: Программное переключение keyboard layout
От: CEMb  
Дата: 23.11.12 13:12
Оценка:
Здравствуйте, Carc, Вы писали:

CEM>>>>Я ещё не зарелизился, но уже насторожился

C>>>Вот что подозрительно...
C>>>В описании RegisterShellHookWindow нет славного и столь нужного параметра HSHELL_LANGUAGE, коий явно присутствует в hook-функции для ShellHook. Так что получится ли так отловить смену языка таким образом — непонятно!?! Настораживает это однако

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

C>Отрепортись плз, если пойдет и смена языка, ладно!?! Не в службу, а в дружбу...

Отрепорчиваюсь: не работает (Win7 x64)
У меня уже было приложение с этим хуком, я поставитл отладку на все сообщения. По смене языка не прилетало ничего
Re[16]: Программное переключение keyboard layout
От: CEMb  
Дата: 23.11.12 14:00
Оценка:
Здравствуйте, Carc, Вы писали:

собственно меня с толку сбило название константы, я ловил тем же хуком HSHELL_REDRAW
Re[17]: Программное переключение keyboard layout
От: Carc Россия http://www.amlpages.com/home.php
Дата: 23.11.12 14:21
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Здравствуйте, Carc, Вы писали:


CEM>собственно меня с толку сбило название константы, я ловил тем же хуком HSHELL_REDRAW

А причем тут HSHELL_REDRAW? Каким образом это влияет на смену языка!?! Redraw по разным причинам может вызываться...
Aml Pages Home
Re[2]: Программное переключение keyboard layout
От: Michaels1  
Дата: 29.11.12 10:41
Оценка:
Здравствуйте, Carc, Вы писали:

C>Все просто:

C>1) SetWindowsHookEx + WH_SHELL + HSHELL_LANGUAGE — получаем все извещения о смене языка.

C>2) SetWindowsHookEx + WH_CBT + HCBT_ACTIVATE|HCBT_SETFOCUS — получаем все переключения между окнами.


Спасибо, так и сделал.

Но почему-то WH_SHELL (nCmd==HSHELL_LANGUAGE) вызывается по нескольку раз при переключении активного (foreground) окна (т.е. похоже, что устанавливать хук WH_CBT нет смысла). Например, MFC диалог с List box'ом, при клике на лист бокс (когда диалог был неактивен), вызывает hook callback 4 раза с одним и тем же языком. При клике на заголовке неактивного MfС диалога — 3 раза подряд.

При нажатии Ctrl+Shift — callback вызывается один раз, как и положено.
Re[3]: Программное переключение keyboard layout
От: Carc Россия http://www.amlpages.com/home.php
Дата: 29.11.12 12:24
Оценка:
Здравствуйте, Michaels1, Вы писали:

M>Здравствуйте, Carc, Вы писали:


C>>Все просто:

C>>1) SetWindowsHookEx + WH_SHELL + HSHELL_LANGUAGE — получаем все извещения о смене языка.

C>>2) SetWindowsHookEx + WH_CBT + HCBT_ACTIVATE|HCBT_SETFOCUS — получаем все переключения между окнами.


M>Спасибо, так и сделал.


M>Но почему-то WH_SHELL (nCmd==HSHELL_LANGUAGE) вызывается по нескольку раз при переключении активного (foreground) окна (т.е. похоже, что устанавливать хук WH_CBT нет смысла). Например, MFC диалог с List box'ом, при клике на лист бокс (когда диалог был неактивен), вызывает hook callback 4 раза с одним и тем же языком. При клике на заголовке неактивного MfС диалога — 3 раза подряд.


M>При нажатии Ctrl+Shift — callback вызывается один раз, как и положено.


Ну в принципе можно ловить переключение окон и в WH_SHELL + HSHELL_WINDOWACTIVATED. Дело в другом. WH_CBT нужен чтобы знать кому именно потом послать WM_LANGCHANGEREQUEST, для этого он и нужен.

Хотя по любому — локаль принадлежит потоку, а не окну. В принципе в подавляющем большинстве случаев можно отослать и окну верхнего уровня, переключение которых мы увидим в WH_SHELL. Но, вообще говоря, чисто теоретически на окне верхнего уровня может лежать дочернее окно, которое крутит свой цикл обработки сообщений в другом потоке. Соответственно, тогда у него вполне может быть и независимая текущая локаль (язык). Такое конечно не часто увидишь. И вообще, нужно будет внимательно смотреть на конкретные детали. Но вот, к примеру MDI-дочки, которые работают в своем собственном потоке, независимо от главного потока MDI-мамы... Как в этом случае? WH_SHELL даст нам поймать переключение mdi-дочек или нет?

Вот для чего нужен WH_CBT, чтобы знать где фокус именно сию секунду. Ну и потом можно разводить и не такие ананизъмы. Если поковыряться, то как-то по моему можно и просто дочернее окошко (WS_CHILD) положить на парент-окошко, но со своим собственным потоком для выборки сообщений. Уж не помню, нафига это надо, но то что как-то можно было — в форуме здесь мелькало. Соответственно, в таких случаях WH_SHELL один-единственный задачу решать не будет.

PS: информация к размышлению: MS WebBrowser как дочерний контрол. Он дочерний, но дофига чего он там ассинхронно сам крутит. Это уже недра COM, и тут всё несколько совсем иначе будет. Но это как раз вполне жизненный пример на тему "куда думать": дочернесть дочернестью — а поток все-таки другой.
Aml Pages Home
Re[4]: Программное переключение keyboard layout
От: Michaels1  
Дата: 01.12.12 17:11
Оценка:
Здравствуйте, Carc, Вы писали:

C>Но, вообще говоря, чисто теоретически на окне верхнего уровня может лежать дочернее окно, которое крутит свой цикл обработки сообщений в другом потоке. Соответственно, тогда у него вполне может быть и независимая текущая локаль (язык). Такое конечно не часто увидишь. И вообще, нужно будет внимательно смотреть на конкретные детали. Но вот, к примеру MDI-дочки, которые работают в своем собственном потоке, независимо от главного потока MDI-мамы... Как в этом случае? WH_SHELL даст нам поймать переключение mdi-дочек или нет?


C>PS: информация к размышлению: MS WebBrowser как дочерний контрол. Он дочерний, но дофига чего он там ассинхронно сам крутит. Это уже недра COM, и тут всё несколько совсем иначе будет. Но это как раз вполне жизненный пример на тему "куда думать": дочернесть дочернестью — а поток все-таки другой.


Эти несколько HSHELL_LANG, которые система вызывает подряд для одного окна, являются проблемой вот почему:
мне нужно при включении одного языка зажечь scrolllock, а при другом языке — погасить.
Зажигаю его я вот так:

void turnon() {
if(!GetKeyState(VK_SCROLL)) {
keybd_event( VK_SCROLL , 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0);
keybd_event( VK_SCROLL , 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}
}

Но, поскольку я получаю несколько (четное к-во) callback вызовов, когда меняется раскладка, функция turnon() также вызывается неск. раз подряд быстро, и за это время состояние скролл лока не успевает поменяться (GetKeyState() возвращает одно и то же значение). В "буфер клавиатуры" выдается 2 пары keybd_event() и скролл лок просто мигает вместо того чтоб зажечься.

Вот теперь думаю как зажечь скролл "атомарно", если это возможно, чтоб он не гас при четном к-ве вызовов turnon().
Может у кого-нибудь есть идеи?
Re[5]: Программное переключение keyboard layout
От: Carc Россия http://www.amlpages.com/home.php
Дата: 01.12.12 18:39
Оценка:
Здравствуйте, Michaels1, Вы писали:

M>Здравствуйте, Carc, Вы писали:


C>>Но, вообще говоря, чисто теоретически на окне верхнего уровня может лежать дочернее окно, которое крутит свой цикл обработки сообщений в другом потоке. Соответственно, тогда у него вполне может быть и независимая текущая локаль (язык). Такое конечно не часто увидишь. И вообще, нужно будет внимательно смотреть на конкретные детали. Но вот, к примеру MDI-дочки, которые работают в своем собственном потоке, независимо от главного потока MDI-мамы... Как в этом случае? WH_SHELL даст нам поймать переключение mdi-дочек или нет?


C>>PS: информация к размышлению: MS WebBrowser как дочерний контрол. Он дочерний, но дофига чего он там ассинхронно сам крутит. Это уже недра COM, и тут всё несколько совсем иначе будет. Но это как раз вполне жизненный пример на тему "куда думать": дочернесть дочернестью — а поток все-таки другой.


M>Эти несколько HSHELL_LANG, которые система вызывает подряд для одного окна, являются проблемой вот почему:

M>мне нужно при включении одного языка зажечь scrolllock, а при другом языке — погасить.
M>Зажигаю его я вот так:

M>void turnon() {

M> if(!GetKeyState(VK_SCROLL)) {
M> keybd_event( VK_SCROLL , 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0);
M> keybd_event( VK_SCROLL , 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
M> }
M>}

M>Но, поскольку я получаю несколько (четное к-во) callback вызовов, когда меняется раскладка, функция turnon() также вызывается неск. раз подряд быстро, и за это время состояние скролл лока не успевает поменяться (GetKeyState() возвращает одно и то же значение). В "буфер клавиатуры" выдается 2 пары keybd_event() и скролл лок просто мигает вместо того чтоб зажечься.


M>Вот теперь думаю как зажечь скролл "атомарно", если это возможно, чтоб он не гас при четном к-ве вызовов turnon().

M>Может у кого-нибудь есть идеи?
Ну если в лоб, то зажигать Scroll Lock отложенно... Как-то так примерно.
1) Запоминаем время получения последнего HSHELL_LANG и взводим какой-нить оконный таймер (WM_TIMER) ну скажем на 500 миллисекунд.
m_dwLastHSHELL_LANG_RECEVED=GetTickCount();
SetTimer(...)



2) Получаем WM_TIMER и проверяем время последнего получения HSHELL_LANG.
Если оно скажем меньше 500 мс, то ждем еще. Если больше — т.е. кагбэ последний HSHELL_LANG пришел уже "давно" — то включаем\выключаем Scroll Lock и заканчиваем ждать.
if (GetTickCount() - m_dwLastHSHELL_LANG_RECEVED) > 500) {
     KillTimer(...);
     //Зажигаем Scroll Lock
}



Ну это так. Костыль конечно. Опять же можно и без WM_TIMER делать, а в каком-нибудь фоновом потоке все ожидания выполнять. Это не суть важно как. Общая идея примерно такая же. В случае с потоком несколько аккуратнее приходится код писать, но зато работать чище будет — все косяки разом себя покажут.
Aml Pages Home
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.