MFC学习:管理程序配置
2024-03-17 17:33:41

CWinApp 的配置管理接口

CWinApp与设置相关的接口有
CWinApp::WriteProfileInt
CWinApp::WriteProfileString
CWinApp::WriteProfileBinary

看看WriteProfileInt的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
BOOL CWinApp::WriteProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry,
int nValue)
{
ASSERT(lpszSection != NULL);
ASSERT(lpszEntry != NULL);
if (m_pszRegistryKey != NULL)
{
HKEY hSecKey = GetSectionKey(lpszSection);
if (hSecKey == NULL)
return FALSE;
LONG lResult = RegSetValueEx(hSecKey, lpszEntry, NULL, REG_DWORD,
(LPBYTE)&nValue, sizeof(nValue));
RegCloseKey(hSecKey);
return lResult == ERROR_SUCCESS;
}
else
{
ASSERT(m_pszProfileName != NULL);

TCHAR szT[16];
_stprintf_s(szT, _countof(szT), _T("%d"), nValue);
return ::WritePrivateProfileString(lpszSection, lpszEntry, szT,
m_pszProfileName);
}
}

知识点:

  1. 优先考虑写入到注册表,但如果未设置m_pszRegistryKey值,则会写入到 ini 文件中。
  2. m_pszRegistryKey默认值是nullptr,可以用 CWinApp::SetRegistryKey 修改它。
  3. m_pszProfileName是在程序启动时初始化的,默认用程序的文件名加上INI后缀。MFC 没有提供函数修改它,但是可以直接对其赋值。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    void CWinApp::SetCurrentHandles()
    {
    ...
    if (m_pszProfileName == NULL)
    {
    Checked::tcscat_s(szExeName, _countof(szExeName), _T(".INI")); // will be enough room in buffer
    BOOL bEnable = AfxEnableMemoryTracking(FALSE);
    m_pszProfileName = _tcsdup(szExeName);
    AfxEnableMemoryTracking(bEnable);
    if(!m_pszProfileName)
    {
    AfxThrowMemoryException();
    }
    }
    }
  4. 如果m_pszProfileName仅仅只有文件名,文件会保存到C:\Windows目录下,所以建议用相对路径的形式.\Config.ini,或着绝对路径。
  5. 当使用注册表保存时,m_pszProfileName就变为了Key
    1
    2
    this->SetRegistryKey(_T("XX公司"));
    this->WriteProfileInt(_T("root"), _T("entry"), 123);
    如果程序文件名为MyApp.exe,最终写入的注册表位置为
    1
    HKEY_CURRENT_USER\SOFTWARE\{m_pszRegistryKey}\{m_pszProfileName}\

INI文件例子:

1
this->WriteProfileInt(_T("root"), _T("item"), 123);

ini 内容

1
2
[root]
item=123

CWinAppEx 的配置管理接口

CWinAppExCWinApp的基础上,扩充了一些接口,相关函数同样以Write开头,扩展的方法是

方法中带Section的写入注册表位置是

1
HKEY_CURRENT_USER\SOFTWARE\{m_pszRegistryKey}\{m_pszProfileName}\{m_strRegSection}\{Section}

方法中不带Section的写入注册表位置是

1
HKEY_CURRENT_USER\SOFTWARE\{m_pszRegistryKey}\{m_pszProfileName}\{m_strRegSection}\

路径中m_strRegSection的默认值是Workspace,可以通过 CWinAppEx::SetRegistryBase 方法修改它。

总结

  • CWinApp的方法可选择写入注册表或是INI文件,默认情况下写INI文件。
  • CWinAppEx提供的方法只能写入注册表,所以必须填充m_pszRegistryKey值。

对于写注册表来说,m_pszRegistryKey一般填入组织名称,m_pszProfileName填入产品名称,m_strRegSection填入子模块名称。
CWinApp的以WriteProfile开头的方法虽然可以写注册表,但是因为没有m_strRegSection字段,没法按模块分别写入不同的位置,所以不建议使用,除非你的工程只有一个模块。