Search
Write a publication
Pull to refresh

Comments 9

Надо читать документацию. Там написано, что

а) должен быть инстанс CWinApp
b) должна вызываться AfxWinInit для инициализации MFC
Попробовал сделать, как Вы рекомендуете, а именно, убрал шаманство, добавил AfxWinInit:

extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPTSTR lpCmdLine, int nCmdShow)
{
//Три строки шаманства
//	AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
//	pModuleState->m_bDLL = 0;
    AfxWinInit(hInstance, hPrevInstance,lpCmdLine, nCmdShow);
    CWinApp *theApp = new CWinApp;

    DO_WORD();

    delete theApp;
    return 0;
}


В результате этого ничего не работает, WinWord не стартует.
Попробуйте добавить CWinApp theApp; перед винмейном, чтобы он живой был до инита.
Я, к несчастью, не могу протестить — нет 6 студии. По идее, этого должно хватать для правильной инициализации МFC.
На Visual Studio 2010 работает, это прямо написано в статье, подозреваю, что в любой другой студии тоже будет.

Или у Вас нет файла msword9.cpp? Выкладываю здесь проект полностью, 54Кб

Итак, попытка номер 2.

CWinApp theApp;

extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPTSTR lpCmdLine, int nCmdShow)
{
//Три строки шаманства
//    AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
//    pModuleState->m_bDLL = 0;
//    CWinApp *theApp = new CWinApp;

    AfxWinInit(hInstance, hPrevInstance,lpCmdLine, nCmdShow);
    DO_WORD();

//    delete theApp;
    return 0;
}


Результат тот же. WinWord не стартует.
Посмотрел. Действительно не работает. Есть еще одна ф-ция инициализации — AfxInitialize. Для консольного приложения будет так:

void main()
{
AfxInitialize(FALSE, _MFC_VER);
AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);
DO_WORD();
}

Для оконного, как у вас, нужно юзать WinMain, предоставляемую MFC, т.е. удалите вашу WinMain и добавьте это:

class App: public CWinApp
{
public:
BOOL InitInstance()
{
DO_WORD();
return FALSE;
}
} theApp;

Все заработает.
Еще одна проблема в DO_WORD — Font, Select и прочие объекты в деструкторе релизят ком-интерфейсы, но вы уже успели вызывать AfxOleTerm. Возьмите болк между AfxOleInit — AfxOleTerm в фигурные скобки.
Да, это оно и есть, спасибо за обстоятельный анализ.

Кстати, глянул исходники функции AfxInitialize из appmodul.cpp из MFC.

Там действительно есть 2 строчки из трех, приводящих к успеху:
BOOL AFXAPI AfxInitialize(BOOL bDLL, DWORD dwVersion)
{
	AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
	pModuleState->m_bDLL = (BYTE)bDLL;
//остальной код skipped
}
где параметр bDLL равен FALSE, что соответствует 0 из статьи.
Ага, получается так. Я тоже много нового узнал. Всегда полагал, что в MFC одна ф-ция инициализации.
Кстати, вот бы вообще от MFC избавиться, например, OleInitialize вместо AfxOleInit или
CoCreateInstance вместо app.CreateDispatch - но это уже тема для немного другой статьи.
Для данного приложения это можно. Тут, в принципе, ничего особо MFC-шного и не надо. Импортить tlb через #import и юзать C++ обертки + _variant_ & _bstr_t.
Sign up to leave a comment.

Articles