Я в процессе переноса проекта C ++ / WTL из Visual Studio 2005 в VS 2008. Одна из конфигураций проекта - это сборка для модульного тестирования, которая определяет символ препроцессора UNIT_TEST.
Чтобы включить мои классы WTL в свой тестовый комплект, я создал класс CFakeWindow
, который заглушает все методы CWindow. Затем в моем файле stdafx.h я делаю это прямо под импортом atlwin.h (который определяет класс CWindow):
#ifdef UNIT_TEST
#include "fakewindow.h"
#define CWindow CFakeWindow
#endif
Мои классы окон выглядят так:
class CAboutDialog :
public CDialogImpl< CAboutDialog, CWindow >
, public CDialogResize< CAboutDialog >
{
// class definition omitted...
};
Это прекрасно работает в VS 2005. Проблема в том, что в VS 2008 вместо класса CFakeWindow вызываются методы из исходного класса CWindow. Это, конечно, приводит к сбою тестов, потому что CWindow
обрызгивается ATLASSERT(::IsWindow(m_hWnd))
.
Когда я выполняю код в отладчике, я вижу, что класс CAboutDialog наследуется от CDialogImpl<CAboutDialog, CFakeWindow>
. Тем не менее, когда я вызываю метод на CAboutDialog
(например, EndDialog(code)
), вызывается метод CWindow
.
Это ошибка в VS 2008, или моя техника условного наследования шаблонов была мерзостью, которую допускал VS 2005, но VS 2008 "исправил"? Есть ли обходной путь, или мне нужно рассмотреть другую технику для модульного тестирования классов WTL? Мне очень нравится этот метод, потому что он позволяет мне помещать WTL-классы в тестовый комплект без использования библиотеки WTL.
Редактировать : Как отмечено в ответе Конала ниже, выходные данные препроцессора показывают, что мой класс наследуется от CFakeWindow:
class CAboutDialog :
public CDialogImpl<CAboutDialog, CFakeWindow >
, public CDialogResize< CAboutDialog >
...
И, как указано выше, когда я выполняю код в отладчике, CAboutDialog отображается в окне локальных компьютеров как наследник от CFakeWindow.
Редактировать 2 : Согласно совету Конала, я прошел через разборку, и код предположительно вызывает метод CFakeWindow, но метод CWindow - это то, что на самом деле называется.
if ( wID == IDCANCEL )
00434898 movzx edx,word ptr [ebp+8]
0043489C cmp edx,2
0043489F jne CAboutDialog::OnCloseCmd+90h (4348B0h)
{
EndDialog( wID ) ;
004348A1 movzx eax,word ptr [ebp+8]
004348A5 push eax
004348A6 mov ecx,dword ptr [ebp-10h]
004348A9 call ATL::CDialogImpl<CAboutDialog,ATL::CFakeWindow>::EndDialog (40D102h)
}
else
004348AE jmp CAboutDialog::OnCloseCmd+9Ah (4348BAh)
{
EndDialog(IDOK);
004348B0 push 1
004348B2 mov ecx,dword ptr [ebp-10h]
004348B5 call ATL::CDialogImpl<CAboutDialog,ATL::CFakeWindow>::EndDialog (40D102h)
Я начинаю больше склоняться к ошибке в отладчике VC ++ 2008.