Дело в том, что у меня GetMessage(&msg, NULL, 0, 0) не возвращает никакого значение.
Т.е. такое впечатление, будто прога зашла куда в глубины GetMessage() и там гдето зациклилось.
Чем лечить? В чем правда?
12.09.05 15:34: Перенесено модератором из 'Этюды для программистов' — Кодт
Здравствуйте, Votblin, Вы писали:
V>Если я не туда запостил, плиз расскажите куда нужно таки?
V>Юзаем С++ в Visual Studio .NET
V>вот кусочек кода.
V>BOOL bRet = true; V>MSG msg; V>bRet = GetMessage(&msg, NULL, 0, 0);
V>Дело в том, что у меня GetMessage(&msg, NULL, 0, 0) не возвращает никакого значение. V>Т.е. такое впечатление, будто прога зашла куда в глубины GetMessage() и там гдето зациклилось.
V>Чем лечить? В чем правда?
The GetMessage function retrieves a message from the calling thread's message queue. The function dispatches incoming sent messages until a posted message is available for retrieval.
то есть она возвращается, только когда в очереди сообщений что-то появляется — операция синхронная.
проверить, есть ли что-нибдуь в очереди можно функцией PeekMessage
V>Дело в том, что у меня GetMessage(&msg, NULL, 0, 0) не возвращает никакого значение. V>Т.е. такое впечатление, будто прога зашла куда в глубины GetMessage() и там гдето зациклилось.
V>Чем лечить? В чем правда?
Правда в документации. (А сила, брат, она в ньютонах). GetMessage
GetMessage ждёт появления виндовских сообщений в очереди сообщений текущего потока, и когда дожидается — извлекает очередное сообщение и возвращает false (если это сообщение было WM_QUIT) либо true (во всех остальных случаях).
Причём программа не циклится в недрах системы, а висит на ожидании. Т.е. прервать (break) этот поток отладчиком не получится.
Если хочешь проверить, не ожидая — пожалуйста: PeekMessage.
Здравствуйте, Votblin, Вы писали:
V>И что, действительно я смогу отловить нажатую клавишу для определенного контрола?
V>ДА и непонятно как юзать этот SetWindowsHook(...)
V>Не мотгли бы Вы подкинуть козу учитывая вышеприведенный код?
V>Не бросайте на произвол ламера!
не знаю что такое коза. но вот примеры из мсдн. Using Hooks
Здравствуйте, Ovl, Вы писали:
Ovl>Здравствуйте, Votblin, Вы писали:
V>>И что, действительно я смогу отловить нажатую клавишу для определенного контрола?
V>>ДА и непонятно как юзать этот SetWindowsHook(...)
V>>Не мотгли бы Вы подкинуть козу учитывая вышеприведенный код?
V>>Не бросайте на произвол ламера!
Ovl>не знаю что такое коза. но вот примеры из мсдн. Ovl>Using Hooks
А Вы уверены, что я перехвачу нажатие кнопки именно для определенного контрола (см. вышеприведенный код) ?
Здравствуйте, Votblin, Вы писали:
V>Здравствуйте, Ovl, Вы писали:
Ovl>>Здравствуйте, Votblin, Вы писали:
V>>>И что, действительно я смогу отловить нажатую клавишу для определенного контрола?
V>>>ДА и непонятно как юзать этот SetWindowsHook(...)
V>>>Не мотгли бы Вы подкинуть козу учитывая вышеприведенный код?
V>>>Не бросайте на произвол ламера!
Ovl>>не знаю что такое коза. но вот примеры из мсдн. Ovl>>Using Hooks
V>А Вы уверены, что я перехвачу нажатие кнопки именно для определенного контрола (см. вышеприведенный код) ?
сообщение о нажатии кнопки отправляется окну, например кнопка в общем случае — это тоже окно
какому именно — можно определить по hwnd. соответственно сообщения для всех остальных окон — можно пропускать
Здравствуйте, Ovl, Вы писали:
Ovl>Здравствуйте, Votblin, Вы писали:
V>>Здравствуйте, Ovl, Вы писали:
Ovl>>>Здравствуйте, Votblin, Вы писали:
V>>>>И что, действительно я смогу отловить нажатую клавишу для определенного контрола?
V>>>>ДА и непонятно как юзать этот SetWindowsHook(...)
V>>>>Не мотгли бы Вы подкинуть козу учитывая вышеприведенный код?
V>>>>Не бросайте на произвол ламера!
Ovl>>>не знаю что такое коза. но вот примеры из мсдн. Ovl>>>Using Hooks
V>>А Вы уверены, что я перехвачу нажатие кнопки именно для определенного контрола (см. вышеприведенный код) ?
Ovl>сообщение о нажатии кнопки отправляется окну, например кнопка в общем случае — это тоже окно Ovl>какому именно — можно определить по hwnd. соответственно сообщения для всех остальных окон — можно пропускать
плохо написал....
ловятся сообщения для всех окон в системе. ваше дело — отфильтровать не нужные.
к примеру
пришло сообщение окну hWnd, вызывается ваша хук-процедура.
смотрите у него parent window, если это "CVotBlinTable", то hWnd — ваш клиент. в противном случае — просто вызываете следующий хук вызовом CallNextHookProc
К>Правда в документации. (А сила, брат, она в ньютонах). К>GetMessage
К>GetMessage ждёт появления виндовских сообщений в очереди сообщений текущего потока, и когда дожидается — извлекает очередное сообщение и возвращает false (если это сообщение было WM_QUIT) либо true (во всех остальных случаях).
Нет, не совсем так. Это распространенное заблуждение, но GetMessage не возвращается при приходе очередного сообщения. У потока как минимум 3 интересующих нас очереди сообщений: очередь сообщений, помещенных туда при помощи Send, ..., при помощи Post и очередь input сообщений. По крайней мере, так выглядит это извне. Так вот, GetMessage не возвращается на сообщения, посланные при помощи Send (на установленный флаг QS_SENDMESSAGE), и это явно сказано даже в документации:
function dispatches incoming sent messages until a posted message is available for retrieval
У Рихтера шаги работы GetMessage приведены как:
1. If the QS_SENDMESSAGE flag is turned on, the system sends the message to the proper window procedure. Both the GetMessage and PeekMessage functions handle this processing internally and do not return to the thread after the window procedure has processed the message; instead, these functions sit and wait for another message to process;
2. If messages are in the thread's posted-message queue, GetMessage and PeekMessage fill the MSG structure passed to these functions, and then the functions return. The thread's message loop usually calls DispatchMessage at this point to have the message processed by the appropriate window procedure.
3. If the QS_QUIT flag is turned on, GetMessage and PeekMessage return a WM_QUIT message (where the wParam parameter is the specified exit code) and reset the QS_QUIT flag.
4. If messages are in the thread's virtualized input queue, GetMessage and PeekMessage return the hardware input message.
5. If the QS_PAINT flag is turned on, GetMessage and PeekMessage return a WM_PAINT message for the proper window.
6. If the QS_TIMER flag is turned on, GetMessage and PeekMessage return a WM_TIMER message.
К>Причём программа не циклится в недрах системы, а висит на ожидании. Т.е. прервать (break) этот поток отладчиком не получится.
К>Если хочешь проверить, не ожидая — пожалуйста: PeekMessage.
Ровно такой же алгоритм, за исключением того, что эта функция не ожидает прихода posted сообщений, а просто возвращает FALSE, если их нет.
У нас есть какая то программка (конечно же без source code). Или даже так: у нас есть 1с v8.0.
И проблема в том, что в табличной части формы спика документов не отлавливается нажатие клавиш. Чтобы их все-таки отловить, я пытаюсь "споймать" message нужного окна.
Т.о. я сначалаи выискиваю handle этого окна, а далее пытаюсь с этого найденного окна словить сообщение ну пусть WM_CHAR. В конце концов, SPY++ ведь это както делает!
V>У нас есть какая то программка (конечно же без source code). Или даже так: у нас есть 1с v8.0. V>И проблема в том, что в табличной части формы спика документов не отлавливается нажатие клавиш. Чтобы их все-таки отловить, я пытаюсь "споймать" message нужного окна. V>Т.о. я сначалаи выискиваю handle этого окна, а далее пытаюсь с этого найденного окна словить сообщение ну пусть WM_CHAR. В конце концов, SPY++ ведь это както делает!
Вы это пытаетесь делать извне или из inproc com сервера, например? Если извне, то, как уже тут говорили, на первый взгляд только хук + сабклассинг поможет. Вкратце технология была уже описана. Используем глобальный хук (например, shell или cbt), внедряемся в целевое приложение, загружаем dll, в которой будет наша процедура сабклассинга, сабклассируем. Можно, конечно, просто глобальный хук на WNDPROC или клавиатуру, но описанная выше методика гораздо более кошерна. Но все равно, и тот, и тот вариант — это как удалять гланды через анус. Лучше написать com расширение для 1c, загружать его из скрипта и из него сабклассировать окно. Это будет и переносимо, и без каких-либо хаков.
Пример можно посмотреть тут: http://gzip.rsdn.ru/article/dotnet/cs1c.xml
В общем, главное попасть в адресное пространство 1с. А уж там перехватить\обработать нужные сообщения проблем не будет. Кстати, наверняка для нужного вам контрола есть и более легальные варианты, чем сабклассирование. Может, стоит спросить на специализированном форуме?
Здравствуйте, Andrew S, Вы писали:
V>>У нас есть какая то программка (конечно же без source code). Или даже так: у нас есть 1с v8.0. V>>И проблема в том, что в табличной части формы спика документов не отлавливается нажатие клавиш. Чтобы их все-таки отловить, я пытаюсь "споймать" message нужного окна. V>>Т.о. я сначалаи выискиваю handle этого окна, а далее пытаюсь с этого найденного окна словить сообщение ну пусть WM_CHAR. В конце концов, SPY++ ведь это както делает!
AS>Вы это пытаетесь делать извне или из inproc com сервера, например? Если извне, то, как уже тут говорили, на первый взгляд только хук + сабклассинг поможет. Вкратце технология была уже описана. Используем глобальный хук (например, shell или cbt), внедряемся в целевое приложение, загружаем dll, в которой будет наша процедура сабклассинга, сабклассируем. Можно, конечно, просто глобальный хук на WNDPROC или клавиатуру, но описанная выше методика гораздо более кошерна. Но все равно, и тот, и тот вариант — это как удалять гланды через анус. Лучше написать com расширение для 1c, загружать его из скрипта и из него сабклассировать окно. Это будет и переносимо, и без каких-либо хаков. AS>Пример можно посмотреть тут: http://gzip.rsdn.ru/article/dotnet/cs1c.xml
AS>В общем, главное попасть в адресное пространство 1с. А уж там перехватить\обработать нужные сообщения проблем не будет. Кстати, наверняка для нужного вам контрола есть и более легальные варианты, чем сабклассирование. Может, стоит спросить на специализированном форуме?
Уважаемый, я в 1с кручусь уже 6 лет, так что поверьте — не поможет обращение в другие форумы. А то что Вы написали не совсем мне понятно, поскольку в с++ я не такой уж мастак осоебнно в WinAPI.
А прмерчик гляну обязательно, но уже утром пожалуй — спать пора!
AS>>В общем, главное попасть в адресное пространство 1с. А уж там перехватить\обработать нужные сообщения проблем не будет. Кстати, наверняка для нужного вам контрола есть и более легальные варианты, чем сабклассирование. Может, стоит спросить на специализированном форуме?
V>Уважаемый, я в 1с кручусь уже 6 лет, так что поверьте — не поможет обращение в другие форумы. А то что Вы написали не совсем мне понятно, поскольку в с++ я не такой уж мастак осоебнно в WinAPI.
В то, что обращение в другие форумы, специализированные под 1с, не поможет — я не верю. Лично я знаю ребят, которые с 1с могут сделать все что угодно.
Ну а касательно выделенной фразы — а что вы ждали? Готового кода? И каким образом С++ связано с WinApi, уже не понимаю я
AS>В то, что обращение в другие форумы, специализированные под 1с, не поможет — я не верю. Лично я знаю ребят, которые с 1с могут сделать все что угодно.
Не верьте, это Ваше дело. Но, проверно, а вот в это поверьте. Самое интересное, что фича с быстрым поиском документов в 1с 77 была. Но в 1с 8.0 с целью улучшения производительности исчезла в том виде, что была в 1с 7.7. Однако что в 1с77 что в 1с80 нет функции, которая реагирует на нажатие клавиатуры. С героической фирмы ABBYY я слышал лишь только слабые повякивания, смысл которых сводился сначала в кпроверки а лицензионная у меня 1с, потом лицензионный у меня виндовз, а потом что у меня за конфйигурация (УТ, УПП, или еще что нибудь, причем не дай Бог самописная!). Вот и два месяца назад я договорился аж получить наконецто диск ИТС, который так до сих пор и не пришел... Так что, то что касается франче — тема больная. Ну а то что, 1с-ки действительно на все руки мастера — это често, особенно не которые работают о франчах, а фикси. Ибо во франчах человек в-основном занят внедрением, а фикси или фрилансер — он занят разработкой конкретной.
Относительно статьи. Я, конечно, может и ошибаюсь, но она меня не совсем устраивает. Я писал конечно длл компоненты для 1с на си шарпе, но на другой фирме. А здесь это сделать нелегко. У нас около 30 филиалов разбросаных по Украине. и устанавливать на кждом по .NET Framework не сахар . Кроме того, есть калькуляторы, у которых установлено Вынь 98. А всего этих компьютеров насчитывается около 150 штук!
Неужто придется выбирать вариант "удалять гланды через анус"?
Вот еще одна статья: http://www.codeguru.com/Cpp/W-P/system/keyboard/article.php/c5699/ . Вот только мне не виртся, что получив HANDLE окна я не могу достучаться до WM_CHAR этого окна и получить код символа. В вышописанной статье путь конечно супер гиморный. Может посоветуете билиотеки какие?