MFC实验报告
实验一
1.1显示一首诗。
在view类的ondraw 函数中添加代码如下:
void CEx11View::OnDraw(CDC* pDC)
{
CEx11Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CString s[4];
s[0]="人生得意须尽欢,莫使金樽空对月。";
s[1]="两岸青山相对出,孤帆一片日边来。";
s[2]="孤帆远影碧空尽,惟见长江天际流。";
s[3]="飞流直下三千尺,疑是银河落九天。";
for(int i=0;i<4;i++)
{
pDC->TextOut(100,100+20*i,s[i]);
}
}
1.2画一个坐标系,画函数的图像。
在view类的ondraw 函数中添加代码如下:
void CEx12View::OnDraw(CDC* pDC)
{
CEx12Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
pDC->SetMapMode(MM_TEXT);
pDC->SetWindowOrg(CPoint(-370,-250));
pDC->MoveTo(0,0);
pDC->LineTo(420,0);
pDC->MoveTo(0,0);
pDC->LineTo(0,-220);
pDC->MoveTo(0,0);
pDC->LineTo(-420,0);
pDC->MoveTo(0,0);
pDC->LineTo(0,220);
// pDC->TextOut(50,10,"1");
CStringArray p;
p.SetSize(8,-1);
p[0]="-1";p[1]="-2";p[2]="-3";p[3]="-4";p[4]="-5";p[5]="-6";p[6]="-7";p[7]="-8";
for(int i=1;i<=8;i++)
{pDC->MoveTo(i*(-50),-10);
pDC->LineTo(i*(-50),+10);
pDC->TextOut(i*(-50),10,p[i-1]);
}
CStringArray s;
s.SetSize(8,-1);
s[0]="1";s[1]="2";s[2]="3";s[3]="4";s[4]="5";s[5]="6";s[6]="7";s[7]="8";
for(int i=1;i<=8;i++)
{pDC->MoveTo(i*50,-10);
pDC->LineTo(i*50,+10);
pDC->TextOut(i*50,10,s[i-1]);
}
int x,y,j;float a;
pDC->MoveTo(0,0);
for(j=0;j<=315;j++)
{x=j;
a=j;
y=-50*sin(a/50);
pDC->LineTo(x,y);}
pDC->MoveTo(0,0);
for(j=0;j>=-315;j--)
{x=j;
a=j;
y=-50*sin(a/50);
pDC->LineTo(x,y);}
}
1.3显示资源中的一幅位图。
1.3.1在资源视图中找到Bitmap右键添加一个位图 ID_BITMAP1
1.3.2在view类的属性找到消息并添加函数
1.3.2在函数OnEraseBkgnd中添加代码如下:
BOOL CEx13View::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
BITMAP bmp;
bitmap.GetBitmap(&bmp);
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(pDC);
dcCompatible.SelectObject(&bitmap);
CRect rect(0,0,500,500);
GetClientRect(&rect);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY); //原位图
pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&dcCompatible, //可对位图进行伸缩
0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); //可对位图进行伸缩
return TRUE;
return CView::OnEraseBkgnd(pDC);
}
1.4GDI绘图之鼠标绘图.
1.4.1画笔
1.4.1.1在view类中添加变量 CString m_ptPrev;
1.4.1.2在view类中添加消息响应函数OnLButtonDown
void CEx141View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
SetCapture();
m_ptPrev=point;
CView::OnLButtonDown(nFlags, point);
}
1.4.1.3在view类中添加消息响应函数OnLButtonUp
void CEx141View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(GetCapture()!=this)
return;
CClientDC dc(this);
dc.MoveTo(m_ptPrev);
dc.LineTo(point);
ReleaseCapture();
CView::OnLButtonUp(nFlags, point);
}
1.4.1.4在view类中添加消息响应函数OnMouseMove
void CEx141View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(GetCapture()!=this)
return;
CClientDC dc(this);
dc.MoveTo(m_ptPrev);
dc.LineTo(point);
m_ptPrev=point;
CView::OnMouseMove(nFlags, point);
}1.4.2绘制直线
在view 类中添加变量
CPoint m_bMouseDown;
CPoint m_ptStart;
CPoint m_ptOld;
CPoint m_hCross;
CPoint m_hArrow;
CPoint nFlags;
CPoint point;
void CEx142View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
// TODO: Add your message handler code here and/or call default
m_bMouseDown = true;
m_ptStart = point;
m_ptOld = point;
SetCapture();
CRect rect;
GetClientRect(&rect);
ClientToScreen(&rect);
ClipCursor(&rect);
SetCursor(m_hCross); //设置鼠标形状为十字形
CView::OnLButtonDown(nFlags, point);
}
void CEx142View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if( m_bMouseDown )
{
m_bMouseDown = false;
ReleaseCapture();
ClipCursor( NULL );
CClientDC dc(this);
dc.SetROP2( R2_NOT );
dc.MoveTo( m_ptStart ); //这两行代码擦除从起点(鼠标按下点)到
dc.LineTo( m_ptOld ); //上次鼠标移动到的位置之间的临时线
dc.SetROP2( R2_COPYPEN );
dc.MoveTo( m_ptStart ); //这两行代码从起点到鼠标当前位置画线
dc.LineTo( point ); //
CEx142Doc *pDoc = GetDocument(); //得到文档类指针
pDoc->m_line = new CLine(m_ptStart,point); //创建CLine对象
pDoc->m_LineList.AddTail( pDoc->m_line); //将pLine加入到链表中
pDoc->SetModifiedFlag(); // Mark the document as having been modified, for
// purposes of confirming File Close.
//pDoc->UpdateAllViews(this, 0L,pLine);
SetCursor(m_hArrow); //设置鼠标形状为标准箭头形
}
CView::OnLButtonUp(nFlags, point);
}
1.4.3画矩形
void CEx143View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_bMouseDown = true;
m_ptStart = point;
m_ptOld = point;
SetCapture();
CRect rect;
GetClientRect(&rect);
ClientToScreen(&rect);
ClipCursor(&rect);
//SetCursor(m_hCross);
CView::OnLButtonDown(nFlags, point);
}
void CEx143View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if( m_bMouseDown )
{
m_bMouseDown = false;
ReleaseCapture();
ClipCursor( NULL );
CClientDC dc(this);
dc.SetROP2( R2_NOT );
//dc.MoveTo( m_ptStart ); //这两行代码擦除从起点(鼠标按下点)到
//dc.LineTo( m_ptOld );
dc.Rectangle(m_ptStart.x,m_ptStart.y,m_ptOld.x,m_ptOld.y);//上次鼠标移动到的位置之间的临时线
dc.SetROP2( R2_COPYPEN );
//dc.MoveTo( m_ptStart ); //这两行代码从起点到鼠标当前位置画线
//dc.LineTo( point ); //
dc.Rectangle(m_ptStart.x,m_ptStart.y,point.x,point.y);
//CEx142Doc *pDoc = GetDocument(); //得到文档类指针
//pDoc->m_line = new CLine(m_ptStart,point); //创建CLine对象
//pDoc->m_LineList.AddTail( pDoc->m_line); //将pLine加入到链表中
//pDoc->SetModifiedFlag(); // Mark the document as having been modified, for
// purposes of confirming File Close.
//pDoc->UpdateAllViews(this, 0L,pLine);
//SetCursor(m_hArrow); //设置鼠标形状为标准箭头形
}
CView::OnLButtonUp(nFlags, point);
}
void CEx143View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if( m_bMouseDown )
{
CClientDC dc(this);
dc.SetROP2( R2_NOT );//绘制模式
//dc.MoveTo( m_ptStart ); //这两行代码擦除从起点(鼠标按下点)到
//dc.LineTo( m_ptOld ); //上次鼠标移动到的位置之间的临时线
dc.Rectangle(m_ptStart.x,m_ptStart.y,m_ptOld.x,m_ptOld.y);
dc.MoveTo( m_ptStart ); //这两行代码从起点到鼠标当前位置画线
//dc.LineTo( point ); //
dc.Rectangle(m_ptStart.x,m_ptStart.y,point.x,point.y);
m_ptOld = point; //鼠标当前位置在下一次鼠标移动事件看来就是"旧位置"
}
CView::OnMouseMove(nFlags, point);
}
实验二
2.1求两正整数的最大公约数和最小公倍速数,用一个函数求最大公约数,另一个函数求最小公倍数。要求 : 两正整数从对话框输入。将最大公约数和最小公倍数在ondraw()函数中输出
2.1.1
2.1.1..1.制作一个对话框,并添加一个对话框类MyDialog
.
2.1.1.2.为Edit Control 空间添加2个变量
int num1;
int num2;
2.1.1.3在view类中添加2个变量 int result ; int result1 ;
2.1.1.4在MyDialog类中添加2个函数,用以求出最大公约数和最小公倍数。
int MyDialog::maxiume(int a, int b)
{
int max=0;
for(int i=1;i<(a>b?b:a);i++)
{
if(a%i==0&&b%i==0)
{
if(max<i)
{
max=i;
}
}
}
return max;
}
int MyDialog::miniume(int c, int d)
{
int min=0;
for(int i=0;i<=c;i++)
{
for(int j=1;j<=d;j++)
{
if(c*j==d*i)
{
min=c*j;
break;
}
}
if(min!=0)
break;
}
return min;
}
2.1.1.5 为button1(最大公约数)工具添加一个事件处理函数
void MyDialog::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
result=maxiume(num1,num2);
CDC* pDC=GetDC();
CString str;
str.Format(_T("%d"),result);
pDC->TextOut(100,100,str);
}
2.1.1.6为button2(最小公倍数)工具添加一个事件处理函数
void MyDialog::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
result1=miniume(num1,num2);
CDC* pDC=GetDC();
CString str1;
str.Format(_T("%d"),result1);
pDC->TextOut(200,150,str1);
}
2.1.2菜单项
2.1.2.1在菜单中添加一个选项
2.1.2.2为菜单项添加一个事件处理函数以弹出对话框
在view头文件中添加一个变量 MyDialog dlg;
在事件处理函数中添加代码
void CEx21View::OnDialog()
{
// TODO: 在此添加命令处理程序代码
dlg.DoModal();
}
2.1.3要点总结
2.1.3.1 UpdateData(true);为传值函数,将输入的文本赋予变量。
2.1.3.2 CDC* pDC=GetDC();获取view类的OnDraw函数功能。
2.1.3.3 变量result ,result1为int型,应该用
CString str1;
str.Format(_T("%d"),result1);
语句转化成CString型
2.1.3.4 pDC->TextOut(200,150,str1);一次只能输出一个值,分2个按钮输出结果。
2.1.3.5 dlg.DoModal();语句触发对话框。
实验三
3.1编写一个单文档应用程序Ex5。在主菜单中增加【曲线】、【线宽】和【颜色】3个菜单项,【曲线】菜单中包含【正弦】和【余弦】两个菜单项;【线宽】菜单中包含【线宽2】和【线宽3】两个菜单项;【颜色】菜单中包含【红色】和【蓝色】两个菜单项。为该应用程序创建一个新工具栏和一个快捷菜单,工具栏包含4个按钮,分别与菜单项【线宽2】、【线宽3】、【红色】和【蓝色】相对应,快捷菜单上有【正弦】、【余弦】、【线宽2】、【线宽3】、【红色】和【蓝色】6个菜单项。在状态栏中增加一个窗格,用来显示曲线的类型、线宽以及颜色的提示信息。
3.2实验步骤
3.2.1制作菜单项,快捷菜单项,按钮项将对应选项ID分别设为
正弦 ID_SINE
余弦 ID_COSINE
线宽2 ID_DRAW_LINE2
线宽3 ID_DRAW_LINE3
红色 ID_SETLINE_RED
蓝色 ID_SETLINE_BLUE
3.2.2为菜单项添加click 事件
在view类的头文件中添加变量:
public:
int OperationType;//曲线类型
int LineType; //线宽
int ColorType; //颜色
void CEx5View::OnSine( )
{
// TODO: 在此添加命令处理程序代码
OperationType=1;
OnDraw(NULL);
this->Invalidate(true);
}
void CEx5View::OnCosine()
{
// TODO: 在此添加命令处理程序代码
OperationType=2;
OnDraw(NULL);
this->Invalidate(true);
}
void CEx5View::OnDrawLine2()
{
// TODO: 在此添加命令处理程序代码
LineType=5;
OnDraw(NULL);
this->Invalidate(true);
}
void CEx5View::OnDrawLine3()
{
// TODO: 在此添加命令处理程序代码
LineType=16;
OnDraw(NULL);
this->Invalidate(true);
}
void CEx5View::OnSetlineRed()
{
// TODO: 在此添加命令处理程序代码
ColorType=2;
OnDraw(NULL);
this->Invalidate(true);
}
void CEx5View::OnSetlineBlue()
{
// TODO: 在此添加命令处理程序代码
ColorType=3;
OnDraw(NULL);
this->Invalidate(true);
}
3.2.3
为快捷菜单添加代码:
在mainframe的头文件中添加:
public:
CToolBar m_wndMYToolBar;
在mainframe.cpp中的OnCreate函数中添加:
if (!m_wndMYToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_TOOLBAR1))
{
TRACE0("未能创建工具栏\n");
return -1; // 未能创建
}
// TODO: 如果不需要可停靠工具栏,则删除这三行
m_wndMYToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndMYToolBar);
在mainframe类中重写函数OnContextMenu
void CMainFrame::OnContextMenu(CWnd* pWnd, CPoint point)
{
// TODO: 在此处添加消息处理程序代码
CMenu menu;
if (menu.LoadMenu(IDR_POPUP_MENU))
{
CMenu *pPopup=menu.GetSubMenu(0);
pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y,this);
}
}
3.2.4添加画法代码
在view类的OnDraw函数中添加:
void CEx5View::OnDraw(CDC* pDC)
{
CEx5Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CClientDC pc(this);
pc.SetMapMode(MM_TEXT);
pc.SetWindowOrg(CPoint(-300,-300));
pc.MoveTo(0,0);
pc.LineTo(420,0);
pc.MoveTo(0,0);
pc.LineTo(0,-220);
//pc->TextOut(50,10,"1");
CStringArray s;
s.SetSize(8,-1);
s[0]="1";s[1]="2";s[2]="3";s[3]="4";s[4]="5";s[5]="6";s[6]="7";s[7]="8";
for(int i=1;i<=8;i++)
{pc.MoveTo(i*50,-10);
pc.LineTo(i*50,+10);
pc.TextOut(i*50,10,s[i-1]);
}
int x,y,j;float a;
pc.MoveTo(0,0);
CPen Pen;
switch (ColorType)
{
case 2:
Pen.CreatePen(PS_SOLID,LineType,RGB(255,0,0));
break;
case 3:
Pen.CreatePen(PS_SOLID,LineType,RGB(0,0,255));
break;
}
CPen *OldPen=pc.SelectObject(&Pen);
switch(OperationType)
{
case 1:
for(j=0;j<=400;j++)
{
x=j;
a=j;
y=-50*sin(a/50);
pc.LineTo(x,y);}
break ;
case 2:
for(j=0;j<=400;j++)
{
x=j;
a=j;
y=-50*cos(a/50);
pc.LineTo(x,y);}
break ;
}
pc.SelectObject(OldPen);
// TODO: 在此处为本机数据添加绘制代码
}
3.2.5状态栏
在mainframe的头文件中添加:
public:
CStatusBar m_wndStatusBar;
在mainframe中的数组
static UINT indicators[] =
{
ID_SEPARATOR, // 状态行指示器
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
中添加3个ID:
ID_LINE_TYPE;
ID_LINE_COLOR;
ID_LINE_SYM;
在mainframe的OnCreate函数中添加
m_wndStatusBar.SetPaneInfo(1,ID_LINE_TYPE,SBPS_POPOUT,50);
m_wndStatusBar.SetPaneInfo(2,ID_LINE_COLOR,SBPS_POPOUT,50);
m_wndStatusBar.SetPaneInfo(2,ID_LINE_SYM,SBPS_POPOUT,50);
实验四
4.1 自定义一个学生信息类,包括学生姓名,电话,地址,学号。使用链表模板存贮班级学生信息,使用Cformview显示,要求有数据导航功能(参考.附件1,)
4.1.1制作一个对话框
4.1.1.1在view类中添加对话框相应控件的变量
CString StuName;
int StuGrade;
CString StuAddress;
int StuNumber;
4.1.1.2插入3个函数以获取、删除和插入对话框输入的信息
void CEx41View::GetInfo(POSITION position){
if(position){
Student* student=m_pList->GetAt(position);
StuName=student->StuName;
StuGrade=student->StuGrade;
StuAddress=student->StuAddress;
StuNumber=student->StuNumber;
}else{
GetInfo();
}
UpdateData(false);
}
void CEx41View::GetInfo(){
StuName="";
StuGrade=0;
StuAddress="";
StuNumber=0;
UpdateData(false);
((CDialog*)this)->GotoDlgCtrl(GetDlgItem(IDC_STU_NAME));
}
void CEx41View::InsertStudent(POSITION position){
if(UpdateData(true)){
Student* student=new Student();
student->StuName=StuName;
student->StuGrade=StuGrade;
student->StuAddress=StuAddress;
student->StuNumber=StuNumber;
m_position=m_pList->InsertAfter(m_position, student);
}
}
4.1.1.3添加消息处理函数DoDataExchange、OnInitialUpdate和OnUpdate
void CEx41View::DoDataExchange(CDataExchange* pDX)
{
// TODO: 在此添加专用代码和/或调用基类
CFormView::DoDataExchange(pDX);
DDX_Text(pDX, IDC_STU_NAME, StuName);
DDV_MaxChars(pDX, StuName, 30);
DDX_Text(pDX, IDC_STU_GRADE, StuGrade);
DDV_MinMaxInt(pDX, StuGrade, 0, 100);
DDX_Text(pDX, IDC_STU_ADRESS, StuAddress);
DDV_MaxChars(pDX, StuAddress, 50);
DDX_Text(pDX, IDC_STU_NUMBER, StuNumber);
DDV_MinMaxInt(pDX, StuNumber, 0, 999999);
}
void CEx41View::OnInitialUpdate()
{
// TODO: 在此添加专用代码和/或调用基类
m_pList=GetDocument()->GetList();
CFormView::OnInitialUpdate();
}
void CEx41View::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
// TODO: 在此添加专用代码和/或调用基类
m_position=m_pList->GetHeadPosition();
}
4.1.1.4为控件clear添加事件处理函数
void CEx41View::OnBnClickedStuClear()
{
// TODO: 在此添加控件通知处理程序代码
GetInfo();
}
4.1.2制作一个菜单项
为菜单项添加消息处理函数
Command型
void CEx41View::OnStuInsert()
{
// TODO: 在此添加命令处理程序代码
TRACE("Entering CEx41View::OnStuInsert\n");
InsertStudent(m_position);
GetDocument()->SetModifiedFlag();
GetDocument()->UpdateAllViews(this);
}
void CEx41View::OnStuDelete()
{
// TODO: 在此添加命令处理程序代码
POSITION pos;
if((pos=m_position)!=NULL){
m_pList->GetNext(pos);
if(pos==NULL){
pos=m_pList->GetHeadPosition();
if(pos==m_position){
pos=NULL;
}
}
GetInfo(pos);
Student* stu=m_pList->GetAt(m_position);
m_pList->RemoveAt(m_position);
delete stu;
m_position=pos;
GetDocument()->SetModifiedFlag();
GetDocument()->UpdateAllViews(this);
}
}
void CEx41View::OnStuFirst()
{
// TODO: 在此添加命令处理程序代码
if(!m_pList->IsEmpty()){
m_position=m_pList->GetHeadPosition();
GetInfo(m_position);
}
}
void CEx41View::OnStuPrevious()
{
// TODO: 在此添加命令处理程序代码
POSITION pos;
if((pos=m_position)!=NULL){
m_pList->GetPrev(pos);
if(pos){
GetInfo(pos);
m_position=pos;
}
}
}
void CEx41View::OnStuNext()
{
// TODO: 在此添加命令处理程序代码
POSITION pos;
if((pos=m_position)!=NULL){
m_pList->GetNext(pos);
if(pos){
GetInfo(pos);
m_position=pos;
}
}
}
void CEx41View::OnStuLast()
{
// TODO: 在此添加命令处理程序代码
if(!m_pList->IsEmpty()){
m_position=m_pList->GetTailPosition();
GetInfo(m_position);
}
}
Update型
void CEx41View::OnUpdateStuFirst(CCmdUI *pCmdUI)
{
// TODO: 在此添加命令更新用户界面处理程序代码
POSITION pos;
pos=m_pList->GetHeadPosition();
pCmdUI->Enable((m_position!=NULL)&&(pos!=m_position));
}
void CEx41View::OnUpdateStuLast(CCmdUI *pCmdUI)
{
// TODO: 在此添加命令更新用户界面处理程序代码
POSITION pos;
pos=m_pList->GetTailPosition();
pCmdUI->Enable((m_position!=NULL)&&(pos!=m_position));
}
void CEx41View::OnUpdateStuDelete(CCmdUI *pCmdUI)
{
// TODO: 在此添加命令更新用户界面处理程序代码
pCmdUI->Enable(m_position!=NULL);
}
4.2对附件3加以修改,增加对颜色,笔宽的处理(参考附件2)
做以下修改:
4.2.1在view类中加入2个变量
protected:
CStroke* m_pStrokeCur; // the stroke in progress
CPoint m_ptPrev; // the last mouse pt in the stroke in progress
4.2.2加入3个消息处理函数:
void CScribbleView::OnLButtonDown(UINT, CPoint point)
{
// Pressing the mouse button in the view window starts a new stroke
m_pStrokeCur = GetDocument()->NewStroke();
// Add first point to the new stroke
m_pStrokeCur->m_pointArray.Add(point);
SetCapture(); // Capture the mouse until button up.
m_ptPrev = point; // Serves as the MoveTo() anchor point for the
// LineTo() the next point, as the user drags the
// mouse.
return;
}
void CScribbleView::OnLButtonUp(UINT, CPoint point)
{
// Mouse button up is interesting in the Scribble application
// only if the user is currently drawing a new stroke by dragging
// the captured mouse.
if (GetCapture() != this)
return; // If this window (view) didn't capture the mouse,
// then the user isn't drawing in this window.
CScribbleDoc* pDoc = GetDocument();
CClientDC dc(this);
CPen* pOldPen = dc.SelectObject(pDoc->GetCurrentPen());
dc.MoveTo(m_ptPrev);
dc.LineTo(point);
dc.SelectObject(pOldPen);
m_pStrokeCur->m_pointArray.Add(point);
ReleaseCapture(); // Release the mouse capture established at
// the beginning of the mouse drag.
return;
}
void CScribbleView::OnMouseMove(UINT, CPoint point)
{
// Mouse movement is interesting in the Scribble application
// only if the user is currently drawing a new stroke by dragging
// the captured mouse.
if (GetCapture() != this)
return; // If this window (view) didn't capture the mouse,
// then the user isn't drawing in this window.
CClientDC dc(this);
m_pStrokeCur->m_pointArray.Add(point);
// Draw a line from the previous detected point in the mouse
// drag to the current point.
CPen* pOldPen = dc.SelectObject(GetDocument()->GetCurrentPen());
dc.MoveTo(m_ptPrev);
dc.LineTo(point);
dc.SelectObject(pOldPen);
m_ptPrev = point;
return;
}
4.2.3在OnDraw函数中加入代码:
void CScribbleView::OnDraw(CDC* pDC)
{
CScribbleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// The view delegates the drawing of individual strokes to
// CStroke::DrawStroke().
CTypedPtrList<CObList,CStroke*>& strokeList = pDoc->m_strokeList;
POSITION pos = strokeList.GetHeadPosition();
while (pos != NULL)
{
CStroke* pStroke = strokeList.GetNext(pos);
pStroke->DrawStroke(pDC);
}
}
实验五
5.1实验内容
(1)使用单文档应用研究程序及分裂视图方法,左窗格使用CformView,添加两个列表框,一个设定颜色红、绿、兰;一个设定sin( )、cos( );右窗格使用Cview, 画一个坐标系,显示正余弦图像。
(2)参考msdn示例之mdi;在多文档应用程序框架下使用菜单分别打开两个不同的文档。一个文档及相关视图用来进行诗行显示;另一个实现正、余弦曲线显示。. 诗行显示,正、余弦曲线显示由菜单控制。
5.2制作过程
5.2.1建立一个工程Curve 并在原工程中选择 添加—>现有项—>CurveView.h/CurveView.cpp
在MainFrm.cpp中添加
#include "CurveView.h"
在CurveView.cpp中添加
#include "stdafx.h"
#include "Ex5.h"
#include "Ex5View.h"
#include "MainFrm.h"
#include "Ex5Doc.h"
#include "math.h"
在CurveView.h的#pragma once上方添加:
#include "Ex5Doc.h"
5.2.1.1CurveView.cpp
5.2.1.1.1在Curve类中添加2个变量
public:
int m_string;
int color;
在视图类的头文件中加上#include "math.h"
5.2.1.1.2在OnDraw函数中添加画sin和cos曲线的代码
void CCurve::OnDraw(CDC* pDC)
{
CEx5Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
//画出坐标系
CRect rectClient;
GetClientRect(rectClient);
pDC->SetMapMode (MM_ANISOTROPIC);
pDC->SetWindowExt (1000,1000);
pDC->SetViewportExt (rectClient.right ,-rectClient.bottom );
pDC->SetViewportOrg (rectClient.right /2,rectClient.bottom /2);
//pDC->Ellipse (-500,500,500,-500);
pDC->MoveTo (-500,0);
pDC->LineTo (500,0);
pDC->MoveTo (500,0);
pDC->LineTo (490,10);
pDC->MoveTo (500,0);
pDC->LineTo (490,-10);
pDC->MoveTo (0,-500);
pDC->LineTo (0,500);
pDC->MoveTo (0,500);
pDC->LineTo (-10,490);
pDC->MoveTo (0,500);
pDC->LineTo (10,490);
for(int i=-4;i<=4;i++)
{
CString str;
str.Format (_T("%d"),i);
pDC->MoveTo (i*100,-5);
pDC->LineTo (i*100,+5);
pDC->TextOutW (i*100,-5,str);
}
for(int i=-1;i<=1;i++)
{
if(i==0)
continue;
CString str;
str.Format (_T("%d"),i);
pDC->MoveTo (-5,i*100);
pDC->LineTo (+5,i*100);
pDC->TextOutW (+5,i*100,str);
}
m_string=pDoc->m_string;
color=pDoc->color;
CPen pen;
//选择颜色
switch(color){
case 0:
pen.CreatePen(PS_SOLID,3,RGB(255,0,0));
break;
case 1:
pen.CreatePen(PS_SOLID,3,RGB(0,0,255));
break;
case 2:
pen.CreatePen(PS_SOLID,3,RGB(0,255,0));
break;
}
CPen* oldPen=pDC->SelectObject(&pen);
//选择线形
switch(m_string)
{case 0:
pDC->MoveTo (-400,(int)100*sin((float)-4));
for(int i=-400;i<=400;i++)
{
float ix,iy;
int y;
ix=(float)i/100;
iy=sin(ix);
y=(int)100*iy;
pDC->LineTo (i,y);
}
break;
case 1:
pDC->MoveTo (-400,(int)100*cos((float)-4));
for(int i=-400;i<=400;i++)
{
float ix,iy;
int y;
ix=(float)i/100;
iy=cos(ix);
y=(int)100*iy;
pDC->LineTo (i,y);
}
break;
}
pDC->SelectObject(oldPen);
}
5.2.2在MainFrame类中重写函数OnCreateClient,在头文件中加入
public:
CSplitterWnd m_wndSplitter;
在MainFrame.cpp中加入头文件
#include "CurveView.h"
#include "Ex5View.h"
并添加代码:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
CCreateContext* pContext)
{
/*return m_wndSplitter.Create(this,
2, 2, // TODO: 调整行数和列数
CSize(10, 10), // TODO: 调整最小窗格大小
pContext);*/
VERIFY(m_wndSplitter.CreateStatic(this,1,2));
VERIFY(m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CEx5View),CSize(100,100),pContext));
VERIFY(m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CCurveView),CSize(100,100),pContext));
return true;
}
5.2.3制作一个对话框
设置
设置3个控件ID依次为 :
IDC_LIST1
IDC_LIST2
IDC_BUTTON1
为3个控件添加Ex5View的事件处理函数:
void CEx5View::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CWnd * pwnd;
pwnd=GetDlgItem( IDC_STATIC);
CDC* pDC=pwnd->GetDC ( );
pDC->Ellipse (0,0,100,100);
}
void CEx5View::OnLbnSelchangeList1()
{
// TODO: 在此添加控件通知处理程序代码
CEx5Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CListBox *pCtrl = (CListBox *)GetDlgItem( IDC_LIST1 ) ;
m_string=pCtrl->GetCurSel();
pDoc->m_string =m_string;
pDoc->UpdateAllViews (NULL);
}
void CEx5View::OnLbnSelchangeList2()
{
// TODO: 在此添加控件通知处理程序代码
CEx5Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CListBox *pCtrl = (CListBox *)GetDlgItem( IDC_LIST2 ) ;
color=pCtrl->GetCurSel();
pDoc->color =color;
pDoc->UpdateAllViews (NULL);
}
5.2.4
重写函数OnInitialUpdate
void CEx5View::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
CListBox *ptrl=(CListBox*)GetDlgItem(IDC_LIST1);
ptrl->AddString(_T("sin(x)"));
ptrl->AddString(_T("cos(x)"));
ptrl->SetCurSel(0);
CListBox *ptrl2=(CListBox*)GetDlgItem(IDC_LIST2);
ptrl2->AddString(_T("红"));
ptrl2->AddString(_T("绿"));
ptrl2->AddString(_T("蓝"));
ptrl2->SetCurSel(0);
}
5.2.5