Здравствуйте, NiJazz, Вы писали:
NJ>Здравствуйте, kankan, Вы писали:
K>>Здравствуйте, NiJazz, Вы писали:
NJ>>>NJ>>>return (m_this->m_pt->*m_mem_proc)( hwnd_, msg_, wparam_, lparam_ );
NJ>>>
K>>неправильно вызывается функция член через указатель
NJ>Спасибо. Теперь такая проблема: код компилируется, только если убрать всю статичность из класса. Вот что говорит: illegal reference to non-static member 'WndProcHooker<T>::m_mem_proc'. Честно говоря, не совсем понятно, почему возникает такая проблема, ведь есть статический мембер m_this, который и предоставляет доступ к полям объекта. Так почему же это не компилируется?
m_mem_proc — это нестатический член класса, соответственно обратиться к нему можно в данном случае только через m_this:
return (m_this->m_pt->*(m_this->m_mem_proc))( hwnd_, msg_, wparam_, lparam_ );
или
MWNDPROC mem_proc = m_this->m_mem_proc;
return (m_this->m_pt->*mem_proc)( hwnd_, msg_, wparam_, lparam_ );
Пытаюсь написать класс для замены диалоговой процедуры не статической функцией-членом любого класса, имеющей соответствующую сигнатуру.
Вот что имеем:
#pragma once
template <typename T>
class WndProcHooker
{
public:
typedef LRESULT ( CALLBACK T::* MWNDPROC )( HWND hwnd_, UINT msg_, WPARAM wparam_, LPARAM lparam_ );
WndProcHooker( HWND hwnd_, T * t_, MWNDPROC mem_proc_, bool hook_now_ = false )
: m_hwnd( hwnd_ ),
m_pt( t_ ),
m_mem_proc( mem_proc_ ),
m_proc( 0 )
{
m_this = this;
if ( hook_now_ )
hook();
}
bool hook()
{
if ( !m_proc )
m_proc = reinterpret_cast<WNDPROC>( ::SetWindowLongPtr( m_hwnd, GWLP_WNDPROC,
reinterpret_cast<LONG_PTR>( _wnd_proc ) ) );
return !!m_proc;
}
~WndProcHooker()
{
try
{
::SetWindowLongPtr( m_hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>( m_proc ) );
}
catch ( ... )
{
}
}
private:
static LRESULT CALLBACK _wnd_proc( HWND hwnd_, UINT msg_, WPARAM wparam_, LPARAM lparam_ )
{
if ( !m_this )
return ::DefWindowProc( hwnd_, msg_, wparam_, lparam_ );
return m_this->m_pt->( *m_mem_proc )( hwnd_, msg_, wparam_, lparam_ );
}
static WndProcHooker * m_this;
WNDPROC m_proc;
HWND m_hwnd;
T * m_pt;
MWNDPROC m_mem_proc;
};
Инстанцируем шаблон:
struct C
{
LRESULT CALLBACK _wnd_proc( HWND hwnd_, UINT msg_, WPARAM wparam_, LPARAM lparam_ )
{
return 0;
}
};
void f()
{
C c;
WndProcHooker<C> h( 0, &c, &C::_wnd_proc );
}
return m_this->m_pt->( *m_mem_proc )( hwnd_, msg_, wparam_, lparam_ );
Компилятор (Visual C++ 9.0) жалуется в этом месте:
C2059: syntax error : '('
Где собака зарыта?
Здравствуйте, NiJazz, Вы писали:
NJ>NJ>return (m_this->m_pt->*m_mem_proc)( hwnd_, msg_, wparam_, lparam_ );
NJ>
неправильно вызывается функция член через указатель
Здравствуйте, kankan, Вы писали:
K>Здравствуйте, NiJazz, Вы писали:
NJ>>NJ>>return (m_this->m_pt->*m_mem_proc)( hwnd_, msg_, wparam_, lparam_ );
NJ>>
K>неправильно вызывается функция член через указатель
Спасибо. Теперь такая проблема: код компилируется, только если убрать всю статичность из класса. Вот что говорит:
illegal reference to non-static member 'WndProcHooker<T>::m_mem_proc'. Честно говоря, не совсем понятно, почему возникает такая проблема, ведь есть статический мембер m_this, который и предоставляет доступ к полям объекта. Так почему же это не компилируется?
Здравствуйте, kankan, Вы писали:
K>m_mem_proc — это нестатический член класса, соответственно обратиться к нему можно в данном случае только через m_this:
K>K> return (m_this->m_pt->*(m_this->m_mem_proc))( hwnd_, msg_, wparam_, lparam_ );
K>
K>или
K>K> MWNDPROC mem_proc = m_this->m_mem_proc;
K> return (m_this->m_pt->*mem_proc)( hwnd_, msg_, wparam_, lparam_ );
K>
Огромное спасибо!
Здравствуйте, NiJazz, Вы писали:
NJ>Пытаюсь написать класс для замены диалоговой процедуры не статической функцией-членом любого класса, имеющей соответствующую сигнатуру.
Идея оказалась провальной, так как дополнительные косвенности плохо влияют на работу окна. Окно начинает криво прорисовываться. Если сделать то же самое, но с использованием обычных, статических или свободных, функций, то всё работает корректно.
Вот.