Я в шоке GetMessage()
От: Votblin  
Дата: 12.09.05 11:32
Оценка:
Если я не туда запостил, плиз расскажите куда нужно таки?

Юзаем С++ в Visual Studio .NET

вот кусочек кода.

BOOL bRet = true;
MSG msg;
bRet = GetMessage(&msg, NULL, 0, 0);

Дело в том, что у меня GetMessage(&msg, NULL, 0, 0) не возвращает никакого значение.
Т.е. такое впечатление, будто прога зашла куда в глубины GetMessage() и там гдето зациклилось.

Чем лечить? В чем правда?

12.09.05 15:34: Перенесено модератором из 'Этюды для программистов' — Кодт
Re: Я в шоке GetMessage()
От: Ovl Россия  
Дата: 12.09.05 11:38
Оценка:
Здравствуйте, 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
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re: Я в шоке GetMessage()
От: Кодт Россия  
Дата: 12.09.05 11:42
Оценка:
Здравствуйте, Votblin, Вы писали:

V>Если я не туда запостил, плиз расскажите куда нужно таки?


Уж всяко не в Этюды. Ладно, спишем на панику.

V>BOOL bRet = true;
V>MSG msg;
V>bRet = GetMessage(&msg, NULL, 0, 0);

V>Дело в том, что у меня GetMessage(&msg, NULL, 0, 0) не возвращает никакого значение.
V>Т.е. такое впечатление, будто прога зашла куда в глубины GetMessage() и там гдето зациклилось.

V>Чем лечить? В чем правда?


Правда в документации. (А сила, брат, она в ньютонах).
GetMessage

GetMessage ждёт появления виндовских сообщений в очереди сообщений текущего потока, и когда дожидается — извлекает очередное сообщение и возвращает false (если это сообщение было WM_QUIT) либо true (во всех остальных случаях).

Причём программа не циклится в недрах системы, а висит на ожидании. Т.е. прервать (break) этот поток отладчиком не получится.

Если хочешь проверить, не ожидая — пожалуйста: PeekMessage.
Перекуём баги на фичи!
Re[2]: Я в шоке GetMessage()
От: Votblin  
Дата: 12.09.05 14:04
Оценка:
ОК ОК спасибо а разъяснения. Однако вот что пишу тогда:
В главной процедуре консольного приложения:

HWND hwnd;
char p[255];
while(1)
{
hwnd = ::FindWindow("CVotBlinTable", NULL);// GetWindow(hwnd,GW_HWNDNEXT);
::EnumChildWindows(hwnd,EnumChildProc, NULL);
}

и функция:


BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
{
char p[255];
::GetClassName(hwndChild, p, 1024);

if( strstr(p, "CGrid") &&
::IsWindowVisible(hwndChild) &&
::IsWindowEnabled(hwndChild)
)
{
BOOL bRet = true;
MSG msg;

while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
cout << "Closing..." << endl;
else if(msg.message == WM_KEYUP)
cout << "KEY UP..." << endl;
else
cout << msg.message << endl;
TranslateMessage(&msg);
DispatchMessage(&msg);
cout << msg.message << endl;
}
}
return true;
}


Пояснения: СGrid — это грид — контрол т.е.

Нужно мне отоловить нажатие клавиш. А именно была ли нажата и код клавиши.

Спасибо заранее. не клюйте меня, ламера, плиз.
Re[3]: Я в шоке GetMessage()
От: Ovl Россия  
Дата: 12.09.05 14:12
Оценка:
Здравствуйте, Votblin, Вы писали:


отловить — помогут хуки

SetWindowsHook() или SetWindowsHookEx() с флагом WH_KEYBOARD

хотя возможно предложат способ проще....
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re[4]: Я в шоке GetMessage()
От: Votblin  
Дата: 12.09.05 14:19
Оценка:
И что, действительно я смогу отловить нажатую клавишу для определенного контрола?

ДА и непонятно как юзать этот SetWindowsHook(...)

Не мотгли бы Вы подкинуть козу учитывая вышеприведенный код?

Не бросайте на произвол ламера!
Re[5]: Я в шоке GetMessage()
От: Ovl Россия  
Дата: 12.09.05 14:31
Оценка:
Здравствуйте, Votblin, Вы писали:

V>И что, действительно я смогу отловить нажатую клавишу для определенного контрола?


V>ДА и непонятно как юзать этот SetWindowsHook(...)


V>Не мотгли бы Вы подкинуть козу учитывая вышеприведенный код?


V>Не бросайте на произвол ламера!


не знаю что такое коза. но вот примеры из мсдн.
Using Hooks
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re[6]: Я в шоке GetMessage()
От: Votblin  
Дата: 12.09.05 14:41
Оценка:
Здравствуйте, Ovl, Вы писали:

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


V>>И что, действительно я смогу отловить нажатую клавишу для определенного контрола?


V>>ДА и непонятно как юзать этот SetWindowsHook(...)


V>>Не мотгли бы Вы подкинуть козу учитывая вышеприведенный код?


V>>Не бросайте на произвол ламера!


Ovl>не знаю что такое коза. но вот примеры из мсдн.

Ovl>Using Hooks

А Вы уверены, что я перехвачу нажатие кнопки именно для определенного контрола (см. вышеприведенный код) ?
Re[7]: Я в шоке GetMessage()
От: Ovl Россия  
Дата: 12.09.05 14:51
Оценка:
Здравствуйте, Votblin, Вы писали:

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


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


V>>>И что, действительно я смогу отловить нажатую клавишу для определенного контрола?


V>>>ДА и непонятно как юзать этот SetWindowsHook(...)


V>>>Не мотгли бы Вы подкинуть козу учитывая вышеприведенный код?


V>>>Не бросайте на произвол ламера!


Ovl>>не знаю что такое коза. но вот примеры из мсдн.

Ovl>>Using Hooks

V>А Вы уверены, что я перехвачу нажатие кнопки именно для определенного контрола (см. вышеприведенный код) ?


сообщение о нажатии кнопки отправляется окну, например кнопка в общем случае — это тоже окно
какому именно — можно определить по hwnd. соответственно сообщения для всех остальных окон — можно пропускать
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re[8]: Я в шоке GetMessage()
От: Ovl Россия  
Дата: 12.09.05 14:57
Оценка: +1
Здравствуйте, 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
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re[2]: Я в шоке GetMessage()
От: Andrew S Россия http://alchemy-lab.com
Дата: 12.09.05 15:36
Оценка: 14 (1) +1
К>Правда в документации. (А сила, брат, она в ньютонах).
К>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, если их нет.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[9]: Я в шоке GetMessage()
От: Votblin  
Дата: 12.09.05 15:39
Оценка:
Спасибо за ответ. Но чтот я и та ки сяк пытался поюзать этот хук. Ничего не выходит.

МОжет подскажете все таки?
Re[9]: Я в шоке GetMessage()
От: Votblin  
Дата: 12.09.05 15:46
Оценка:
И насколько я понял из описания необходимо создавать dll.

Неужто все так запущено?
Re[3]: Я в шоке GetMessage()
От: Votblin  
Дата: 12.09.05 15:48
Оценка:
Это конечно все хорошо, но как отловить мессагу и ка копределить код клавиши для отловленного HANDLE окна?
Re[4]: Я в шоке GetMessage()
От: Andrew S Россия http://alchemy-lab.com
Дата: 12.09.05 15:54
Оценка:
V>Это конечно все хорошо, но как отловить мессагу и ка копределить код клавиши для отловленного HANDLE окна?

Сформулируйте поставленную вам задачу по-человечески Скажите, что вам нужно, и вам скажут, как это сделать.
http://www.rsdn.ru/Info/Howtoask.xml

В правильно поставленном вопросе содержится 50% ответа.

http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[5]: Я в шоке GetMessage()
От: Votblin  
Дата: 12.09.05 19:33
Оценка:
Конечно, конечно!

Вот собственно, та задача.

У нас есть какая то программка (конечно же без source code). Или даже так: у нас есть 1с v8.0.

И проблема в том, что в табличной части формы спика документов не отлавливается нажатие клавиш. Чтобы их все-таки отловить, я пытаюсь "споймать" message нужного окна.

Т.о. я сначалаи выискиваю handle этого окна, а далее пытаюсь с этого найденного окна словить сообщение ну пусть WM_CHAR. В конце концов, SPY++ ведь это както делает!

Вот собственно и задача.
Re[6]: Я в шоке GetMessage()
От: Andrew S Россия http://alchemy-lab.com
Дата: 12.09.05 19:56
Оценка:
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
Автор(ы): Алексей Столповских
Дата: 20.11.2004
Данная статья описывает технологию создания COM+-компонента для 1С на C#. Код компонента был написан с использованием Microsoft Visual Studio.NET 2003, классов Microsoft .NET Framework 1.1 и протестирован на операционной системе Windows Server 2003 System.




В общем, главное попасть в адресное пространство 1с. А уж там перехватить\обработать нужные сообщения проблем не будет. Кстати, наверняка для нужного вам контрола есть и более легальные варианты, чем сабклассирование. Может, стоит спросить на специализированном форуме?
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[7]: Я в шоке GetMessage()
От: Votblin  
Дата: 12.09.05 21:22
Оценка:
Здравствуйте, 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
Автор(ы): Алексей Столповских
Дата: 20.11.2004
Данная статья описывает технологию создания COM+-компонента для 1С на C#. Код компонента был написан с использованием Microsoft Visual Studio.NET 2003, классов Microsoft .NET Framework 1.1 и протестирован на операционной системе Windows Server 2003 System.




AS>В общем, главное попасть в адресное пространство 1с. А уж там перехватить\обработать нужные сообщения проблем не будет. Кстати, наверняка для нужного вам контрола есть и более легальные варианты, чем сабклассирование. Может, стоит спросить на специализированном форуме?


Уважаемый, я в 1с кручусь уже 6 лет, так что поверьте — не поможет обращение в другие форумы. А то что Вы написали не совсем мне понятно, поскольку в с++ я не такой уж мастак осоебнно в WinAPI.

А прмерчик гляну обязательно, но уже утром пожалуй — спать пора!
Re[8]: Я в шоке GetMessage()
От: Andrew S Россия http://alchemy-lab.com
Дата: 12.09.05 21:35
Оценка:
AS>>В общем, главное попасть в адресное пространство 1с. А уж там перехватить\обработать нужные сообщения проблем не будет. Кстати, наверняка для нужного вам контрола есть и более легальные варианты, чем сабклассирование. Может, стоит спросить на специализированном форуме?

V>Уважаемый, я в 1с кручусь уже 6 лет, так что поверьте — не поможет обращение в другие форумы. А то что Вы написали не совсем мне понятно, поскольку в с++ я не такой уж мастак осоебнно в WinAPI.


В то, что обращение в другие форумы, специализированные под 1с, не поможет — я не верю. Лично я знаю ребят, которые с 1с могут сделать все что угодно.
Ну а касательно выделенной фразы — а что вы ждали? Готового кода? И каким образом С++ связано с WinApi, уже не понимаю я
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[9]: Я в шоке GetMessage()
От: Votblin  
Дата: 13.09.05 04:59
Оценка:
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 этого окна и получить код символа. В вышописанной статье путь конечно супер гиморный. Может посоветуете билиотеки какие?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.