Требуется создать сабж. Полностью, с регистрацией имени
класса в системе (RegisterClass(...)). Так же, как MFC создает
класс "MDIFrame", например. Также необходимо, чтобы правильно
работала MessageMap. Как это сделать? Понятно, что функция окна
не может быть методом класса, но в MFC это реализовано???
Не при помощи ли GetSuperWndProcAddr() ?
Помогите, кто может! Совсем зат%?№!"ся :(
Спасибо.
Здравствуйте KaSA, Вы писали:
KSA>Требуется создать сабж. Полностью, с регистрацией имени KSA>класса в системе (RegisterClass(...)). Так же, как MFC создает KSA>класс "MDIFrame", например. Также необходимо, чтобы правильно KSA>работала MessageMap. Как это сделать? Понятно, что функция окна KSA>не может быть методом класса, но в MFC это реализовано??? KSA>Не при помощи ли GetSuperWndProcAddr() ?
1. Пишется класс, наследованный от CWnd, c message map и всеми делами.
class CMyWnd : public CWnd { ... };
2. Создается объект класса и создается окно:
CMyWnd * pWnd = new CMyWnd(); pWnd->Create(...);
В этом случае окно будет иметь имя класса, сгенерированное MFC, что-то вроде "Afx:400000:8:10011:0:19800411".
3. Если хочется, чтобы окно имело конкретный предопределенный класс, то нужно зарегистрировать этот класс в PreCreateWindow:
4. Все перечисленные методы требуют, чтобы сначала был создан объект C++, а только потом создавалось окно. Если хочется зарегистрировать класс окна, так чтобы кто-то вызывал ::CreateWindow(_T("MyWndClass"), ...), возможно, даже не подозревая о том, что окно реализовано на MFC, нужно действовать по другому.
4.а Рериструруем класс окна и указываем там свою функцию окна (она может быть статическим членом класса):
4.б В функции окна создаем объект С++ и субклассируем уже созданное окно:
LRESULT CALLBACK
CMyWnd::MyWndProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
// первым делом отсоединяем эту функцию от окна, чтобы она никогда
// больше не вызывалась и назначаем DefWindowProc в качестве функции
// окна
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)DefWindowProc);
// создаем объект C++
CMyWnd * pWnd = new CMyWnd();
// субклассируем окно
pWnd->SubclassWindow(hWnd);
// теперь все новые сообщения, которые идут в это окно будут попадать
// в AfxWndProc, которая по идентификатору окна найдет нужный объект
// CMyWnd и передаст сообщение ему. Все необработанные сообщения она
// будет передавать предыдущей функции окна, которую мы только что
// установили в DefWindowProc.
// Однако, самое первое сообщение, которое мы в данный момент обрабатываем,
// уже не будет получено через стандартные механизмы, поэтому мы вызываем
// AfxWndProc явно, чтобы дать возможность окну обработать это сообщениеreturn AfxWndProc(hWnd, uMsg, wParam, lParam);
}
Примерно так. Я мог напутать чего-нибудь, проверишь — расскажешь.
AF> // создаем объект C++ AF> CMyWnd * pWnd = new CMyWnd();
М-да, рано радовался :(
Все было бы хорошо, еслиб знать, как эти созданные
С++ объекты удалять. Особенно созданные внутри них
MFC объекты...такая ж%па начинается после закрытия окна,
ужас просто :)
мож я тупой ваще, но не вижу тривиального решения...
есть идеи?
Здравствуйте KaSA, Вы писали:
KSA>Здравствуйте Alex Fedotov, Вы писали:
AF>> // создаем объект C++ AF>> CMyWnd * pWnd = new CMyWnd();
KSA>М-да, рано радовался :( KSA>Все было бы хорошо, еслиб знать, как эти созданные KSA>С++ объекты удалять. Особенно созданные внутри них KSA>MFC объекты...такая ж%па начинается после закрытия окна, KSA>ужас просто :) KSA>есть идеи?
Есть одна идея, к сожалению нет времени сейчас это проверить :(, надо сделать
поддержку динамического создания в класс CMyWnd и использовать его
Здравствуйте KaSA, Вы писали:
AF>> // создаем объект C++ AF>> CMyWnd * pWnd = new CMyWnd();
KSA>Все было бы хорошо, еслиб знать, как эти созданные KSA>С++ объекты удалять. Особенно созданные внутри них KSA>MFC объекты...такая ж%па начинается после закрытия окна, KSA>ужас просто :) KSA>мож я тупой ваще, но не вижу тривиального решения... KSA>есть идеи?
Здравствуйте KaSA, Вы писали:
KSA>Все привыкли, к фразе "цель оправдывает средства", KSA>но в данном контексте усё наоборот :) — KSA>средства вовсе не оправдывают цель...
KSA>решил проблему путем встраивания в OnDestroy(...) KSA>строки — delete this; Не лучший вариант, но работает :) KSA>Даже ВС не ругается...
Специально для этого сделана виртуальная функция PostNcDestroy, которая вызывается сразу после обработки сообщения WM_NCDESTROY (последнее сообщение, которое приходит в окно перед его уничтожением). Странно не воспользоваться специально предназначенным для этого средством и изобретать велосипед, хотя и очень похожий.
Здравствуйте Alex Fedotov, Вы писали:
AF>Специально для этого сделана виртуальная функция PostNcDestroy, которая вызывается сразу после обработки сообщения WM_NCDESTROY (последнее сообщение, которое приходит в окно перед его уничтожением). Странно не воспользоваться специально предназначенным для этого средством и изобретать велосипед, хотя и очень похожий.
Велосипед я не изобретал...просто реализовал это раньше, чем Вы ответили.
А за то, что насчет PostNcDestroy просветили — огромное человеческое спасибо :)