碰到一个微软的bug:CWinAppEx::GetString

在调试公司项目代码的时候,有一个系统设置的功能,里面须要从注册表中去读取数据,由于使用了MFC框架因此,为了简化代码直接使用了CWinAppEx::GetString 、CWinAppEx::SetString、CWinAppEx::GetInt、CWinAppEx::SetInt等等框架内函数,由于使用它之间只须要SetRegistryKey(_T("Application Name"));设置一下就行了,远比本身调用win32 API或者CRegKey类用起来方便多了。app

发现一个GetString的在实现的时候有一个bug,起初是我在读取一个注册表String时发现,CWinAppEx::GetString即便传入了第二个参数lpzDefault没能成功访问注册表的话返回仍是空字符串!框架

debug进入代码中看:函数

首先能够发现GetString其实是调用的GetSectionString函数:spa

CString CWinAppEx::GetString(LPCTSTR lpszEntry, LPCTSTR lpszDefault /*= ""*/)
{
    return GetSectionString(_T(""), lpszEntry, lpszDefault);
}

afxwinappex.cpp:debug

CString CWinAppEx::GetSectionString( LPCTSTR lpszSubSection, LPCTSTR lpszEntry, LPCTSTR lpszDefault /*= ""*/)
{
    ENSURE(lpszSubSection != NULL);
    ENSURE(lpszEntry != NULL);
    ENSURE(lpszDefault != NULL);

    CString strRet = lpszDefault;

    CString strSection = GetRegSectionPath(lpszSubSection);

    CSettingsStoreSP regSP;
    CSettingsStore& reg = regSP.Create(FALSE, TRUE);

    if (reg.Open(strSection))
    {
        reg.Read(lpszEntry, strRet);
    }
    return strRet;
}

从代码中来看,前面几行都没有问题,按F11进入到reg.Read(lpszEntry, strRet);调试

afxsettingsstore.cpp:code

BOOL CSettingsStore::Read(LPCTSTR lpszValueName, CString& strValue)
{
    ENSURE(lpszValueName != NULL);

    strValue.Empty();

    DWORD dwCount = 0;
    if (m_reg.QueryStringValue(lpszValueName, NULL, &dwCount) != ERROR_SUCCESS)
    {
        return FALSE;
    }

    if (dwCount == 0)
    {
        return TRUE;
    }

    LPTSTR szValue = new TCHAR [dwCount + 1];

    BOOL bRes = m_reg.QueryStringValue(lpszValueName, szValue, &dwCount) == ERROR_SUCCESS;
    if (bRes)
    {
        strValue = szValue;
    }

    delete [] szValue;
    return bRes;
}

在这里能够看到strValue.Empty();在最开始的时候就被调用了,明显不对,就算你是否有正确的值传进来,也不应首先就直接将default value清空啊,坑啊!blog

搜索看到国外有个哥们也遇到相同的问题:http://www.bcgsoft.com/cgi-bin/forum/topic.asp?TOPIC_ID=4485字符串

相关文章
相关标签/搜索