Вопрос

Я использую комбинацию ATL и WTL для проекта и вывел свой собственный класс из CWindowImpl, который выглядит примерно так:

class CMyControl : public CWindowImpl<CMyControl>
{
public:
    DECLARE_WND_CLASS(_T("MyClassName"))
    ...
    BEGIN_MSG_MAP(CMyControl)
        ...
    END_MSG_MAP()
};

Это все хорошо, и если я использую CMyControl::Create чтобы создать экземпляр элемента управления, тогда он будет работать нормально, так как под капотом, CWindowImpl::Create функция зарегистрирует класс Win32 (в данном случае вызываемый MyClassName).

Однако именно такое поведение - класс Win32 регистрируется при создании экземпляра - вызывает у меня головную боль.Я хочу иметь возможность зарегистрировать класс заранее, чтобы я мог использовать имя класса с другой сторонней библиотекой, которая создаст окно с использованием Win32 CreateWindowEx звоните, но я не могу найти простой способ сделать это.В настоящее время я решаю эту проблему, используя static в качестве CreateWindowEx имя класса, а затем использовать CMyWindow::SubclassWindow чтобы присоединить к нему мой класс, но это клудж.

Кто-нибудь знает, как зарегистрировать CWindowImpl производный класс без фактического создания окна, поэтому я могу передать имя класса в CreateWindowEx успешно?Я бы подумал, что существует стандартный способ сделать это с ATL Windows, поскольку я не могу быть первым, кто сталкивается с этой проблемой.

Это было полезно?

Решение

То, что вы пытаетесь сделать, не сработает.Это связано с тем, что создание окна ATL / WTL должно проходить через класс ATL.Класс регистрирует свои это ptr с окном тук - тук.Этот блок становится WNDPROC и заменяет параметр HWND WNDPROC на это ptr экземпляра объекта.

Короче говоря, если бы вы знали, как работает ATL windowing под капотом, вы бы не пытались попробовать это.Если бы вы смогли зарегистрировать класс window, вызов CreateWindowEx успешно создал бы окно.Однако блок WNDPROC не был бы создан, и не было бы экземпляра объекта, с которым можно было бы связать ваше окно, и ни один из ваших обработчиков сообщений не был бы вызван.Вместо этого посмотрите, можете ли вы создать свое окно с помощью CWindowImpl::Create и передать вашей сторонней библиотеке hwnd элемента управления ATL после его создания.

Другие советы

Вы можете использовать:

WNDPROC pUnusedWndSuperProc; 
pUnusedWndSuperProc = NULL;
CMyControl::GetWndClassInfo().Register(&pUnusedWndSuperProc);

Хотя...Я не уверен, почему вы просто не создадите экземпляр window и не сохраните его скрытым.Это немного накладно, но это позволяет избежать путаницы с оконной логикой (что довольно сложно...последнее, чего вы хотите, - это какой-нибудь неожиданной или необычной проблемы с "грохотом").

Вы можете вызвать Win32 API Зарегистрироватьclassex функционируйте напрямую.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top