📄 readfileview.cpp
字号:
// ReadFileView.cpp : implementation of the CReadFileView class
//
#include "stdafx.h"
#include "ReadFile.h"
#include "ReadFileDoc.h"
#include "ReadFileView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//
//#ifndef WM_UPDATE_DXF_DLG_POS
//#define WM_UPDATE_DXF_DLG_POS WM_USER + 10000
//#endif
//
//#ifndef WM_UPDATE_DXF_DLG_DESTROY
//#define WM_UPDATE_DXF_DLG_DESTROY WM_USER + 10001
//#endif
/////////////////////////////////////////////////////////////////////////////
// CReadFileView
IMPLEMENT_DYNCREATE(CReadFileView, CView)
BEGIN_MESSAGE_MAP(CReadFileView, CView)
//{{AFX_MSG_MAP(CReadFileView)
ON_COMMAND(IDM_READ_DXF_FILE, OnReadDxfFile)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CReadFileView construction/destruction
CReadFileView::CReadFileView()
{
// TODO: add construction code here
}
CReadFileView::~CReadFileView()
{
}
BOOL CReadFileView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CReadFileView drawing
void CReadFileView::OnDraw(CDC* pDC)
{
CReadFileDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CReadFileView printing
BOOL CReadFileView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CReadFileView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CReadFileView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CReadFileView diagnostics
#ifdef _DEBUG
void CReadFileView::AssertValid() const
{
CView::AssertValid();
}
void CReadFileView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CReadFileDoc* CReadFileView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CReadFileDoc)));
return (CReadFileDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CReadFileView message handlers
CStdioFile * g_pFile = NULL;//全局的文件指针
HANDLE g_hMutex = NULL;//互斥量
//发送进度条位置消息的进程
DWORD WINAPI SetProgressPosThreadProc(LPVOID lParam)
{
CDialog * pDlg = (CDialog *)lParam;//传入的进度条对话框指针
if(!pDlg)return 0; //异常判断
DWORD dPos=0; //当前文件指针的位置
DWORD dLength = 1; //文件的长度
DWORD dProssPos = 0; //计算出来的进度条的位置
DWORD dPrePos = 0; //记录前一个进度条的位置
DWORD dw;
dw = WaitForSingleObject(g_hMutex,INFINITE);//等待互斥量有信号
if(dw==WAIT_OBJECT_0) //判断互斥量是否为有信号
{
dLength = g_pFile->GetLength(); //获取文件长度
}
else //废弃的信号,说明读取文件的线程有异常
{
::SendMessage(pDlg->GetSafeHwnd(),WM_UPDATE_DXF_DLG_POS,100,NULL);
//向对话框发送消息, 以销毁对话框
::SendMessage(pDlg->GetSafeHwnd(),WM_UPDATE_DXF_DLG_DESTROY,NULL,NULL);
return 0;
}
ReleaseMutex(g_hMutex);//释放互斥量
while(dPos < dLength)//当文件未读完时执行循环
{
if(!pDlg)return 0;//异常判断
dw = WaitForSingleObject(g_hMutex,INFINITE); //等待互斥量有信号
if(dw==WAIT_OBJECT_0) //等待到信号
{
dPos = g_pFile->GetPosition(); //获取当前文件指针的位置
dProssPos = DWORD(double(dPos) / dLength * 100); //计算进度条的位置
}
else //废弃的信号
{
::SendMessage(pDlg->GetSafeHwnd(),WM_UPDATE_DXF_DLG_POS,100,NULL);
//向对话框发送消息, 以销毁对话框
::SendMessage(pDlg->GetSafeHwnd(),WM_UPDATE_DXF_DLG_DESTROY,NULL,NULL);
return 0;
}
ReleaseMutex(g_hMutex); //释放互斥量
if(dProssPos!=dPrePos) //进度条位置相同时不发送更新消息
{
::SendMessage(pDlg->GetSafeHwnd(),WM_UPDATE_DXF_DLG_POS,dProssPos,NULL);
}
dPrePos = dProssPos; //当前位置变为前一位置
}
//由于计算位置时用的将double 强制转换为 DWORD 型,有可能没有计算到100
//所以需要发送一个消息将进度条位置刷新到100
::SendMessage(pDlg->GetSafeHwnd(),WM_UPDATE_DXF_DLG_POS,100,NULL);
Sleep(500);
//向对话框发送消息, 以销毁对话框
::SendMessage(pDlg->GetSafeHwnd(),WM_UPDATE_DXF_DLG_DESTROY,NULL,NULL);
//文件读取完毕以后要对文件指针进行关闭和销毁
dw = WaitForSingleObject(g_hMutex,INFINITE);
if(dw==WAIT_OBJECT_0)
{
g_pFile->Close();
delete g_pFile;
g_pFile = NULL;
}
else //废弃的信号
{
g_pFile->Close();
delete g_pFile;
g_pFile = NULL;
}
ReleaseMutex(g_hMutex);
return 0;
}
//读取文件的线程
DWORD WINAPI ReadDxfThreadProc(LPVOID lParam)
{
CString strTemp = ""; //存放读取的字符
BOOL bIsEnd = TRUE; //指示文件是否读取完毕
DWORD dw; //互斥量信号结果
while(1)
{
if(!g_pFile)return 0;//异常判断
dw = WaitForSingleObject(g_hMutex,INFINITE);
if(dw==WAIT_OBJECT_0) //互斥量等待到信号
{
bIsEnd = g_pFile->ReadString(strTemp);//读取文件
}
else if(dw==WAIT_ABANDONED)
{
return 0 ;
}
ReleaseMutex(g_hMutex);
if(bIsEnd == FALSE) break;
}
return 0 ;
}
void CReadFileView::OnReadDxfFile()
{
// TODO: Add your command handler code here
//如果对话框没有销毁,说明上一个文件读取线程还没有结束,因此要返回
if(m_ProgressDlg.GetSafeHwnd())
{
MessageBox("文件还未读取完毕! 请稍候!",NULL,MB_OK);
return;
}
CString strFileName = "";
//本实例采用dxf文件为读取的文本文件类型
CFileDialog dlg(TRUE,"dxf","*.dxf",OFN_HIDEREADONLY,
"dxf File (*.dxf)|*.dxf||",NULL);
if(dlg.DoModal()==IDOK)
{
strFileName=CString(dlg.GetFileName());
g_pFile = new CStdioFile(strFileName,CFile::modeRead);//初始化文件指针
m_ProgressDlg.Create();//开始创建非模态对话框
g_hMutex = CreateMutex(NULL,FALSE,NULL);//创建互斥量
//创建读取文件的线程和发送进度条位置消息的进程
//创建SetProgressPosThreadProc线程时将非模态对话框的指针传入
HANDLE hThreads[2];
DWORD dwThreadId; //存放线程ID
hThreads[0] = CreateThread( NULL,0,SetProgressPosThreadProc, &m_ProgressDlg,0,&dwThreadId);
hThreads[1] = CreateThread( NULL,0,ReadDxfThreadProc, NULL,0,&dwThreadId);
CloseHandle(hThreads[0]);
CloseHandle(hThreads[1]);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -