As we can build desktop Windows RT applications now - it is a good idea to use MFC for GUI. But suddenly I've found that there is no MFC 11.0 for ARM in Visual Studio 2012, even with the ARM WDK installed! The program compiles fine as the headers are present, but you'll get linker errors stating that uafxcw.lib, uafxcwd.lib and similar files are not found. Only ATL is present for ARM.
The first thought was to use
dll2lib to generate import library from a mfc110.dll, but that DLL exports functions only by ordinals. So I've decided to look for mfc*.def in the "Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\src" dir and was surprised not to find it there. And there was also no makefile, unlike older MFC versions.
I've decided to compile a static MFC library. In this case linker would ignore all extra/unnecessary files I could add into the project by mistake. Created a new Win32 project, selected "Use MFC as a static library", added the whole "src\mfc" directory except for dll*.cpp and localized resource files - and the project compiled successfully! But after adding the generated MFC.lib to a project - got errors complaining on the
AfxRegisterMFCCtrlClasses.
Googling on that function gave a
link to a Microsoft blog describing its purpose. But there was no such function in whole MFC sources! After looking into the x86 uafxcwd.lib I've got that it is implemented in the afxctrlcontainer2.obj, so the file is probably named afxctrlcontainer2.cpp. Obviously I have not found that file. Several other functions were not present too:
CMFCControlContainer::UTF8ToString,
_AfxDispatchCall (it is implemented in x86/x64 ASM, and I was too lazy to rewrite it in THUMB), seems that they deal with MFC and OLE controls embedded into dialog resources. It would not be difficult to reimplement them by looking in disasm or implementation in older MFC versions, but I'm too lazy to do that myself.
I don't need OLE or MFC controls in my dialogs - so I've defined
_AFX_NO_MFC_CONTROLS_IN_DIALOGS in stdafx.h of my project, and implement those functions as stubs.
Here is the code of all stubs:
void __cdecl AfxRegisterMFCCtrlClasses(void)
{
}
extern "C" int
__afxNoMFCControlContainerInDialogs=1;
extern "C" DWORD_PTR AFXAPI
_AfxDispatchCall(AFX_PMSG pfn, void* pArgs, UINT nSizeArgs)
{
__debugbreak();
return 0;
}
int __cdecl CMFCControlContainer::UTF8ToString(char const *,class
ATL::CStringT<wchar_t,class StrTraitMFC<wchar_t,
class ATL::ChTraitsCRT<wchar_t> > > &,int)
{
__debugbreak();
return 0;
}
After adding that code to MFC lib sources - my project compiled and works correctly on Windows RT.
Debug MFC library is 157 Mb in size, and release version is 1.2 Gb. This is much more than the same x86 LIBs. Probably this is due to embedded debugger and incremental linker information.
The compiled LIB files are published in
this post on XDA. Do not forget to add
#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS
to your stdafx.h and avoid using custom MFC controls in dialog designer.