小程序,文件讀寫:
1.新建MFC程序,選擇"單文檔"界面,程序名"TextFilter"
2.還是設置一下窗口大小,不然一個小軟件搞個大界面總覺得不好意思^^
在MainFrm.cpp裏,PreCreateWindow(CREATESTRUCT& cs)
修改這個cs可以修改主界面的外觀,
cs.cy = ::GetSystemMetrics(SM_CYSCREEN) / 3; //截面寬度
cs.cx = ::GetSystemMetrics(SM_CXSCREEN) / 3; //界面高度
cs.y = ((cs.cy * 3) - cs.cy) / 2; //界面中心點y座標
cs.x = ((cs.cx * 3) - cs.cx) / 2; //界面中心點x座標
同樣,如果要改變視圖外觀,也可以到"TextFilterView.cpp"裏
的PreCreateWindow修改cs
3.在視圖裏用一個文本框來顯示程序操作狀態
<1>在"TextFilterView.h"裏定義
CRichEditCtrl m_rich;
<2>在"TextFilterView.cpp"的OnCreate(LPCREATESTRUCT lpCreateStruct)中添加:
m_rich.Create(ES_AUTOVSCROLL|ES_MULTILINE|ES_WANTRETURN|
WS_CHILD| WS_VISIBLE|WS_VSCROLL,rect,this,1);
CFont font;
VERIFY(font.CreateFont(16,0,0,0,FW_NORMAL, FALSE, FALSE,0,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS,
"Courier New"));
m_rich.SetFont(&font,1);//設置字體
<3>爲了在界面被放縮的時候,CRichEditCtrl與視圖大小匹配,
在"TextFilterView.cpp"的OnSize中,添加:
CRect rect;
GetClientRect(rect);
m_rich.SetWindowPos(&wndTop,0,0,rect.right-rect.left,
rect.bottom-rect.top,SWP_SHOWWINDOW);
4.下面是打開CFileDialog時選擇文件,並獲得文件路徑,打開文件的操作,先在類
視圖中選擇CTextFilterView,選擇屬性,在"事件"中選擇"ID_FILE_OPEN",添加
OnFileOpen()函數,在"TextFilterView.cpp"的OnFileOpen()中添加以下代碼:
void CTextFilterView::OnFileOpen()
{
if(!IsMissonComplete)
{
AfxMessageBox("上次任務未完成,結束上次任務");
return;
} //檢測是否上次打開的文件關閉
IsMissonComplete=false;
CFileDialog dlg(TRUE,"","*.htm",OFN_HIDEREADONLY |
OFN_OVERWRITEPROMPT |
OFN_ALLOWMULTISELECT);
CString str(" ", 1024);
dlg.m_ofn.lpstrFile=str.GetBuffer(1024);
dlg.m_ofn.nMaxFile=1024;//注意:看最下面
str.ReleaseBuffer();
CString pathName[100];
if(dlg.DoModal()==IDOK)
{
POSITION mPos=dlg.GetStartPosition();
int count=0;
while(mPos!=NULL)
{
pathName[count]=dlg.GetNextPathName(mPos);
count++;
} //獲取所有選擇文件的路徑
m_fileCout=count;//記數(共開了多少文件),m_fileCout是個全局變量
CString fileTitle;
for(int temp=0;temp<count;temp++)
{
char buf[50];
itoa(temp+1,buf,10);
VERIFY(m_file[temp].Open(pathName[temp],CFile::modeReadWrite));
fileTitle=fileTitle+CString(buf)+CString("> ")+
m_file[temp].GetFileName()+
CString(" ---Opened/r/n");
}
m_rich.SetWindowText(fileTitle);//顯示給用戶哪些文件被打開了
}
}
5.在工具欄上放了兩個按鈕,一個是打開文件,一個是過濾選項(比如我要的<center></center>),
點擊"確定"開始過濾.
先添加一個對話框,如圖
爲"過濾選項"按鈕添加事件代碼
void CMainFrame::OnStartFilte()
{
COptionDialog option=new COptionDialog();
option.DoModal();
}
6.爲上面的對話框添加類COptionDialog,爲確定按鈕添加事件處理程序
void COptionDialog::OnBnClickedOk()
{
if(m_fileCout==0)
{
AfxMessageBox("沒有選擇文件哦^^");
return;
}
CString firstToken;
CString secondToken;
CString filteMode;
GetDlgItemText(IDC_EDIT1,firstToken);
GetDlgItemText(IDC_EDIT2,secondToken);
GetDlgItemText(IDC_COMBO1,filteMode);
for(int i=0;i<m_fileCout;i++)
{
//前面提到的m_fileCout是個全局變量,主要是爲了在這裏使用
//把所有文件在這個for循環裏進行處理.
CString pbuf;
CString text;
while( m_file[i].ReadString(pbuf))
{
//讀取文件內容到pbuf中,在放到text中,以待處理
text=text+pbuf+'/r'+'/n';
}
//FilteText函數,處理數據
if( !FilteText(text,firstToken,secondToken,filteMode) )
{
char temp[10];
itoa(i+1,temp,10);
CString FaileMsg="不好意思,第"+CString(temp)+"個文件格式化失敗^^";
AfxMessageBox(FaileMsg);
m_file[i].Close();
continue;
}
m_file[i].SetLength(0);
m_file[i].SeekToBegin();
m_file[i].Write((LPCTSTR)text,text.GetLength());
m_file[i].Close();
}
AfxMessageBox("恭喜恭喜!!搞定^^");
IsMissonComplete=true;
OnOK();
}
7.FilteText是我定義在TextFilter中的一個全局函數:
bool FilteText(CString& resource,CString firstToken,
CString secondToken,CString filteMode)
{
char temp[10];
int start=resource.Find(firstToken);//查找開始標記
if(start==-1)
{
AfxMessageBox("沒找到你要的'開始'標記^^");
return false;
}
int end=resource.Find(secondToken);//查找結束標記
if(end==-1)
{
AfxMessageBox("沒找到你要的'結束'標記^^");
return false;
}
resource.Delete(start,end-start+secondToken.GetLength());
//擦掉標記和標記之間的數據(當然這個程序裏是字符串)
return true;
}
到此,程序就完成了.
-----------------------------------------------------------------------
其中學到了些東東:
I.在MFC框架程序中怎麼定義全局變量和全局函數
[1]在"程序名.h"中聲明變量或函數
extern int m_fileCout;
extern bool FilteText(CString&,CString,CString,CString);
注意:聲明和定義不是一個概念,聲明表示你要定義這個變量或函數,但是還並沒有
分配內存空間這個變量或函數需要在外部定義看[2]
[2]在"程序名.cpp"中定義變量或函數
int m_fileCout;
bool FilteText(CString&,CString,CString,CString){...}
II.要同時選擇打開多個文件,在構造CFileDialog是,要設置OFN_ALLOWMULTISELECT
標記,並且,要設置字符緩衝區,存放獲取的文件名,注意這兩行
CString str(" ", 1024);
dlg.m_ofn.lpstrFile=str.GetBuffer(1024);
dlg.m_ofn.nMaxFile=1024;//最小256
並且注意設置m_ofn.nMaxFile值;(--感謝Cr羣裏Alon的幫助:) )
IIV.在想一個文件寫數據的時候,只調用write函數的話,是把數據附加到文件的末尾,如
果要擦除以前的數據,再寫進新數據,如下
m_file[i].SetLength(0);//設置文件長度0
m_file[i].SeekToBegin();//定位到文件開始位置
m_file[i].Write((LPCTSTR)text,text.GetLength());
OK,就這樣了,睡覺去了^^
-----------------------------------------------------------------
vigor
2004.11.8