amo's BLOG

一直在默默无闻

首页 CNDEV 网志 联络 (RSS 2.0) (Atom) 登录
  随笔 87 :: 收藏 13 :: 评论 0 :: 寻迹: 0

News


随笔归档

收藏

图库

BLOGs

BTers的聚积地

OpenSource

常去网站

高校BBS

俱乐部

软工相关

友人博客

发信人: Quaful (夸父), 信区: NewSoftClub
标? 题: MFC对话框文字在中文Windows下显示不全的BUG的完全修正
发信站: BBS 水木清华站 (Sat Sep 11 12:09:03 2004), 站内

很多用MFC编写的应用程序,特别是英文的应用程序,如NOD32,还有Visual
Studio 6.0自身,在中文Windows下,对话框中的文字都有可能显示不全,文
字超出了边框范围。cygwin在前文中提到了这是MFC的一个BUG:

MFC\SRC\dlgcore.cpp:

// On DBCS systems, also change "MS Sans Serif" or "Helv" to system font.
if ((!bSetSysFont) && GetSystemMetrics(SM_DBCSENABLED))
{
??????? bSetSysFont = (strFace == _T("MS Shell Dlg") ||
??????????????? strFace == _T("MS Sans Serif") || strFace == _T("Helv"));
??????? if (bSetSysFont && (wSize == 8))
??????????????? wSize = 0;
}

if (bSetSysFont)
{
??????? CDialogTemplate dlgTemp(lpDialogTemplate);
??????? dlgTemp.SetSystemFont(wSize);
??????? hTemplate = dlgTemp.Detach();
}

修正的方法是把if((!bSetSysFont)...){ } 那一段注释掉。

但我如法修改后,发现属性页(property page)的字体还是不对。经过查找,在
MS的knowledge base里面找到了对此问题的描述:
256158 - FIX Text May Appear Truncated in MFC Applications
Localized for Japanese Windows 2000

This problem is caused by a bug in the MFC framework. The font for an MFC property page is set to the font of the associated property sheet. The font for the property sheet is retrieved by the AfxGetPropSheetFont function, which is an internal MFC function that can be found in the \Mfc\Src\Ccdata.cpp file. The font lookup code in this function makes an incorrect assumption about the font from the property sheet resource that is located in the Comctl32.dll file.

The internal AfxGetPropSheetFont function now contains code to select the correct property page font. This fix is already included in the Mfc42.dll and Mfc42u.dll files that are shipped with Windows 2000. Only applications that are statically linked to the MFC libraries and localized for Japanese platforms are affected.

MS居然说这个问题已经修正了,看来只是在日文系统上修正了……

还需要修改MFC\SRC\ccdata.cpp文件,我这里做了简单处理,把从comctl32.dll里面读字体
的部分全部注释掉,然后把Font Name写死,下面是修改后的AfxGetPropSheetFont:

BOOL AFXAPI AfxGetPropSheetFont(CString& strFace, WORD& wSize, BOOL bWizard)
{
??????? _AFX_PROPPAGEFONTINFO* pFontInfo = _afxPropPageFontInfo.GetData();

??????? // determine which font property sheet will use
??????? if (pFontInfo->m_wSize == 0)
??????? {
??????????????? ASSERT(pFontInfo->m_pszFaceName == NULL);

??????????????? /*
??????????????? HINSTANCE hInst = GetModuleHandleA("COMCTL32.DLL");
??????????????? if (hInst != NULL)
??????????????? {
??????????????????????? HRSRC hResource = NULL;
??????????????????????? WORD wLang = 0;
??????????????????????? HMODULE hKernel32 = ::GetModuleHandleA("KERNEL32.DLL");
??????????????????????? PFNGETUSERDEFAULTUILANGUAGE pfnGetUserDefaultUILanguage;
??????????????????????? pfnGetUserDefaultUILanguage = (PFNGETUSERDEFAULTUILANGUAGE)::GetProcAddress(
??????????????????????????????? hKernel32, "GetUserDefaultUILanguage");
??????????????????????? if (pfnGetUserDefaultUILanguage != NULL)
??????????????????????? {
??????????????????????????????? LANGID langid;
??????????????????????????????? langid = pfnGetUserDefaultUILanguage();
??????????????????????????????? if ((PRIMARYLANGID(langid) == LANG_JAPANESE) &&
??????????????????????????????????????? IsFontInstalled(_T("MS UI Gothic")))
??????????????????????????????????????? wLang = MAKELANGID(LANG_JAPANESE, 0x3f);
??????????????????????? }
??????????????????????? if (wLang != 0)
??????????????????????? {
??????????????????????????????? hResource = ::FindResourceEx(hInst, RT_DIALOG,
??????????????????????????????????????? MAKEINTRESOURCE(bWizard ? IDD_WIZARD : IDD_PROPSHEET), wLang);
??????????????????????? }
??????????????????????? if (hResource == NULL)
??????????????????????? {
??????????????????????????????? hResource = ::FindResource(hInst,
??????????????????????????????????????? MAKEINTRESOURCE(bWizard ? IDD_WIZARD : IDD_PROPSHEET),
??????????????????????????????????????? RT_DIALOG);
??????????????????????? }
??????????????????????? HGLOBAL hTemplate = LoadResource(hInst, hResource);
??????????????????????? if (hTemplate != NULL)
??????????????????????????????? CDialogTemplate::GetFont((DLGTEMPLATE*)hTemplate, strFace,
??????????????????????????????????????? wSize);
??????????????? }
??????????????? */
???????????????
??????????????? /////////////////////////////////////////
??????????????? // Fixed by quaful[at]smth.org
??????????????? UNREFERENCED_PARAMETER(bWizard);
??????????????? strFace = _T("MS Shell Dlg");
??????????????? wSize = 8;
??????????????? /////////////////////////////////////////

??????????????? pFontInfo->m_pszFaceName = (LPTSTR)GlobalAlloc(GPTR, sizeof(TCHAR) *
??????????????????????? (strFace.GetLength() + 1));
??????????????? lstrcpy(pFontInfo->m_pszFaceName, strFace);
??????????????? pFontInfo->m_wSize = wSize;
??????? }

??????? strFace = pFontInfo->m_pszFaceName;
??????? wSize = pFontInfo->m_wSize;

??????? return (wSize != 0xFFFF);
}

修改完上面的内容后,用
nmake /f MFCDLL.mak LIBNAME=MFC42 DEBUG=0 CODEVIEW=0 BROWSE=0 BROWSEONLY=0 UNICODE=0
编译出来放到应用程序目录下就可以了。

注:NOD32用的是MFC42U.dll,要设置UNICODE=1编译成unicode版本

?

发表于 @ 2004-09-13 10:29

Feedback

尚无评论

发表评论

标题:  
署名:  
链接:
内容:
验证码: