新建一个基于对话框的工程,将其界面设计成如下所示:
为"统计"按钮与"..."按钮建立类向导,同时为三个编辑框关联非控件变量,为"统计"按钮关联控件变量。并初始化:
void CCharCountDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCharCountDlg)
DDX_Control(pDX, IDSTAT, m_stat);
DDX_Text(pDX, IDC_EDIT1, m_path);
DDX_Text(pDX, IDC_EDIT2, m_ascii);
DDX_Text(pDX, IDC_EDIT3, m_Sinology);
//}}AFX_DATA_MAP
}
CCharCountDlg::CCharCountDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCharCountDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCharCountDlg)
m_path = _T("");
m_ascii = _T("");
m_Sinology = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
下面就是两个类向导的关联事件:
void CCharCountDlg::OnBrower()
{
CFileDialog filedialog(true,NULL,NULL,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
"文本文件(*.txt)|*.txt||");
if (filedialog.DoModal() == IDOK)
{
m_path = filedialog.GetPathName();
m_stat.EnableWindow(true);
UpdateData(false);
}
}
void CCharCountDlg::OnStat()
{
UpdateData();//把控件的值更新到成员变量
HANDLE hThread = CreateThread(NULL, 0, ThreadProc, this, 0, NULL);
::WaitForSingleObject(hThread, INFINITE);
UpdateData(false);//把成员变量的值更新到控件
}
接着就是线程函数的实现代码:
DWORD __stdcall ThreadProc(LPVOID pParam)
{
CCharCountDlg *dlg = (CCharCountDlg *)pParam;
CFile file(dlg->m_path,CFile::modeRead);
int size = file.GetLength();
int i = 0;
int ascii = 0;
int sinology = 0;
char str;
while (i < size)
{
file.Read(&str,1);
if (!isascii(str))
{
i += 2;
sinology++;
file.Seek(1,CFile::current);
}
else
{
i++;
ascii++;
}
}
file.Close();
dlg->m_ascii.Format("%d",ascii);
dlg->m_Sinology.Format("%d",sinology);
return 0;
}
代码实现:
这篇文章涉及到的知识点很多,比如线程的知识,对于线程,我之前研究了很多,并写了很多心得文章,例如《worker线程与UI线程的学习》《线程学习心得浅析》等等很多的文章,你可以找找,其次就是CFile类的成员方法的使用了,有兴趣的话,你可以研究研究。还有就是《UpdateData函数的运行机制及源代码分析》,我都写了文章。