Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как получить дескриптор родительского окна из dll? 
:(
    Опции темы
andrewak
Дата 10.7.2009, 10:10 (ссылка)   | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 22.8.2008

Репутация: нет
Всего: нет



Проблема в следующем. Есть dll, которая чего-то там делает. Задача: передать приложению, которое вызвало эту dll, сообщение. Для этого, как не трудно догадаться, мне нужен hWnd. Проблема в том, что родительское приложение может быть любым. То есть поиск по заголовку и перечисление всех окон мне не поможет :(
Чувствую пятой точкой, что вопрос тупой..... 
Буду благодарен за любые советы, кроме посылания в куй smile
PM MAIL   Вверх
Earnest
Дата 10.7.2009, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Что значит "родительское окно", Этот термин имеет смысл только по отношению к дочерним окнам, а у тебя в DLL, как я понимаю, никаких окон нет.
Если подразумевается главное окно приложения (а оно существует только в контексте MFC-оболочки, а не "вообще"), есть варианты:
1) Если DLL тоже является MFC, да еще и MFC-extension, то нет проблем - обычный вызов AfxGetMainWnd выдаст искомое
2) Поиск очень даже поможет, если искать окно не по заголовку, а по принадлжености к процессу. Чтобы найти главное окно, нужно искать "самое родительское" окно.
3) Можно послать широковещательное сообщение (HWND_BROADCAST, но специальное или зарегистрированное, чтобы на него реагировлао только окно приложения).


--------------------
...
PM   Вверх
AlexT84
Дата 10.7.2009, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 10.7.2009

Репутация: 1
Всего: 1



Попробуй функцию EnumThreadWindows. Она найдёт тебе все недочерние окна потока. Если потоков несколько, то придётся искать и по потокам. В результате получиш список недочерних окон. Какое из них саааамое главное врятли получится узнать для общего случая, без какой-либо дополнительной информации.
PM MAIL   Вверх
andrewak
Дата 10.7.2009, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 22.8.2008

Репутация: нет
Всего: нет



Цитата(Earnest @ 10.7.2009,  12:24)
Что значит "родительское окно", Этот термин имеет смысл только по отношению к дочерним окнам, а у тебя в DLL, как я понимаю, никаких окон нет.
Если подразумевается главное окно приложения (а оно существует только в контексте MFC-оболочки, а не "вообще"), есть варианты:
1) Если DLL тоже является MFC, да еще и MFC-extension, то нет проблем - обычный вызов AfxGetMainWnd выдаст искомое
2) Поиск очень даже поможет, если искать окно не по заголовку, а по принадлжености к процессу. Чтобы найти главное окно, нужно искать "самое родительское" окно.
3) Можно послать широковещательное сообщение (HWND_BROADCAST, но специальное или зарегистрированное, чтобы на него реагировлао только окно приложения).

Сорри за ошибки в терминологии - я с ООП как-то не дружу в принципе, но надо осваиваться потихоньку :(
1) Что значит MFC-extention? Я в студии (2005) сделал проект MFC Dll. В любом случае, щас попробую AfxGetMainWnd...
2) Вот! поиск даст именно главное окно! а если dll была вызвана не главным окном? обломс получится :(
3) Хм..... тоже вариант. 
Спасибо!
пысы кстати, что значит "тоже mfc"? да dll у меня mfc. но значит ли это что для корректной работы AfxGetMainWnd приложение тоже должно быть mfc?

Добавлено @ 16:19
Цитата(AlexT84 @ 10.7.2009,  15:01)
Попробуй функцию EnumThreadWindows. Она найдёт тебе все недочерние окна потока. Если потоков несколько, то придётся искать и по потокам. В результате получиш список недочерних окон. Какое из них саааамое главное врятли получится узнать для общего случая, без какой-либо дополнительной информации.

Да, эту функцию я уже нашёл в msdn, только пока не разглядел всей её полезности. Получить то список окон не проблема. Только как узнать какое из этих окон вызвало мою dll?

Это сообщение отредактировал(а) andrewak - 10.7.2009, 16:23
PM MAIL   Вверх
AlexT84
Дата 10.7.2009, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 10.7.2009

Репутация: 1
Всего: 1



dll аттачится к процессу, а не к окну. Такого понятия, как "окно вызвавшее dll" нет. Можеш узнать процесс. Можеш узнать поток вызвавший определённую функцию. Можеш узнать список потоков к приаттаченному процессу. Можеш узнать о создании/завершении новых потоков. А вот окно, обработчик которой подгрузил либу/вызвал из неё функцию врятли. Разве что список всех недочерних окон принадлежащих потоку.
PM MAIL   Вверх
andrewak
Дата 10.7.2009, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 22.8.2008

Репутация: нет
Всего: нет



Цитата(Earnest @ 10.7.2009,  12:24)
Что значит "родительское окно", Этот термин имеет смысл только по отношению к дочерним окнам, а у тебя в DLL, как я понимаю, никаких окон нет.
Если подразумевается главное окно приложения (а оно существует только в контексте MFC-оболочки, а не "вообще"), есть варианты:
1) Если DLL тоже является MFC, да еще и MFC-extension, то нет проблем - обычный вызов AfxGetMainWnd выдаст искомое
2) Поиск очень даже поможет, если искать окно не по заголовку, а по принадлжености к процессу. Чтобы найти главное окно, нужно искать "самое родительское" окно.
3) Можно послать широковещательное сообщение (HWND_BROADCAST, но специальное или зарегистрированное, чтобы на него реагировлао только окно приложения).

Странно, но AfxGetMainWnd всегда остаётся 0 :(
Я просто добавил строчку в InitInstance моей dll.
Код

HWND hToMyWnd = AfxGetMainWnd()->GetSafeHwnd();


Видимо придётся делать через посылку широковещательного сообщения...
PM MAIL   Вверх
andrewak
Дата 10.7.2009, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 22.8.2008

Репутация: нет
Всего: нет



Цитата(AlexT84 @ 10.7.2009,  17:10)
dll аттачится к процессу, а не к окну. Такого понятия, как "окно вызвавшее dll" нет. Можеш узнать процесс. Можеш узнать поток вызвавший определённую функцию. Можеш узнать список потоков к приаттаченному процессу. Можеш узнать о создании/завершении новых потоков. А вот окно, обработчик которой подгрузил либу/вызвал из неё функцию врятли. Разве что список всех недочерних окон принадлежащих потоку.

хм...... более-менее понял....
и список недочерних окон мне как-то мало поможет :( в любом случае, спасибо! буду чё-нить думать дальше.....
PM MAIL   Вверх
Earnest
Дата 11.7.2009, 05:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(andrewak @  10.7.2009,  18:28 Найти цитируемый пост)
Странно, но AfxGetMainWnd всегда остаётся 0 :(

Ничего странного, значит, у тебя не Extension DLL. Последняя встраивается в MFC-приложение как "родная" (т.е. все работает практически так же, как и внутри самом приложения).
Но задачу ты поставил неточно. Тебе, оказывыается, нужно узнать, из какого окна вызвана DLL. 
Т.е., видимо, из обработчика какого окна, и не DLL, а одна из ее функций.
Ответ - никак это не узнать, только передавать соответствующий аргумент в эту функцию. А если нужно узнать, откуда именно вызвана загрузка библиотеки - то вообще кранты. Только установка глобальной переменной. Причем переменной в DLL. Т.е. нужно писать что-то вроде оболочек к функциям DLL: загрузил DLL, установил переменную = HWND. Не совсем понятно все же, что имеется в виду: таки загрузить DLL или вызывать функцию? Если последнее, я бы сделала что-то вроде контекста вызова:
Код

SetCallContext (hWnd);
WantedFunction (...);
SetCallContext (0);

SetCallContext - функция DLL, устанавливающая текущее окно, WantedFunction - целевая функция. Все это можно обернуть макросом, чтобы не писать каждый раз по 3 строки, а обойтись одной...


--------------------
...
PM   Вверх
andrewak
Дата 11.7.2009, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 22.8.2008

Репутация: нет
Всего: нет



Цитата(Earnest @ 11.7.2009,  05:43)
Цитата(andrewak @  10.7.2009,  18:28 Найти цитируемый пост)
Странно, но AfxGetMainWnd всегда остаётся 0 :(

Ничего странного, значит, у тебя не Extension DLL. Последняя встраивается в MFC-приложение как "родная" (т.е. все работает практически так же, как и внутри самом приложения).
Но задачу ты поставил неточно. Тебе, оказывыается, нужно узнать, из какого окна вызвана DLL. 
Т.е., видимо, из обработчика какого окна, и не DLL, а одна из ее функций.
Ответ - никак это не узнать, только передавать соответствующий аргумент в эту функцию. А если нужно узнать, откуда именно вызвана загрузка библиотеки - то вообще кранты. Только установка глобальной переменной. Причем переменной в DLL. Т.е. нужно писать что-то вроде оболочек к функциям DLL: загрузил DLL, установил переменную = HWND. Не совсем понятно все же, что имеется в виду: таки загрузить DLL или вызывать функцию? Если последнее, я бы сделала что-то вроде контекста вызова:
Код

SetCallContext (hWnd);
WantedFunction (...);
SetCallContext (0);

SetCallContext - функция DLL, устанавливающая текущее окно, WantedFunction - целевая функция. Все это можно обернуть макросом, чтобы не писать каждый раз по 3 строки, а обойтись одной...

Звучит обнадёживающе smile
Суть проблемы в следующем: апликация устанавливает глобальные хуки на клавиатуру и мышь. Колбэки размещаются в dll. Там же делается обработка и результаты складываются в shared memory, ибо их много... Сейчас апликация читает информацию по таймеру, но это как-то  не комильфо. Я хочу при полузаполнении буфера, в который склабываются результаты, засылать апликации сообщение типа "поди глянь". вот и вся проблема smile
В любом случае спасибо! пойду читать msdn..... и чего масдай такой замороченный? и вообще я как-то операционки недолюбливаю......
PM MAIL   Вверх
Earnest
Дата 13.7.2009, 07:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Ну, кроме виндовских сообщений, есть механизм событий (правда, он для многопоточного случая). Кроме того, можно написать свой механизм генерации событий (по принципу подписчик - издатель). Или использовать точки подключения (напр. boost::signals). Или передать в DLL callback-функцию. Или...
В общем, можно придумать массу способов. Незачем завязываться на оконные сообщения). Думаю, в твоем случая calback-функция - самый простой вариант. 


--------------------
...
PM   Вверх
andrewak
Дата 14.7.2009, 05:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 22.8.2008

Репутация: нет
Всего: нет



Спасибо за совет!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0956 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.