1

我对我们正在开发的程序有疑问。它是使用 MFC 编写的,但不使用 unicode。我们已经翻译成简体中文。到目前为止,这是我们的第一个也是唯一一个本地化。我们已将所有字符串移至资源中以使其可翻译。在我们的计算机(Win7 和 XP)上似乎一切正常,但对于一些运行 Windows XP 的客户计算机,我们遇到了问题:

在这些计算机上,除了我们输入到树控件(直接使用 CTreeCtrl)的那些之外,所有翻译的字符串都可以工作。我不确定是树控件还是我们输入的文本导致了问题,但字体似乎没有在这些控件中被替换。我的猜测是它可能不会被替换,因为某些字符串还包含拉丁字符。尽管如此,这种替换似乎在程序的其他地方也有效,并且并非所有输入到树中的字符串都包含这些字符。

所以我的第一个问题是:有没有办法知道控件内部发生了什么?我们可以远程访问发生问题的计算机,但在它们上运行调试器可能有点棘手。什么样的工具可以用来诊断这个问题?

我想到的一种可能的解决方案是对树控件进行子类化,以更好地控制实际的文本绘制,可能使用来自http://blogs.msdn.com/b/oldnewthing/archive/2004/07/16/的方法185261.aspx来解决这个问题。这会有效吗?还是白白费力?

非常感谢!

4

1 回答 1

0

Ok, it seems on their system there was either a bug in the tree control implementation or they had some systemwide addin that hooked into the drawing in some way. What I ended up doing was to do custom drawing through notifications in the tree view and then using font linking to resolve the fonts. I dont think font linking would be necessary, though, because I think most of the time it ended up doing just TextOutW() with the preselected font anyway.

Here is a somewhat simplified code sample of what I ended up with:

void MyDlg::OnCustomDrawTreeItem( NMHDR* pNMHDR, LRESULT* pResult )
{

if (!mpFontLink)
{
    *pResult = CDRF_DODEFAULT;
    return;
}

LPNMTVCUSTOMDRAW pCustomdraw = (LPNMTVCUSTOMDRAW) pNMHDR;
switch(pCustomdraw->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
    {
        // Ask to do custom draw
        *pResult = CDRF_NOTIFYITEMDRAW;
        break;
    }
case CDDS_ITEMPREPAINT:
    {
        // Ask for post paint notification
        *pResult = CDRF_NOTIFYPOSTPAINT;
        break;
    }
case CDDS_ITEMPOSTPAINT:
    {
        // Get the rect of only the item, not the tree stuff
        RECT rcItem;
        m_pageTree.GetItemRect((HTREEITEM) pCustomdraw->nmcd.dwItemSpec, &rcItem, TRUE);

        // Erase the item background in case the previous string drawn was wider
        HDC hDC = pCustomdraw->nmcd.hdc;
        FillRect( hDC, &rcItem, (HBRUSH) GetClassLongPtr(m_pageTree.GetSafeHwnd(), GCLP_HBRBACKGROUND));

        pageStruct *pS = (pageStruct*) pCustomdraw->nmcd.lItemlParam;
        DWORD dwFontCodepages = 0, dwStrCodepages = 0;

        HFONT hOriginalFont = (HFONT)GetCurrentObject(hDC, OBJ_FONT);
        HRESULT hr = mpFontLink->GetFontCodePages( hDC, hOriginalFont, &dwFontCodepages);
        OML_CStringW tData = pS->csCaption.GetBuffer();

        // Set up position etc
        DWORD dwAlignOrig = GetTextAlign(hDC);
        if (!(dwAlignOrig & TA_UPDATECP)) {
            SetTextAlign(hDC, dwAlignOrig | TA_UPDATECP);
        }

        POINT ptOrig;
        MoveToEx(hDC, 2 + rcItem.left, 1 + rcItem.top, &ptOrig);
        SetTextColor( hDC, pCustomdraw->clrText );
        SetBkColor( hDC, pCustomdraw->clrTextBk );

        // Loop over the parts of the text
        TuInt32 nIndex = 1;
        while (nIndex <= tData.GetLength())
        {
            long nActualChars = 0;
            wchar_t *pStr = (wchar_t*)tData.BaseGetItemP( nIndex );
            TuInt32 nChars = 1 + tData.GetLength() - nIndex;
            hr = mpFontLink->GetStrCodePages(pStr, nChars,
                                             dwFontCodepages, &dwStrCodepages, &nActualChars);

            if (dwStrCodepages & dwFontCodepages)
            {
                // We end up here almost every time, that is why TextOutW would probably be enough.
                // This part is supported by the original font (or the GDI can help us switch automatically)
                TextOutW(hDC, 0, 0, pStr, nActualChars);
            }
            else
            {
                // We need to link
                HFONT hLinked;
                if (FAILED(hr = mpFontLink->MapFont(hDC, dwStrCodepages, 0, &hLinked)))
                {
                    // Fail: Output the rest without linking
                    TextOutW( hDC, 0, 0, pStr, nChars );
                    break;
                }

                // Output with linked font
                SelectObject(hDC, hLinked);
                TextOutW( hDC, 0, 0, pStr, nActualChars);
                SelectObject(hDC, hOriginalFont);
                mpFontLink->ReleaseFont( hOriginalFont );
            }
            nIndex += nActualChars;
        }
        OML_LOG_1( "_END:");

        // Reset alignment mode
        if (!(dwAlignOrig & TA_UPDATECP)) {
            SetTextAlign(hDC, dwAlignOrig);
            MoveToEx(hDC, ptOrig.x, ptOrig.y, NULL);
        }

        *pResult = CDRF_SKIPDEFAULT;
    }
default:
    {
        *pResult = CDRF_DODEFAULT;
        break;
    }
}
} /* OnCustomDrawTreeItem */
于 2012-08-09T10:21:44.747 回答