需要将CString的Format进行封装,使得在所有加载资源ID的代码调用前,切换到正确的资源。用完后恢复为用之前的资源。因为涉及到变参,开始有些没想明白。因为变参需要约定规则,而Format的规则,即格式串中%符号,这很复杂,解析太烦。查看CString::Format源码,
发现:CString::FormatV已经将一切工作搞定。
这样一来,实现就很Easy了:
void CBaseUtil::Format(CString &sDest,UINT uID,...)
{
HINSTANCE inst = ::AfxGetResourceHandle();
::AfxSetResourceHandle( g_resLoader.GetCurrentResInstance());
CString strFormat;
VERIFY(strFormat.LoadString(uID) != 0);
va_list ap;
va_start(ap,uID);
sDest.FormatV(strFormat,ap);
va_end(ap);
::AfxSetResourceHandle(inst);
}
仔细看CString::FormatV的代码可以完全了解C++中变参的使用,应该说变参的实现原理很简单,虽说实用性不强,但在某些特定场合可能有些用处。
关于Format封装的补充:
其实写完之后,我才发现我如此麻烦去考虑变参,其实也不一定有必要。
如果将原有代码的Format拆为两句:
CBaseUtil::LoadString(uid,strFormat);
Str.Format(strFormat,…)
这样,只需要封装LoadString,可以绕过变参。当然,这样代码不如直接封存装来得简洁。
不过,可以借此了解一下变参的使用。
绑在MFC的C++的程序员们,先是痛苦,对MFC框架生成东东很是敬畏,然后有些明白之后,开始BS之。
我想:再之后就应该是正确重用之,将其真正当作自已代码的一部分。这样,就不会感觉受控于它了。魔由心生,将MFC当作魔鬼也好,当做天使也好,但只要能控制它,那就园满了。