MFC窗口分割以及各窗口間的通訊


一個偶然的機會又重新接觸了MFC窗口的分割,自己結合資料重新寫了一個窗口分割的程序,現將具體流程跟大家分享一下:

1.我們先創建一個MFC單文檔類的程序,具體分割方式先將單文檔整個客戶區分成兩行一列,首先我們在MFC的CMainFrame類中定義一個CSplitterWnd類的對像m_wndSplitter,在主窗口類中我們可以通過對象m_wndSplitter,調用CSplitterWnd類的所有成員函數,為了將窗口分割成兩行一列,我們在CMainFrame類中重載OnCreateClient函數,在OnCreateClient函數中編寫代碼,我們現將窗口分割:

   CRect rect;
   GetClientRect(&rect); //產生第一次靜態分割
   m_wndSplitter.CreateStatic(this, //父窗口指針
  2,1); //行數與列數

將主窗口分割成兩行一列

然后將分割的窗口與一個特定的類關聯起來。

m_wndSplitter.CreateView(0,0, //窗格的行列序數
  RUNTIME_CLASS(CFengeView),//視圖類

CSize(rect.Width(),rect.Height()-rect.Height()/5),pContext);//父窗口創建參數

m_wndSplitter.CreateView(1,0,RUNTIME_CLASS(Cliftdown),
  CSize(rect.Width(),rect.Height()/5),pContext); //給分割的窗口關聯上對於的類
 //不在調用基類的OncreateClient函數
return true;

這里分割開的兩個窗口一個關聯基礎視類,另一個因為我們要用作一些信息的顯示用,我們創建一個新類,這個新類的基礎類是CEditView,完成后要注意頭文件也要關聯上,否則CMainFrame 不認識新創建的類。運行一下如果報以下錯誤:

                             error C2143: syntax error : missing ';' before '*'
                             error C2501: 'CFengeDoc' : missing storage-class or type specifiers
                             error C2501: 'GetDocument' : missing storage-class or type specifiers

我們在視類的頭文件的開頭添加#include "fengeDoc.h"即可,再次運行

 

 

 

OK接下來我們要在這個基礎上再次進行分割,將第一行分割成兩列,第一行的第一列我們要求它有輸入功能主要是信息的錄入,以及按鈕的添加,第一行的第二列我們要求它一列表的形式顯示

我們添加錄入的信息。為了完成以上功能我們首先添加一個對話框資源,給這個對話框資源關聯上一個新類,新類的基礎類是 CFormView,同時為了能以一個類表的形式顯示錄入的信心我們還有添加一個新的類,這個類的基礎類是CListView,好了類添加完成我們要在第一次分割的基礎上再次分割,這次分割的流程和第一次的思路是一樣的,但要注意幾點不同:1.我們要在基礎視類中添加一個CSplitterWnd類的對像m_wndSplitter1,2.直接在基礎視類中重載OnCreate函數中添加分割代碼具體代碼如下:

 

 

 CRect rect;
 GetClientRect(&rect); //  獲得窗口的創建信息指針
CCreateContext *pContext=(CCreateContext *)lpCreateStruct->lpCreateParams;
m_wndSplitter1.CreateStatic(this,1,2); //產生第二次的靜態分割
 //為第一個窗格產生視圖
m_wndSplitter1.CreateView(0,0,//窗口的行列序數
  RUNTIME_CLASS(Cliftup),//視圖類
CSize(rect.Width()/4,rect.Height()),//
pContext);
//為第二個窗格產生視圖
m_wndSplitter1.CreateView(0,1,RUNTIME_CLASS(Crightup),CSize(1,1),pContext);
return 0;

同時在主視類中添加OnSize函數並在函數中添加代碼:

CView::OnSize(nType, cx, cy);
CRect rect;
GetClientRect(&rect);
int x=rect.Width();
int y=rect.Height();
m_wndSplitter1.MoveWindow(-2,-2,x,y+3);
m_wndSplitter1.SetColumnInfo(0,x/4,0); //左邊窗格位置
m_wndSplitter1.SetColumnInfo(1,x-x/4,0); //右邊窗格位置
m_wndSplitter1.RecalcLayout();

除了要添加上識別頭文件外,還要注意當程序報錯說找不到CListView類時我們在新建的Crightup類的頭文件中添加# include <afxcview.h>。給對話框中的按鈕添加一個消息響應函數,消息響應函數就在對話框所關聯的類下即Cliftup類。為了將我們在對話框中錄入的信息顯示出來,要先創建一個數組用來存放這些信息,這里我們在CFengeDoc類中創建一個CStringArray類型的數字infoArray[4],同時定義一個BOOL類型的變量add;注意一定要在構造函數中給add初始化要不然會報錯的,接下來給對話框的四個編輯框關聯上四個CString類型的變量。分別是m_num,m_name,m_zhuanye,m_home.

下邊我們要做的是把幾塊兒視圖區聯系起來,首先在Cliftup類下的按鈕響應函數中填寫一下代碼:

UpdateData(TRUE);

if(m_num.IsEmpty()||m_name.IsEmpty())

{

AfxMessageBox("填寫不能為空");

return 1;

}

CFengeDoc*pDoc=((CFengeDoc*)GetDocument();

pDoc->InfoArray[0].InsertAt(0,m_num);

pDoc->InfoArray[1].InsertAt(0,m_name);

pDoc->InfoArray[2].InsertAt(0,m_zhuanye);

pDoc->InfoArray[3].InsetAt(0,m_home);

pDoc->add=true; //添加了數據
pDoc->UpdateAllViews(NULL); //更新所有視圖
m_num=_T("");
m_name=_T("");
m_zhuanye=_T("");
m_home=_T("");
UpdateData(FALSE); //各控件的內容清空

接下來在Cliftdown類中重載OnInitialUpdate() 函數,在函數中添加代碼:

CEdit &mEdit=GetEditCtrl(); //獲取編輯視圖的控件
mEdit.SetWindowText("等待用戶輸入學生的信息!");//設置顯示信息
mEdit.EnableWindow(FALSE); //編輯控件不可編輯

再次在Cliftdown類中重載另一個函數OnUpdate,在函數中添加代碼:

CFengeDoc* pDoc=(CFengeDoc*)GetDocument(); // 獲取文檔指針
if(pDoc->add) // 添加了數據
{
CString str;
str="已經成功添加了學號為"+pDoc->infoArray[0].GetAt(0)+"的學生信息!";
CEdit &mEdit=GetEditCtrl(); //獲取編輯視圖控件
mEdit.SetWindowText(str); //顯示信息

}

 

然后再Crightup類中重載函數OnInitialUpdate() ,在函數中添加代碼:

CString m_ColumnLabelStr[]={"學號","姓名","專業","籍貫"};
//表頭字段
CListCtrl& listctrl=GetListCtrl();//獲取列表的控件
DWORD dwStyle = listctrl.GetExtendedStyle();
dwStyle |= LVS_EX_FULLROWSELECT;
// 選中某行使整行高亮(只適用與report風格的listctrl)
dwStyle |= LVS_EX_GRIDLINES;
dwStyle |=LVS_EX_UNDERLINEHOT;
listctrl.SetExtendedStyle(dwStyle);//列表風格
int width[6]={80,80,110,150};
for(int i=0;i<4;i++)
{
listctrl.InsertColumn(i,m_ColumnLabelStr[i],LVCFMT_LEFT,width[i]);

}

 

在Crightup類中重載函數PreCreateWindow並添加代碼:

cs.style=cs.style|LVS_REPORT;// 設置成報告列表的顯示形式

同時再次在Crightup類中重載函數OnUpdate,並在函數中添加代碼:


CFengeDoc* pDoc=(CFengeDoc*)GetDocument(); //獲取文檔指針都要獲取文檔類指針,把文檔類當成了橋梁
if(pDoc->add) //添加了數據
{
CListCtrl& listctrl=GetListCtrl(); // 獲取列表的控件
listctrl.DeleteAllItems(); //刪除所有項
for(int i=0;i<pDoc->infoArray[0].GetSize();i++) //列表框中插入數據
{ listctrl.InsertItem(i,pDoc->infoArray[0].GetAt(i));
listctrl.SetItemText(i,1,pDoc->infoArray[1].GetAt(i));
listctrl.SetItemText(i,2,pDoc->infoArray[2].GetAt(i));
listctrl.SetItemText(i,3,pDoc->infoArray[3].GetAt(i));
}

}

OK現在運行一下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM