碰到一個微軟的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字符串

相關文章
相關標籤/搜索