小程序-文件讀寫(TextFilter)

小程序,文件讀寫:

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章