2009-02-22 9 views
3

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

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, чтобы прикрепить к нему свой класс, но это kludge.

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

ответ

2

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

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

0

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

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

Хотя ... Я не знаю, почему вы не просто создать экземпляр окна и держать его скрытым. Его немного накладных расходов, но это позволяет избежать смещения с кишками логики окон (что довольно сложно ... последнее, что вы хотите, это какая-то неожиданная или необычная проблема с «thunking»).

 Смежные вопросы

  • Нет связанных вопросов^_^