![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| 0xDEAD |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 77 Регистрация: 20.9.2009 Репутация: 3 Всего: 3 |
Добрый день.
У меня программа внедряет DLL в чужой процесс, а от туда DLL делает сабклассинг окну, таким образом:
Все работает как надо, и когда я заканчиваю, я вызываю:
После чего сразу выгружаю DLL. Проблема такая: иногда процесс вылетает, потому что пытается вызвать NewWndProc, а DLL уже выгружен. Каким образом я могу подождать, пока все вызовы NewWndProc сделаются, чтоб только тогда выгрузить DLL? P.S. Я пробовал так:
Все равно иногда вылетает, да и не красиво получается... Спасибо! |
||||||||
|
|||||||||
| BorisVorontsov |
|
|||
![]() Thinker ![]() ![]() Профиль Группа: Комодератор Сообщений: 714 Регистрация: 3.11.2005 Где: Молдавия, г. Киши нёв Репутация: 4 Всего: 10 |
Ты уверен, что именно в этом причина ошибки? После возврата GWL_WNDPROC все последующие сообщения, переданные в DispatchMessage, будут направлены в новую заданную оконную функцию -------------------- [code=cpp] const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out); for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl; [/code] |
|||
|
||||
| 0xDEAD |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 77 Регистрация: 20.9.2009 Репутация: 3 Всего: 3 |
Уверен, так как программа вылетает на NewWndProc, вызванная из user32.
Программа многопоточная, может, дело в этом? |
|||
|
||||
| 0xDEAD |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 77 Регистрация: 20.9.2009 Репутация: 3 Всего: 3 |
Да, функция и правда вызывается из нового потока.
Создается новый поток, который вызывает:
И user32 почему-то в этом PeekMessage за одно вызывает:
И программа вылетает. То есть наверно получается, что этот новый поток берет WndProc до того, как я вызываю SetWindowLongPtr, но вызывает его после того, как я выгружаю DLL. Что делать? |
||||
|
|||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
можно дождаться опустошения очереди сообщений прежде чем выгружать библиотеку ( через GetQueueStatus, например ) Это сообщение отредактировал(а) GremlinProg - 9.9.2011, 06:23 -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| 0xDEAD |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 77 Регистрация: 20.9.2009 Репутация: 3 Всего: 3 |
GetQueueStatus Function
Retrieves the type of messages found in the calling thread's message queue. Во первых, я вызываю SetWindowLongPtr с другого потока, во вторых, даже с того потока, как я могу использовать GetQueueStatus?
? Не очень красиво и не очень надежно... |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
ради бога, лишь бы в том же процессе
например: вместо явной смены процедуры окна - крутить PostMessage с каким-нибудь своим сообщением до тех пор, пока старшее слово от GetQueueStatus не обнулится, после чего - вернуть на место pOldWndProc и выгрузить длл ( последнее не стоит делать из адресного пространства выгружаемой длл -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| 0xDEAD |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 77 Регистрация: 20.9.2009 Репутация: 3 Всего: 3 |
Если я правильно понял, вы предлогаете сделать что-то в этом роде:
Вопрос: если процесс довольно активно посылает сообщения, не может получится так, что GetQueueStatus всегда будет что-то возвращать? Процесс, которого я мучаю: експлорер |
||||
|
|||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
не совсем так,
таймер я бы не советовал, т.к. QS_ALLINPUT включает QS_TIMER, который реагирует на WM_TIMER, крутить - в смысле, крутить через саму очередь:
по идее, должно сработать, т.е., на момент вызова SetWindowLongPtr и сопутствующей выгрузке модуля, в очереди нет ни каких сообщений, которые могли бы как-то на это действо влиять -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| 0xDEAD |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 77 Регистрация: 20.9.2009 Репутация: 3 Всего: 3 |
Тут я вроде был прав, с вашим методом программа заходит в бесконечный цикл, а GetQueueStatus(QS_ALLINPUT) никогда не обнуляется. Я попробовал немного по другому:
почти всегда работает, но иногда получается так, что HIWORD(GetQueueStatus(QS_ALLINPUT)) не перестает возвращать 0x30 (QS_PAINT|QS_TIMER), и получается бесконечный цикл. С QS_TIMER-ом все ясно, QS_PAINT тоже вроде как-то особенно посылается. Наверно я их просто не буду проверять... Это сообщение отредактировал(а) 0xDEAD - 11.9.2011, 15:25 |
||||||
|
|||||||
| 0xDEAD |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 77 Регистрация: 20.9.2009 Репутация: 3 Всего: 3 |
Сделал так:
Погонял немного, не вылетает и не зависает. Вроде проблема решена, спасибо за помощь |
||||
|
|||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
логично, пока стоит какой-нибудь таймер или видно какое-либо окно потока, на это и был намек -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |