| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Visual C++/MFC/WTL > SubClassing CLictCtrl |
| Автор: Andrey44 15.7.2009, 09:38 | ||||
| У меня есть класс наследник от CLictCtrl и есть HWND SysListView32 Пытаюсь сделать так
Но падаю в wincore.cpp
Что я делаю не так? |
| Автор: Earnest 15.7.2009, 19:22 |
| Либо не там вызываешь, либо сабклассится дважды. Конкретно, тебе сообщают, что данное окно (hwndNew) уже приаттачено к какому-то объекту. Поскольку прошел первый ассерт, то это другой объект (экземпляр)... Похоже на косяк, типа аттач к автоматичкеской переменной или что-то вроде... А что, не проще DDX_Control в DoDataExchange вставить? Зачем явно вызывать SubclassWindow? |
| Автор: Earnest 16.7.2009, 10:03 |
| Да SubclassWindow - нормальный путь, DDX_Control его и вызывает собственно. Нужно причину искать. Эта DLL, где ListView создается - она тоже MFC? А может даже extension и там у этого окна есть экземпляр класса? Тогда низя! Может быть только одно отображение hWnd -> CWnd, иначе ничего работать не будет. Но если очень хочется, то можно. Но с оглядкой: просто Attach вызове (к своему классу) и на его деструкторе не забудь обнулить hWnd, а то плохо будет... Но имей в виду, это будет "ненастоящий" attach - для MFC-оболочки твоего окна как не было, так и не будет (все сообщения будут приходить "тому" окну). Чобы что-то посоветовать, нужно понять, че те надо: конкретно, откуда такая надобность... Кстати, если ты можешь получить хандл, то и окно постоянное получить не проблема FromHandlePermanenet, а затем, если знаешь какого класса объект, то преобразовть DYNAMIC_DOWNCAST (если класс DECLARE_DYNAMIC) или dynamic_cast (если RTTI включен). |
| Автор: Andrey44 16.7.2009, 10:22 | ||||
| Вобщем есть движок который читая XML файл строит на окне меню с разными контролами которые написаны в XML Но есть еще возможно делать обычные WIN контролы. Но понадобилось сделать CListCtrl в стиле всех контролов и есть возможность получать HWND. И вот я написал класс который должен переделать окно под общий стиль. Да, кстати контрол в длл создается с MFC. Если просто делать
А если
то падает при .......ну сверху описано. Earnest, теперь ты поняла в чем проблема? |
| Автор: Earnest 16.7.2009, 12:05 | ||
А сие что значит? Кстати, лист-контрол-то именно этот класс имеет (CSkinListCtrl)? Иначе некорректно. И лучще использовать не reinterpret_cast, a dynamic_cast или хотя бы static_cast (если не включено RRTI, но тогда лучше DYNAMIC_DOWNCAST). Если у тебя есть hWnd, то ты можешь сделать с окном практически все (в его процессе, конечно). MFC-класс всего лишь оболочка для удобства (CListCtrl не содержит данных). А вот CSkinListCtrl вполне может содержать, и тогда нужно быть уверенным, что это именно он создается в библиотеке. Добавлено через 4 минуты и 59 секунд Фактически, насколько я поняла, тебе требуется подменить класс, который используется в библиотеке для созхдания лист-вью на свой... А там тоже какой-то MFC-класс... Чисто SubclassWindow не прокатит, конечно, это же не АПИ, хотя слово похожее... Во-первых, нужно поковыряться в библиотеке - возможно, там что-то предусмотрено на этот предмет, а если нет, то боюсь не получится... Разве что с рисованием (использовать CustomDraw, т.к. эти уведомления парент обрабатывает). Но и то при условии, что сам исходный класс его не использует. |
| Автор: Andrey44 16.7.2009, 12:13 |
| Вобщем можно сделать вывод что разным потокам не разрешается совместно использовать объекты MFC-классов Добавлено через 1 минуту и 15 секунд Это значит что в CSkinListCtrl не приходят сообщения |
| Автор: Andrey44 16.7.2009, 12:47 |
| Короче придется делать через GetWindowLong(hwnd, GWL_WNDPROC); и SetWindowLong(hwnd, GWL_WNDPROC, NewWndProc); |
| Автор: Earnest 16.7.2009, 14:39 | ||||
Непричем здесь разные потоки. Нельзя замэпить одно окно на два разных MFC-объекта - это да. Но это из другой оперы.
Это тебе тоже может отлиться, если в библиотеке MFC-класс, то все развалится. Если ты подменишь оконную процедуру лист-вью, которое обернуто в MFC-класс, этот класс перестанет работать, т.е. ты потеряешь функциональность, которая есть в DLL. |
| Автор: Andrey44 16.7.2009, 14:55 | ||
В длл никакой функциональности нет. Есть разные контролы, а вот листвью нет. Но там предусмотрено создание стандартных контролов. Вот и создается SysListView32 в МФЦ оболочке. Так что я теперь просто хочу подменить оконную процедуру и взять все управление на себя. |
| Автор: Andrey44 17.7.2009, 06:42 | ||
Делаю :
Почему header сабклассится? Он ведь тоже объект класса МФЦ CHeaderCtrl |
| Автор: Earnest 17.7.2009, 06:44 | ||
| Все равно подменять оконную функцию нельзя! Потому что у всех MFC-окон общая оконная функция, которая и обеспечивает работу оболочки (хождение сообщения и т.д.) Если в DLL нет никакай функциональности, то тогда можно просто перед SubclassWindow сделать Detach. Т.е. получить окно по hWnd (FromHandlePermanent) и сделать ему детач. Это, конечно, кривовато, и может привести к утечкам памяти (хз как окно в библиотеке создается, скорее всего динамически, но можно попробовать и удалить его). Добавлено через 2 минуты и 10 секунд
Кто тебе сказал? Это просто АПИ-шное окно. Стандартный лист-контрол его не сабклассит. А то, что тебе может вернуться CWnd - так это временное окно. Есть большая разница между FromHandle и FromHandlePermanent |
| Автор: Andrey44 17.7.2009, 07:10 | ||
| Earnest, объясни пожалуйста на пальцах, что-то я не пойму. Надо делать так?
Или я не правильно понял? |
| Автор: Andrey44 17.7.2009, 07:27 | ||
Earnest, если так то вылетает теперь в другом месте
|
| Автор: Earnest 17.7.2009, 14:29 | ||
Т.е детач ты сделал, надо полагать. Видимо, нужно отбить и процедуру... она обнаружиает, что ты пытаешься сабклассить окно, которое уже сабкласировано MFC и возмущается... Я бы не парилась, а просто сделала сначала Detach этому FromHandlePermanent, а потом Attach к своему классу. Вроде должно пройти... сабклассинг делать не надо, т.к. процедура уже нужная впарена. На всякий случай, reinterpret_cast<CListCtrl*>(CListCtrl::FromHandlePermanent - масло маслянное. Чтобы отшибить хандл или сабклассить хватит и обычного CWnd:
|
| Автор: Andrey44 17.7.2009, 15:21 |
| Earnest, пробовал и так, нигде не падает, но кроме WM_PAINT ничего не приходит |
| Автор: Earnest 17.7.2009, 18:20 |
| А что собственно должно приходить? Раз WM_PAINT приходит, то в смысле винапи все нормально. А если нет, скажем, заполнения (которое есть если все штатно), то стало быть есть в dll функциональность, связанная с этим классом... |
| Автор: Andrey44 20.7.2009, 06:53 |
| Earnest, спасибо за помощь. Придется идти другим путем. |