CASE
Мои подклассы "Control" базового класса Управление кнопкой WinAPI:
hWndControl = CreateWindowEx
(
0
, L"BUTTON"
, L"Button"
, WS_VISIBLE | WS_CHILD | BS_OWNERDRAW | WS_EX_TRANSPARENT
, wndRc.left
, wndRc.top
, wndRc.right
, wndRc.bottom
, hWndParent
, 0
, hInstance
, 0
);
void* p_this{reinterpret_cast<void*>(this)}; // avoiding C-style cast
SetWindowSubclass
(
hWndControl
, Control::ControlProc
, 0
, reinterpret_cast<DWORD_PTR>(p_this)
)
Насколько я знаю, это требует от меня определения обратного вызова как статического c (что я и делаю). Вот пример обратного вызова для справки:
LRESULT CALLBACK Control::ControlProc
(
HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
, UINT_PTR uIdSubclass
, DWORD_PTR dwRefData
)
{
// RETRIEVE POINTER TO THIS CLASS OBJECT
void* p_thisV{reinterpret_cast<void*>(dwRefData)}; // avoiding C-style cast
Control* const p_this{reinterpret_cast<Control*>(p_thisV)};
// PROCESS MESSAGES
switch (msg)
{
// DRAWING
case MY_DRAWITEM: // custom message forwarding WM_DRAWITEM from main window
{
p_this->DrawControl();
}
break;
...
}
return DefSubclassProc(hWnd, msg, wParam, lParam);
}
Поскольку здесь все работает нормально, если я рисую в функции обратного вызова или в функции-члене, определенной в базовом классе, указанном в обратном вызове.
Но я планирую наследовать этот базовый класс для нескольких разных элементов управления с разным внешним видом при использовании одного и того же обратного вызова. Поэтому я подумал, что создам виртуальные функции, вызываемые в определенных c точках обратного вызова, которые я могу переопределить в производном классе с настраиваемым поведением для каждого производного класса, например так:
// Base class header
class Control
{
...
protected:
virtual void DrawControl();
...
};
// Derived class header
class CalendarItem : public Control
{
...
protected:
void DrawControl();
...
};
// Derived class cpp
void CalendarItem::DrawControl()
{
std::unique_ptr<DrawBg> drawBg = std::unique_ptr<DrawBg>(new DrawBg(Control::hWndControl));
// this is the actual drawing mechanism, works, not relevant
}
ПРОБЛЕМА
Я получаю исключение в функции обратного вызова в строке: p_this->DrawControl();
Текст исключения: p_this -> **** был 0x75004D.
Скажите, пожалуйста, мне, как исправить это решение, чтобы работать, или возможно ли что-то подобное даже это?