DDX_Control(pDX, IDC_LIST2, m_readerlist);出现读取不了文件中的中文
时间: 2023-11-28 12:47:18 浏览: 139
这个问题可能是由于文件编码格式不正确导致的。你可以尝试将文件编码格式改为 UTF-8 或者 GBK,看看是否能够解决问题。
如果还是不能解决问题,你可以尝试使用 Unicode 编码格式来读取文件中的中文字符。具体做法是,在打开文件时指定文件编码格式为 Unicode,例如:
```
CFile file(_T("your_file_path"), CFile::modeRead | CFile::shareDenyNone);
CArchive ar(&file, CArchive::load | CArchive::bNoFlushOnDelete);
ar.m_pDocument->SetDocLocale(_T("zh-CN")); // 设置本地化信息
CString str;
ar >> str; // 读取字符串
```
希望这些信息能够帮助到你。
相关问题
使用mfc 1 每条记录包含职工姓名、工号、基本工资、岗位津贴、奖金、医疗保险、公积金,个人所得税信息; 2 其中个人所得税通过“2012年个人所得税税率表”计算获得; 3 工资信息的显示、增、删、改、查功能; 4 程序启动时可以从文件读取已存在工资信息; 5 程序退出时将最新的信息保存到原来的文件中;
好的,下面是一个简单的基于MFC对话框的工资管理系统实现,包括了上述要求的功能:
1. 创建一个MFC对话框应用程序。
2. 在对话框中添加文本框、列表框、按钮等控件,用于显示工资信息和进行操作。
3. 在对话框类中定义数据结构体Salary,包含职工姓名、工号、基本工资、岗位津贴、奖金、医疗保险、公积金、个人所得税等信息。
4. 在对话框类中定义变量和控件对象,例如:CListCtrl m_listCtrl,用于显示工资信息的列表框。
5. 在对话框类的OnInitDialog()函数中,初始化列表框控件,加载已存在的工资信息。
6. 在对话框类中添加函数,用于显示、增、删、改、查工资信息,例如:DisplaySalary()、AddSalary()、DeleteSalary()、EditSalary()、SearchSalary()等函数。
7. 在对话框类中添加函数,用于计算个人所得税,例如:CalculateTax()函数,根据“2012年个人所得税税率表”计算个人所得税。
8. 在对话框类的保存和销毁函数中,将最新的工资信息保存到原文件中,例如:OnOK()和OnDestroy()函数。
下面是一个简单的实现示例,供您参考:
```cpp
// Salary.h 文件
#pragma once
struct Salary
{
CString name; // 姓名
CString id; // 工号
double basicSalary; // 基本工资
double postAllowance; // 岗位津贴
double bonus; // 奖金
double medicalInsurance;// 医疗保险
double providentFund; // 公积金
double tax; // 个人所得税
};
// MyDialog.h 文件
#pragma once
#include "afxwin.h"
#include "afxcmn.h"
#include "Salary.h"
class CMyDialog : public CDialog
{
public:
CMyDialog(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_MYDIALOG_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
protected:
virtual BOOL OnInitDialog();
virtual void OnOK();
virtual void OnDestroy();
afx_msg void OnBnClickedBtnAdd();
afx_msg void OnBnClickedBtnDelete();
afx_msg void OnBnClickedBtnEdit();
afx_msg void OnBnClickedBtnSearch();
DECLARE_MESSAGE_MAP()
private:
void InitListCtrl();
void DisplaySalary();
void AddSalary();
void DeleteSalary();
void EditSalary();
void SearchSalary();
void CalculateTax(Salary& salary);
private:
CListCtrl m_listCtrl;
CString m_strName;
CString m_strID;
double m_dBasicSalary;
double m_dPostAllowance;
double m_dBonus;
double m_dMedicalInsurance;
double m_dProvidentFund;
double m_dTax;
int m_nSelectedRow;
std::vector<Salary> m_vecSalaries;
};
```
```cpp
// MyDialog.cpp 文件
#include "stdafx.h"
#include "MyDialog.h"
#include <fstream>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMyDialog 对话框
CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/)
: CDialog(CMyDialog::IDD, pParent)
, m_strName(_T(""))
, m_strID(_T(""))
, m_dBasicSalary(0)
, m_dPostAllowance(0)
, m_dBonus(0)
, m_dMedicalInsurance(0)
, m_dProvidentFund(0)
, m_dTax(0)
, m_nSelectedRow(-1)
{
// ...
}
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_SALARY, m_listCtrl);
DDX_Text(pDX, IDC_EDIT_NAME, m_strName);
DDX_Text(pDX, IDC_EDIT_ID, m_strID);
DDX_Text(pDX, IDC_EDIT_BASIC_SALARY, m_dBasicSalary);
DDX_Text(pDX, IDC_EDIT_POST_ALLOWANCE, m_dPostAllowance);
DDX_Text(pDX, IDC_EDIT_BONUS, m_dBonus);
DDX_Text(pDX, IDC_EDIT_MEDICAL_INSURANCE, m_dMedicalInsurance);
DDX_Text(pDX, IDC_EDIT_PROVIDENT_FUND, m_dProvidentFund);
DDX_Text(pDX, IDC_EDIT_TAX, m_dTax);
}
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
ON_BN_CLICKED(IDC_BTN_ADD, &CMyDialog::OnBnClickedBtnAdd)
ON_BN_CLICKED(IDC_BTN_DELETE, &CMyDialog::OnBnClickedBtnDelete)
ON_BN_CLICKED(IDC_BTN_EDIT, &CMyDialog::OnBnClickedBtnEdit)
ON_BN_CLICKED(IDC_BTN_SEARCH, &CMyDialog::OnBnClickedBtnSearch)
END_MESSAGE_MAP()
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
// 初始化列表框控件
m_listCtrl.InsertColumn(0, _T("姓名"), LVCFMT_CENTER, 80);
m_listCtrl.InsertColumn(1, _T("工号"), LVCFMT_CENTER, 80);
m_listCtrl.InsertColumn(2, _T("基本工资"), LVCFMT_CENTER, 80);
m_listCtrl.InsertColumn(3, _T("岗位津贴"), LVCFMT_CENTER, 80);
m_listCtrl.InsertColumn(4, _T("奖金"), LVCFMT_CENTER, 80);
m_listCtrl.InsertColumn(5, _T("医疗保险"), LVCFMT_CENTER, 80);
m_listCtrl.InsertColumn(6, _T("公积金"), LVCFMT_CENTER, 80);
m_listCtrl.InsertColumn(7, _T("个人所得税"), LVCFMT_CENTER, 80);
// 加载已存在的工资信息
std::ifstream inFile("salary.txt");
if (inFile.is_open())
{
Salary salary;
while (inFile >> salary.name >> salary.id >> salary.basicSalary >> salary.postAllowance >> salary.bonus >> salary.medicalInsurance >> salary.providentFund)
{
CalculateTax(salary);
m_vecSalaries.push_back(salary);
}
inFile.close();
}
// 显示工资信息到列表框中
DisplaySalary();
return TRUE;
}
void CMyDialog::OnOK()
{
// 保存最新的工资信息到文件中
std::ofstream outFile("salary.txt");
if (outFile.is_open())
{
for (auto& salary : m_vecSalaries)
{
outFile << salary.name << " " << salary.id << " " << salary.basicSalary << " " << salary.postAllowance << " " << salary.bonus << " " << salary.medicalInsurance << " " << salary.providentFund << std::endl;
}
outFile.close();
}
CDialog::OnOK();
}
void CMyDialog::OnDestroy()
{
// 保存最新的工资信息到文件中
std::ofstream outFile("salary.txt");
if (outFile.is_open())
{
for (auto& salary : m_vecSalaries)
{
outFile << salary.name << " " << salary.id << " " << salary.basicSalary << " " << salary.postAllowance << " " << salary.bonus << " " << salary.medicalInsurance << " " << salary.providentFund << std::endl;
}
outFile.close();
}
CDialog::OnDestroy();
}
void CMyDialog::InitListCtrl()
{
m_listCtrl.DeleteAllItems();
m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
}
void CMyDialog::DisplaySalary()
{
InitListCtrl();
for (auto& salary : m_vecSalaries)
{
CString strTax;
strTax.Format(_T("%.2f"), salary.tax);
int nIndex = m_listCtrl.InsertItem(m_listCtrl.GetItemCount(), salary.name);
m_listCtrl.SetItemText(nIndex, 1, salary.id);
m_listCtrl.SetItemText(nIndex, 2, std::to_wstring(salary.basicSalary).c_str());
m_listCtrl.SetItemText(nIndex, 3, std::to_wstring(salary.postAllowance).c_str());
m_listCtrl.SetItemText(nIndex, 4, std::to_wstring(salary.bonus).c_str());
m_listCtrl.SetItemText(nIndex, 5, std::to_wstring(salary.medicalInsurance).c_str());
m_listCtrl.SetItemText(nIndex, 6, std::to_wstring(salary.providentFund).c_str());
m_listCtrl.SetItemText(nIndex, 7, strTax);
}
}
void CMyDialog::AddSalary()
{
// 获取控件中的工资信息
UpdateData(TRUE);
// 根据工资信息计算个人所得税
Salary salary;
salary.name = m_strName;
salary.id = m_strID;
salary.basicSalary = m_dBasicSalary;
salary.postAllowance = m_dPostAllowance;
salary.bonus = m_dBonus;
salary.medicalInsurance = m_dMedicalInsurance;
salary.providentFund = m_dProvidentFund;
CalculateTax(salary);
// 添加工资信息到列表框中
m_vecSalaries.push_back(salary);
DisplaySalary();
// 清空控件中的工资信息
m_strName.Empty();
m_strID.Empty();
m_dBasicSalary = 0;
m_dPostAllowance = 0;
m_dBonus = 0;
m_dMedicalInsurance = 0;
m_dProvidentFund = 0;
m_dTax = 0;
UpdateData(FALSE);
}
void CMyDialog::DeleteSalary()
{
// 获取选中的行数
POSITION pos = m_listCtrl.GetFirstSelectedItemPosition();
if (pos == NULL)
{
MessageBox(_T("请先选择一条记录!"), _T("提示"), MB_ICONWARNING);
return;
}
m_nSelectedRow = m_listCtrl.GetNextSelectedItem(pos);
// 删除选中的工资信息
m_vecSalaries.erase(m_vecSalaries.begin() + m_nSelectedRow);
DisplaySalary();
}
void CMyDialog::EditSalary()
{
// 获取选中的行数
POSITION pos = m_listCtrl.GetFirstSelectedItemPosition();
if (pos == NULL)
{
MessageBox(_T("请先选择一条记录!"), _T("提示"), MB_ICONWARNING);
return;
}
m_nSelectedRow = m_listCtrl.GetNextSelectedItem(pos);
// 在控件中显示选中的工资信息
Salary& salary = m_vecSalaries[m_nSelectedRow];
m_strName = salary.name;
m_strID = salary.id;
m_dBasicSalary = salary.basicSalary;
m_dPostAllowance = salary.postAllowance;
m_dBonus = salary.bonus;
m_dMedicalInsurance = salary.medicalInsurance;
m_dProvidentFund = salary.providentFund;
m_dTax = salary.tax;
UpdateData(FALSE);
}
void CMyDialog::SearchSalary()
{
// 获取控件中的查询条件
CString strName;
CString strID;
double dMinSalary;
double dMaxSalary;
UpdateData(TRUE);
strName = m_strName;
strID = m_strID;
UpdateData(FALSE);
// 根据查询条件筛选工资信息
std::vector<Salary> vecResult;
for (auto& salary : m_vecSalaries)
{
if (!strName.IsEmpty() && salary.name != strName)
continue;
if (!strID.IsEmpty() && salary.id != strID)
continue;
double dSalary = salary.basicSalary + salary.postAllowance + salary.bonus - salary.medicalInsurance - salary.providentFund - salary.tax;
if (dSalary < dMinSalary || dSalary > dMaxSalary)
continue;
vecResult.push_back(salary);
}
// 显示筛选结果到列表框中
m_vecSalaries = vecResult;
DisplaySalary();
}
void CMyDialog::CalculateTax(Salary& salary)
{
double dTotalSalary = salary.basicSalary + salary.postAllowance + salary.bonus;
double dTax = 0;
if (dTotalSalary <= 1500)
{
dTax = dTotalSalary * 0.03;
}
else if (dTotalSalary <= 4500)
{
dTax = dTotalSalary * 0.1 - 105;
}
else if (dTotalSalary <= 9000)
{
dTax = dTotalSalary * 0.2 - 555;
}
else if (dTotalSalary <= 35000)
{
dTax = dTotalSalary * 0.25 - 1005;
}
else if (dTotalSalary <= 55000)
{
dTax = dTotalSalary * 0.3 - 2755;
}
else if (dTotalSalary <= 80000)
{
dTax = dTotalSalary * 0.35 - 5505;
}
else
{
dTax = dTotalSalary * 0.45 - 13505;
}
salary.tax = dTax;
}
void CMyDialog::OnBnClickedBtnAdd()
{
AddSalary();
}
void CMyDialog::OnBnClickedBtnDelete()
{
DeleteSalary();
}
void CMyDialog::OnBnClickedBtnEdit()
{
EditSalary();
}
void CMyDialog::OnBnClickedBtnSearch()
{
SearchSalary();
}
```
用C++实现MFC对话框:提供选择录功能,让用户选择需要查找的目标文件夹。 提供文件名 EditBox,接收用户输入的文件名,支持按回车或点击查找按钮触发查找操作。 支持部分匹配或全字匹配选项,支持是否查找子目录和是否包含文件夹名,其中部分匹配、包含子目录、不查找文件央名为默认选项。 列表按照文件全路径排序,表格支持点击表头进行排序。 支持热键触发按钮和选项。 记录历史选项和输入的文件名,再次打开对话框时自动加载上一次的历史。 如果没有历史记录,则路径名默认为当前目录。
好的,以下是实现MFC对话框的代码:
首先,在对话框资源中添加控件,包括一个编辑框、一个选择文件夹按钮、一个“查找”按钮、多个复选框和一个列表框。
在对话框类头文件中添加以下代码:
```
class CMyDlg : public CDialogEx
{
// ...
private:
CString m_strFolderPath; // 保存选择的文件夹路径
CString m_strFileName; // 保存输入的文件名
BOOL m_bPartialMatch; // 部分匹配选项
BOOL m_bSearchSubDir; // 是否查找子目录选项
BOOL m_bIncludeFolder; // 是否包含文件夹名选项
CListCtrl m_lstResult; // 显示查找结果的列表框
// 私有成员函数
void DoSearch(); // 执行查找操作
void LoadHistory(); // 加载历史记录
void SaveHistory(); // 保存历史记录
};
```
在对话框类的实现文件中添加以下代码:
```
void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_FILENAME, m_strFileName);
DDX_Control(pDX, IDC_LIST_RESULT, m_lstResult);
DDX_Check(pDX, IDC_CHECK_PARTIAL, m_bPartialMatch);
DDX_Check(pDX, IDC_CHECK_SUBDIR, m_bSearchSubDir);
DDX_Check(pDX, IDC_CHECK_FOLDER, m_bIncludeFolder);
}
BOOL CMyDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 加载历史记录
LoadHistory();
// 设置列表框风格
m_lstResult.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
// 添加列表框列头
m_lstResult.InsertColumn(0, _T("文件名"), LVCFMT_LEFT, 300);
m_lstResult.InsertColumn(1, _T("路径"), LVCFMT_LEFT, 500);
return TRUE;
}
void CMyDlg::OnBnClickedButtonBrowse()
{
// 打开文件夹选择对话框
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(bi));
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
if (pidl != NULL)
{
TCHAR szFolderPath[MAX_PATH];
SHGetPathFromIDList(pidl, szFolderPath);
m_strFolderPath = szFolderPath;
UpdateData(FALSE);
}
}
void CMyDlg::OnBnClickedButtonSearch()
{
UpdateData(TRUE);
DoSearch();
SaveHistory();
}
void CMyDlg::DoSearch()
{
m_lstResult.DeleteAllItems();
// 枚举文件夹中的文件和子文件夹
CString strSearchPath = m_strFolderPath + _T("\\*.*");
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile(strSearchPath, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
return;
do
{
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// 如果是子文件夹,则递归查找
if (m_bSearchSubDir && _tcscmp(FindFileData.cFileName, _T(".")) != 0 && _tcscmp(FindFileData.cFileName, _T("..")) != 0)
{
CString strSubDirPath = m_strFolderPath + _T("\\") + FindFileData.cFileName;
m_strFolderPath = strSubDirPath;
DoSearch();
}
}
else
{
// 如果是文件,则进行匹配
CString strFilePath = m_strFolderPath + _T("\\") + FindFileData.cFileName;
CString strFileName = FindFileData.cFileName;
CString strFolderName = m_strFolderPath.Mid(m_strFolderPath.ReverseFind('\\') + 1);
if (m_bIncludeFolder)
strFileName = strFolderName + _T("\\") + strFileName;
if (m_bPartialMatch)
{
if (strFileName.Find(m_strFileName) != -1)
{
int nIndex = m_lstResult.InsertItem(m_lstResult.GetItemCount(), strFileName);
m_lstResult.SetItemText(nIndex, 1, strFilePath);
}
}
else
{
if (strFileName.CompareNoCase(m_strFileName) == 0)
{
int nIndex = m_lstResult.InsertItem(m_lstResult.GetItemCount(), strFileName);
m_lstResult.SetItemText(nIndex, 1, strFilePath);
}
}
}
} while (FindNextFile(hFind, &FindFileData));
FindClose(hFind);
}
void CMyDlg::LoadHistory()
{
// 从注册表中读取历史记录
CWinApp* pApp = AfxGetApp();
m_strFolderPath = pApp->GetProfileString(_T("Settings"), _T("FolderPath"), _T(""));
m_strFileName = pApp->GetProfileString(_T("Settings"), _T("FileName"), _T(""));
m_bPartialMatch = pApp->GetProfileInt(_T("Settings"), _T("PartialMatch"), TRUE);
m_bSearchSubDir = pApp->GetProfileInt(_T("Settings"), _T("SearchSubDir"), TRUE);
m_bIncludeFolder = pApp->GetProfileInt(_T("Settings"), _T("IncludeFolder"), FALSE);
// 更新控件值
UpdateData(FALSE);
}
void CMyDlg::SaveHistory()
{
// 保存历史记录到注册表中
CWinApp* pApp = AfxGetApp();
pApp->WriteProfileString(_T("Settings"), _T("FolderPath"), m_strFolderPath);
pApp->WriteProfileString(_T("Settings"), _T("FileName"), m_strFileName);
pApp->WriteProfileInt(_T("Settings"), _T("PartialMatch"), m_bPartialMatch);
pApp->WriteProfileInt(_T("Settings"), _T("SearchSubDir"), m_bSearchSubDir);
pApp->WriteProfileInt(_T("Settings"), _T("IncludeFolder"), m_bIncludeFolder);
}
```
在对话框类的消息映射中添加以下代码:
```
BEGIN_MESSAGE_MAP(CMyDlg, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON_BROWSE, &CMyDlg::OnBnClickedButtonBrowse)
ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CMyDlg::OnBnClickedButtonSearch)
END_MESSAGE_MAP()
```
至此,一个简单的文件查找对话框就实现了。
阅读全文