Direct2D 桌面 window class 模板基于 ATL 的 CWindowImpl
Direct2D desktop window class template based on ATL's CWindowImpl
Kenny Kerr 在他关于 Direct2D 的教程 (part1, part2) 中展示了如何制作简单的 2D 动画时钟并使用以下 classes 层次结构:
//Desktop window class based on ATL's CWindowImpl
template <typename T> struct DesktopWindow :
CWindowImpl<DesktopWindow<T>, CWindow, CWinTraits<WS_OVERLAPPEDWINDOW | WS_VISIBLE>>
{
// code here, including:
void Run() {}
};
//ClockSample class which further extends DesktopWindow
template <typename T> struct ClockSample : T
{
//code here
};
//SampleWindow class which is empty and is needed, as far as I understand,
//to, so to speak, "untemplate" ClockSample template
struct SampleWindow : ClockSample<DesktopWindow<SampleWindow>>
{
//empty
};
//main function
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
SampleWindow window;
window.Run();
}
我没有包含实际代码,因为它很大而且与问题无关。
struct SampleWindow : ClockSample<DesktopWindow<SampleWindow>>
- 我很难理解哪个 class 继承自哪个以及这里是什么? SampleWindow 继承自 ClockSample,然后又出现了 SampleWindow,它看起来像是对我的循环引用?如果有人能用简单的语言解释这里到底发生了什么,我会很高兴。
SampleWindow
继承自 ClockSample
("untemplates"),后者又派生自 DesktopWindow
,后者又派生自 ATL 的 CWindowImpl
(进一步以 CWindow
作为基础 class;CWindow
是 HWND
window 句柄上的薄包装)。
将 SampleWindow
作为模板参数允许在代码中 "downcast" 后代 class 并调用覆盖的方法,而无需将它们设为虚拟。这种方法在 ATL 中被大量使用,尤其是。
例如:
template <typename T> struct DesktopWindow :
CWindowImpl<DesktopWindow<T>, CWindow, CWinTraits<WS_OVERLAPPEDWINDOW | WS_VISIBLE>>
{
// code here, including:
void Run()
{
T* pT = static_cast<T*>(this); // T = SampleWindow
pT->InternalRun();
}
};
struct SampleWindow : ClockSample<DesktopWindow<SampleWindow>>
{
VOID InternalRun()
{
// So we eventually reach here
}
};
Kenny Kerr 在他关于 Direct2D 的教程 (part1, part2) 中展示了如何制作简单的 2D 动画时钟并使用以下 classes 层次结构:
//Desktop window class based on ATL's CWindowImpl
template <typename T> struct DesktopWindow :
CWindowImpl<DesktopWindow<T>, CWindow, CWinTraits<WS_OVERLAPPEDWINDOW | WS_VISIBLE>>
{
// code here, including:
void Run() {}
};
//ClockSample class which further extends DesktopWindow
template <typename T> struct ClockSample : T
{
//code here
};
//SampleWindow class which is empty and is needed, as far as I understand,
//to, so to speak, "untemplate" ClockSample template
struct SampleWindow : ClockSample<DesktopWindow<SampleWindow>>
{
//empty
};
//main function
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
SampleWindow window;
window.Run();
}
我没有包含实际代码,因为它很大而且与问题无关。
struct SampleWindow : ClockSample<DesktopWindow<SampleWindow>>
- 我很难理解哪个 class 继承自哪个以及这里是什么? SampleWindow 继承自 ClockSample,然后又出现了 SampleWindow,它看起来像是对我的循环引用?如果有人能用简单的语言解释这里到底发生了什么,我会很高兴。
SampleWindow
继承自 ClockSample
("untemplates"),后者又派生自 DesktopWindow
,后者又派生自 ATL 的 CWindowImpl
(进一步以 CWindow
作为基础 class;CWindow
是 HWND
window 句柄上的薄包装)。
将 SampleWindow
作为模板参数允许在代码中 "downcast" 后代 class 并调用覆盖的方法,而无需将它们设为虚拟。这种方法在 ATL 中被大量使用,尤其是。
例如:
template <typename T> struct DesktopWindow :
CWindowImpl<DesktopWindow<T>, CWindow, CWinTraits<WS_OVERLAPPEDWINDOW | WS_VISIBLE>>
{
// code here, including:
void Run()
{
T* pT = static_cast<T*>(this); // T = SampleWindow
pT->InternalRun();
}
};
struct SampleWindow : ClockSample<DesktopWindow<SampleWindow>>
{
VOID InternalRun()
{
// So we eventually reach here
}
};