第一篇:MFC 对话框编程 -- 总结
MFC 对话框编程--总结
一、创建对话框对象
1.首先利用资源编辑器创建对话框资源,并针对该对话框资源定义一个对话框类:classCTestDlg :public CDialog
2.创建话话框对象
模态对话框的创建:
如:
CTestDlgdlg;
dlg.DoModal();
非模态对话框创建:
如:
CTestDlgdlg;
dlg.Create(IDD_DIALOG, this);
但这样是得不到一个正常显示的非模态对话框的。因为模态与非模态对话框的实现方式并不相同,这里我们还要注意几点。
非模态对话框创建完成后是隐藏着的,必须调用ShowWindow来进行显示。
对于模态对话框,当执行到DoModal 函数以创建对话框时,程序会暂停执行,直至模态对话框关闭。所以创建模态对话框可以采用局部对象。
但是,对于非模态对话框,当执行Create函数时并不会暂停执行,当执行到大括号“}后Dlg局部对象被销毁生命周期结束,于是异常出现了。
解决方法有两个:
一、在View类中定义一个CTestDlg 成员变量。
二、动态创建一个CTestDlg 变量,并重写CTestDlg 类的 PostNcDestroy函数,在该函数里销毁对象 deletethis;
无论创建的是模态对话框,还是非模态对话框,当我们单击确定或取消按钮后对话框都会消失。但这时低层的操作却是不同的。
对于模态对话框,此时对话框对象的确是被销毁了,但对于非模态对话框,这时只是隐藏起来不再显示。这需要我们自己调用DestoryWindow函数来进行销毁工作。
这时我们必须重写 CTestDlg 的 OnOK、OnCancel 两个函数(这两个是基类CDialog的虚函数),在这两个函数内调用DestroyWindow函数,并注意不再调用基类CDialog相应的函数。正确地创建非模态对话框的代码如下:
CTestDlg*pDlg = new CTestDlg;
pDlg->Create(IDD_DIALOG, this);
pDlg->ShowWindow(SW_SHOW);
同时,在CTestDlg 类的 PostNcDestroy函数中销毁对象:deletethis;
二、动态创建按钮
1.在对话框类CTestDlg 中定义一个 CButton 类对象,作为其成员变量。
2.在相应的消息处理中,调用 CButton类的Create函数创建按钮。
要注意两点:
如果在调用CButton::Create创建按钮时没有指定WS_VISIBLE 风格,那么随后一定要调用这个按钮对象的ShowWindow函数,来将该按钮显示出来。
为防止该CButton关联多个按钮,这里需要进行一些设置,如下:
if(!m_btn.m_hwnd)
{
// CButton 对象m_btn 未关联一个按钮
m_btn.Create(....);
}
else
{
// CButton 对象m_btn 已关联一个按钮
其他操作...}
当然,方法并不只这一种。但这是最漂亮的方法。
三、设置控件文本文字
1.下面列举几个用来设置控件文本文字的函数:
// 取得对话框中指定控件的窗口句柄。控件通过ID标识来指定
CWnd*GetDlgItem(int nID)const;
void CWnd::GetDlgItem(int nID, HWND* phWnd)const;
// 取得窗口文本
intGetWindowText(LPTSTR lpszStringBuf, int nMaxCount)const;
voidGetWindowText(CString& rString)const;
// 设置窗口文本
voidSetWindowText(LPCTSTR lpszString);
// 取得指定控件窗口文本。控件通过ID标识来指定
intGetDlgItemText(int nID, LPTSTR lpStr, int nMaxCount)const;
intGetDlgItemText(int nID, CString& rString)const;
// 设置指定控件窗口文本。控件通过ID标识来指定
void SetDlgItemText(int nID, LPCTSTR lpszString);
// 取得指定控件窗口文本,并转化为UINT 类型返回。控件通过ID标识来指定
UINT GetDlgItemInt(int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE)const;// 设置指定控件窗口文本,由UINT类型转化为字符。控件通过ID标识来指定
voidSetDlgItemInt(int nID, UINT nValue, BOOL bSigned = TRUE);
2.可以为对话框控件关联一个变量,在CTestDlg 类的DoDataExchange来完成数据的更新与交换。这里我们需要重点说明 DoDataExChange 函数:
首先引用MSDN的一段解释吧:Called by the framework to exchange and validate dialog data。意指框架调用此函数来改写与确认对话框数据。
其实DoDataExChange函数主要是通过DDX_TEXT(....)或 DDX_CONTROL(....)来实现数据的实时关联的。
我从我的MSDN中随便拿来一个定义:
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, BYTE& value);
其实这个要关联的话也很简单,没有那么复杂。如下:
value = GetDlgItemInt(nIDC);
SetDlgItemInt(nIDC, value);
而DoDataExchange 函数是在UpdateData函数内部调用的。
该函数只有一个布尔型参数,b31.org 它决定了数据传送的方向:
调用UpdateData(TRUE),将数据从对话框的控件中传送到对应的数据成员中。
调用UpdateData(FALSE),则将数据从数据成员中传送给对应的控件。
UpdateData(FALSE)是将变量的值传到控件.UpdateData(TRUE)是从控件中取值到关联的变量
四、对话框伸缩功能的实现
只关联到两个函数:
// 取得指定窗口边框折尺寸
void GetWindowRect(LPRECT lpRect)const;
// 设置指定窗口(控件)的位置同尺寸
BOOL SetWindowPos(const CWnd* pWndInsertAfter, intx, inty, int cx, intcy, UINTnFlags);
五、逃跑按钮的实现
1.创建一个基于对话框的MFC 程序,删除原有的控件后,再添加两个按钮,更改两按钮名为”你能抓到我吗?“
2.打开类视图,定义一个新类CNewButton,这个新类的基类为CButton。并为此类添加一个成员变量:CNewButton*m_pbtn;
3.打开资源视图,分别为两个按钮创建两个CNewButton类关联变量:m_btn1, m_btn2;
4.在CXXXDlg中改写其OnInitDialog函数。主要添加:
m_btn1.m_pbtn = &m_btn2;
m_btn2.m_pbtn = &m_btn1;
5.对于CNewButton 类,必定其OnMouseMove函数。主要添加:
ShowWindow(SW_HIDE);
m_pbtn->ShowWindow(SW_SHOW);
编译,连接。OK
六、属性页、属性表单与向导的建立
1.创建属性页
打开资源编辑器,点击Dialog 资源并在列出的选项中,选择:IDD_PROPPAGE_LARGE。建立属性页资源。
之后,我们就可以其上添加其他控件来完善我们的属性页。关于属性页的完善操作我们在后面会谈到。
属性页资源完善后,再为每一个属性页关联一个类。
2.创建属性表单
打开类视图,添加新类CPropSheet,其基类为CPropertySheet。
之后再为其添加属性页类对象,并在其构造函数中利用AddPage函数将属性页添加到表单上。
3.消息响应
再主菜单的最后再增加一个菜单项,并为此菜单添加消息响应函数。
在此响应函数中创建属性表单:
CPropSheetpropSheet(TEXT(”属性表单"));
propSheet.DoModal();
4.向导的创建
创建一个向导类型的对话框,应该遵循创建一个标准属性表单的步骤来实现。
但在调用属性表单对象的DoModal函数之前,应该先调用SetWizardMode函数,来声明建立的是一个作为向导的属性表单。
所以,应在DoModal函数之前添加如下代码:
propSheet.SetWizardMode();
5.属性页的完善操作
首先我们要注意到属性页,澳门新濠天地官网66bb.org 在三个不同时期的关键性操作:当属性表单中的某属性页被选中,从而成为一个活动的页面时,应用程序框架就会调用OnSetActive函数。
OnSetActive 是其基类的一个虚函数,我们可以重写这个函数并在其中进行一些操作。
假设当前我们处于属性表单中的某属性页,当我们点击下一步并将进入下一个属性页时,应用程序框架会调用OnWizardNext函数。
OnWizardNext 是其基类的一个虚函数,我们可以重写这个函数并在其中进行一些操作。类似的还有OnWizardBack 同 OnWizardFinish函数。
当一个属性页被创建时,会调用其OnInitDialog函数。
我们可以在这个函数里对属性页中的控件进行一些操作。如为列表框或下拉框添加字符串等。
第二篇:MFC编程学习心得
//
1、将C语言变量简单重新定义 UINT、INT(32位,4字节)
LONG、DWORD(32位,4字节)WPARAM、LPARAM(32位,4字节)SHORT、WORD(16位,2字节)LONG、LRESULT BOOL(TRUE、FALSE)PINT
PSTR、LPSTR、LPCSTR(字符串指针,只读和可写)
//
2、H开头,Windows句柄类型变量 HANDLE of Windows =>HWND HANDLE of Instance =>HINSTANCE HANDLE of Icon =>HICON
//3结构体类型
SIZE、POINT、RECT
MFC所有封装类一共有200多个,但是MFC的内部技术不只是简单地封装。MFC内部总共有六大关键技术,构架起了整个MFC开发平台。
一、MFC的六大关键技术包括: a)MFC程序的初始化过程: b)消息映射机制;
c)运行时类型识别(RTTI); d)动态创建; e)永久保存; f)消息传递;
六大关键技术的目的是为了提高开发效率,开发者只需要在局部做简单的修改,即可处理大部分窗口事物。
二、SendMessage和PostMessage函数的功能:
a)能够向指定的窗口内发送窗口消息,既可以是本进程内窗口也可以是其他进程的; b)既可以发送系统内部消息,消息编号的范围是:1-WM_USER-1; 例如:WM_LBUTTONDONW,WM_MOUSEMOVE等; c)也可以发送非系统消息(开发者定义的消息),范围是WM_USER-0x7FFF。
三、SendMessage和PostMessage两个函数的区别是:
a)SendMessage是阻塞型函数,PostMessage是非阻塞型函数:
SendMessage用于调用指定窗口的内部程序,直到窗口程序处理完成以后再返回: PostMessage是将一个消息寄送到一个窗口内的消息队列后就立即返回。b)两个函数的返回值不同:
LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM,lParam);BOOL PostMessage(HWND hWnd,UNIT Msg,WPARAM wParam,LPARAM,lParam);SendMessage的返回值依赖于消息处理函数
c)跨线程或者跨进程发送消息,推荐使用PostMessage函数。
一、更具主窗口类型,MFC软件工程可以分为以下几种构架模型:
1、SDI(Single Document Interface):单文档界面,一个主框架窗口下只能编辑一份文档。例如:记事本和画笔等。
2、MDI(Multiple Document Interface):多文档界面,一个主框架窗口下可以同时编辑多份文档。
例如:VC++6.0,Photoshop等软件。
3、基于对话框的软件模型:主窗口是通过资源管理器,在对话框模板内摆放控件编辑而成的。
多数用于开发小规模软件,例如:任务管理器。
4、其他自定义窗口做主窗口:主窗口既不是框架也不是对话框,而是直接开发通用窗口类CWind而成。
例如:输入法窗口、QQ和360软件等,有时这类软件都可以使用框架和对话框模式来代替开发而成。
对话框常用消息映射函数:
二、对话框初始化消息:
1、WM_CREATE:通用窗口初始化消息
窗口还未显示出来,只有父窗口,子窗口还没创建
2、WM_INITDIALOG:对话框窗口专用消息
子窗口已经全部创建完成,可以调用和操作子窗口
三、对话框关闭过程消息:
1、WM_SYSCOMMAND:管理所有系统菜单和系统按钮消息 包括通过最大化、最小化、移动、大小和关闭等
2、WM_CLOSE:是WM_SYSCOMMAND消息的一个专用关闭的分支 再次消息处理过程可以取消本次关闭任务
3、IDCANCEL按钮消息:不但用于按钮回调消息,也是系统按钮关闭窗口的回调 执行真正关闭对话框函数是EndDialog,在此消息处理过程可以取消本次关闭任务
4、WM_DESTROY:通用窗口销毁消息
窗口已经在屏幕中消失了,但是自身窗口和窗口内的控件都还可以调用 在此消息处理过程可以取消本次关闭任务
四、非模式对话框:
1、在调用EndDialog函数关闭时,非模式对话框只是隐藏没有真正关闭;
2、在调用DestroyWindow函数关闭时,只是隐藏没有真正关闭;
3、DestroyWindow函数是通用摧毁窗口的函数,适用于对话框、控件、框架和视图等。
一个MFC软件工程由至少一个CWind派生类和一个CWinApp派生类,因此这两个类是MFC工程中最重要的两个类。
一、CWind成员函数:主要就是一个核心成员变量m_hWnd。
1、DestroyWindow:摧毁窗口。
2、Create和CreateEx:创建窗口,CreateEx创建时可以指定扩展风格。
3、获取窗口句柄:
a)pWnd->m_hWnd:直接调用前最好判断一下指针是否为空。b)operator HWND():自动类型转换,将对象转换为句柄。
c)GetSafeHwnd():可以避免的a方法,因为指针为空造成软件崩溃。
4、由句柄转化为CWnd对象:
a)CWnd::FromHandle:生成一个临时性窗口类指针
b)Attach和Detach:为一个CWnd对象嫁接和移除窗口句柄; c)SubclassWindow和UnsubclassWindow:子类化和反子类化; d)SubclassDlgItem:子类化指定ID对应的控件窗口。
5、获取和设置窗口信息:
a)GetWindowText和SetWindowText:获取和设置窗口的标题文字。b)GetStyle和ModifyStyle:获取和设置窗口的基础风格。c)GetExStyle和ModifyStyleEx:获取和设置窗口的扩展风格。
6、计时器: a)SetTimer: b)KillTimer:
7、窗口操作: a)ShowWindow: b)EnableWindow: c)MoveWindow: d)CenterWindow:
二、CWinApp类成员变量:
三、CWinApp类成员函数:
//匈牙利命名法: //变量:
int long定义:int nSel;long nTel HANDLE hInst;CString szName,szPass;CString strAddr;LPCSTR pszName;DWORD dwID;//如果是成员变量,以“m_”开头 //如果是全局变量,以“g_”开头
第三篇:MFC编程讲稿(二)
一、打字功能
1.加入数据成员
选择ClassView,双击CMyView,光标直接停留在类CMyView的定义处。在类CMyView中加入如下部分: class CMyView : public CView { protected: // create from serialization only
CMyView();
DECLARE_DYNCREATE(CMyView)
// Attributes public:
CMyDoc* GetDocument();
// Operations public: //代码编写开始
POINT Caret;
//用于存放插入符当前坐标位置 //代码编写结束 // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyView)public: virtual void OnDraw(CDC* pDC);// overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);//}}AFX_VIRTUAL
// Implementation public: virtual ~CMyView();#ifdef _DEBUG virtual void AssertValid()const;virtual void Dump(CDumpContext& dc)const;#endif
protected:
// Generated message map functions protected: //{{AFX_MSG(CMyView)afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);//}}AFX_MSG DECLARE_MESSAGE_MAP()};2.加入消息:WM_CREATE(1)在“查看”菜单中选择“建立类向导”(ClassWizard)命令,打开MFC ClassWizard窗口。
(2)选择 Message Maps。(3)分别选择:
Project: 打字
Class Name: CMyView Objects: CMyView Messges: WM_CREATE(4)单击Add Function按钮。
(5)单击Edit Code按钮。在OnCreate()函数体中加入以下部分。
int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct){ if(CView::OnCreate(lpCreateStruct)==-1)
return-1;//代码编写开始
TEXTMETRIC tm;
//声明TEXTMETRIC结构类型对象tm,用于存放字符信息。
CClientDC dc(this);
//生成应用程序窗口设备情景对象
//调用CDC类成员函数GetTextMetrics()取得字符信息,并存入变量tm中。
dc.GetTextMetrics(&tm);//调用CWnd类成员函数CreateSolidCaret()创建黑色矩形条插入符,插入符宽度为tm.tmAveCharWidth/8,高度为tm.tmHeight。
CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight);//设置插入符的初始位置
Caret.x=0;
} Caret.y=tm.tmHeight;SetCaretPos(Caret);//在初始位置显示插入符 ShowCaret();//代码编写结束 return 0;3.加入键盘消息:WM_CHAR(1)在“查看”菜单中选择“建立类向导”(ClassWizard)命令,打开MFC ClassWizard窗口。
(2)选择 Message Maps。(3)分别选择:
Project: 打字
Class Name: CMyView Objects: CMyView Messges: WM_CHAR(4)单击Add Function按钮。
(5)单击Edit Code按钮。在OnChar()函数体中加入以下部分。
void CMyView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags){
// TODO: Add your message handler code here and/or call default
//代码编写开始
SIZE size;
//存放字符的宽度和长度。
static UINT dy=Caret.y;
//声明静态变量dy,存放插入符Y轴坐标。CString a;
//声明CString类对象a,存放键盘检索到的字符nChar。a=nChar;CClientDC dc(this);//生成应用程序窗口设备情景对象
} CView::OnChar(nChar, nRepCnt, nFlags);for(UINT i=0;i } //代码编写结束 HideCaret(); //隐藏光标,使得显示字符使插入符消失。switch(nChar){ case 'r': //将插入符移动到下一行的开头 Caret.x=0;Caret.y+=Caret.y;break;default: } //将插入符移动到字符后面,并显示出来。SetCaretPos(Caret);ShowCaret();dc.TextOut(Caret.x,Caret.y,a,1);//输出字符 size=dc.GetTextExtent(a);//获得字符大小 Caret.x+=size.cx;//将字符的宽度加入到插入符的当前坐标位置 二、绘图功能 (一)生成Draw程序框架 (二)鼠标绘图 用鼠标绘制图形,一般分三个环节: (1)确定绘图位置:按下鼠标左键,产生WM_LBUTTONDOWN消息(2)确定图形显示范围:拖动鼠标,产生WM_MOUSEMOVE消息(3)完成图形显示:放开鼠标左键,产生WM_LBUTTONUP消息 1.在视图类CDrawView中加入数据成员 选择ClassView视图,双击CdrawView,光标直接停留在类CdrawView的定义处。在类CdrawView的定义中加入如下代码。 class CDrawView : public CView { //代码开始编写 protected: int m_Dragging; CPoint m_PointOld;CPoint m_PointOrigin;//代码编写结束 protected: // create from serialization only // Attributes public: // Operations CDrawView();DECLARE_DYNCREATE(CDrawView)CDrawDoc* GetDocument();public: // Overrides // Implementation public: virtual ~CDrawView();// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDrawView)public: virtual void OnDraw(CDC* pDC);// overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);//}}AFX_VIRTUAL #ifdef _DEBUG virtual void AssertValid()const;virtual void Dump(CDumpContext& dc)const;#endif protected: // Generated message map functions protected: //{{AFX_MSG(CDrawView)// NOTEthe ClassWizard will add and remove member functions here.// DO NOT EDIT what you see in these blocks of generated code!//}}AFX_MSG DECLARE_MESSAGE_MAP()21 4.定义函数CdrawDoc::AddLine()选择FileView,展开SourceFiles,双击DrawDoc.cpp,打开执行文件DrawDoc.cpp,在其末尾,加入以下代码。 //代码编写开始 // AddLine()生成新的Cline对象,并调用CObArray成员函数Add()向m_LineArray添加Cline对象指针。 void CDrawDoc::AddLine(int X1,int Y1,int X2,int Y2){ } //代码编写结束 CLine *pLine=new CLine(X1,Y1,X2,Y2);m_LineArray.Add(pLine);5.定义函数CdrawDoc::GetLine()选择FileView,展开SourceFiles,双击DrawDoc.cpp,打开执行文件DrawDoc.cpp,在其末尾,加入以下代码。 //代码编写开始 // CObArray成员函数GetUpperBound()返回加入的最后一个指针的索引,即最大的有效索引,CObArray成员函数GetAt()返回对应的CLine指针。如果索引号小于0或大于最大的有效索引号,GetLine()返回0;否则,返回对应的CLine指针。 CLine *CDrawDoc::GetLine(int Index){ } //代码编写结束 if(Index<0||Index>m_LineArray.GetUpperBound())return 0;return(CLine *)m_LineArray.GetAt(Index);22 6.定义函数CdrawDoc::GetNumLines()选择FileView,展开SourceFiles,双击DrawDoc.cpp,打开执行文件DrawDoc.cpp,在其末尾,加入以下代码。 //代码编写开始 // 通过调用CObArray成员函数GetSize(),GetNumLines()返回m_LineArray当前存放的CLine指针的个数。 int CDrawDoc::GetNumLines(){ } //代码编写结束 return m_LineArray.GetSize();7.修改函数视图类消息处理函数OnLButtonUp()调用GetDocument()和AddLine()来存放新直线。 回到Workspace,选择ClassView,单击CDrawView,展开CdrawView成员变量和成员函数。双击OnLButtonUp(),在函数OnLButtonUp()中定义后加入以下代码。 void CDrawView::OnLButtonUp(UINT nFlags, CPoint point){ // TODO: Add your message handler code here and/or call default int b; CRect Rect(40,40,600,400);b=Rect.PtInRect(point);if(b)::SetCursor(m_HCross);else ::SetCursor(m_HArrow);if(m_Dragging&&b){ m_Dragging=0;CClientDC dc(this);dc.SetROP2(R2_NOT); dc.MoveTo(m_PointOrigin);dc.LineTo(m_PointOld);dc.MoveTo(m_PointOrigin);dc.LineTo(point);//代码开始编写 //调用函数GetDocument()取得文档类的指针,并存入pDoc中。CDrawDoc * pDoc=GetDocument(); //通过指针pDoc调用加入的文档类成员函数AddLine()向m_LineArray加入 Cline类直线对象。 pDoc->AddLine(m_PointOrigin.x,m_PointOrigin.y,point.x,point.y); // 当一条新的直线绘制完成,视图类OnLButtonUp(nFlags, point)函数通过上面的工作将新绘制的直线存入文档类中。 } } CView::OnLButtonUp(nFlags, point);//代码编写结束 8.修改视图类成员函数OnDraw()void CDrawView::OnDraw(CDC* pDC){ CDrawDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data here pDC->MoveTo(40,40); pDC->LineTo(600,40); pDC->LineTo(600,400); pDC->LineTo(40,400); pDC->LineTo(40,40); //代码编写结束 } 9.编译、运行 //代码开始编写 int Index=pDoc->GetNumLines();while(Index--)pDoc->GetLine(Index)->Draw(pDC); (六)图形的删除 下面向Draw程序加入图形的编辑功能。选择“编辑/撤销”菜单命令就可以删除最近绘制的直线,选择“编辑/全部删除”菜单命令可以清除掉视图窗口中所有的直线。 函数DeleteContents专门负责文档数据的删除工作,可以在文档类中加入该函数删除存放的直线。我们的目的是通过菜单命令答道编辑的功能,因此需要加入“编辑/撤销”和 “编辑/全部删除”菜单命令的消息处理函数,在它们的消息处理函数中调用函数DeleteContents()。 1. 加入“编辑”菜单命令“全部删除” (1)选择ResourceView视图,打开Menu项目下的IDR_MAINFRAME标志符,在Edit菜单下面加入菜单命令 “全部删除”。 ID标志符为:ID_EDIT_CLEAR_ALL,Caption为:全部删除(&A)tCtrl+A(2)双击Accelerator项目下面的IDR_MAINFRAME标志符,打开快捷键编辑器。双击快捷键编辑框底部的空框,在ID文本框中输入ID_EDIT_CLEAR_ALL,在Key文本框中输入A,并选择Ctrl。 2. 加入虚函数DeleteContents()25(1)在“查看”菜单中选择“建立类向导”(ClassWizard)命令,打开MFC ClassWizard窗口。 (2)选择 Message Maps。(3)分别选择: Project: Draw Class Name: CDrawDoc Objects: CDrawDoc Messges: DeleteContents(4)单击Add Function按钮。 (5)单击Edit Code按钮。在DeleteContents()函数体中加入以下部分。void CDrawDoc::DeleteContents(){ } 3. 加入ID_EDIT_CLEAR_ALL的COMMAND消息处理函数OnEditClearAll()(1)在“查看”菜单中选择“建立类向导”(ClassWizard)命令,打开MFC ClassWizard窗口。 (2)选择 Message Maps。(3)分别选择: Project: Draw Class Name: CDrawDoc Objects IDs: ID_EDIT_CLEAR_ALL Messges: COMMAND // TODO: Add your specialized code here and/or call the base class //代码编写开始 int Index=m_LineArray.GetSize();while(Index--)delete m_LineArray.GetAt(Index);m_LineArray.RemoveAll();//代码编写结束 CDocument::DeleteContents();(4)单击Add Function按钮。 (5)单击Edit Code按钮。在OnEditClearAll()函数体中加入以下部分。void CDrawDoc::OnEditClearAll(){ // TODO: Add your command handler code here //代码编写开始 DeleteContents(); } 4. 加入ID_EDIT_CLEAR_ALL的UPDATE_COMMAND_UI消息处理函数(1)在“查看”菜单中选择“建立类向导”(ClassWizard)命令,打开MFC ClassWizard窗口。 (2)选择 Message Maps。(3)分别选择: Project: Draw Class Name: CDrawDoc Objects IDs: ID_EDIT_CLEAR_ALL Messges: UPDATE_COMMAND_UI(4)单击Add Function按钮。 (5)单击Edit Code按钮。在OnUpdateEditClearAll()函数体中加入以下部分。void CDrawDoc::OnUpdateEditClearAll(CCmdUI* pCmdUI){ } 5. 加入ID_EDIT_UNDO的COMMAND消息处理函数 UpdateAllViews(0);//代码编写结束 // TODO: Add your command update UI handler code here //代码编写开始 pCmdUI->Enable(m_LineArray.GetSize());//代码编写结束(1)在“查看”菜单中选择“建立类向导”(ClassWizard)命令,打开MFC ClassWizard窗口。 (2)选择 Message Maps。(3)分别选择: Project: Draw Class Name: CDrawDoc Objects IDs: ID_EDIT_UNDO Messges: COMMAND(4)单击Add Function按钮。 (5)单击Edit Code按钮。在OnEditUndo()函数体中加入以下部分。void CDrawDoc::OnEditUndo(){ // TODO: Add your command handler code here //代码编写开始 int Index=m_LineArray.GetUpperBound(); } 6. 加入ID_EDIT_UNDO的UPDATE_COMMAND_UI消息处理函数 (1)在“查看”菜单中选择“建立类向导”(ClassWizard)命令,打开MFC ClassWizard窗口。 (2)选择 Message Maps。(3)分别选择: Project: Draw Class Name: CDrawDoc Objects IDs: ID_EDIT_UNDO if(Index>-1){ } UpdateAllViews(0);//代码编写结束 delete m_LineArray.GetAt(Index);m_LineArray.RemoveAt(Index);Messges: UPDATE_COMMAND_UI(4)单击Add Function按钮。 (5)单击Edit Code按钮。在OnUpdateEditUndo()函数体中加入以下部分。void CDrawDoc::OnUpdateEditUndo(CCmdUI* pCmdUI){ // TODO: Add your command update UI handler code here //代码编写开始 pCmdUI->Enable(m_LineArray.GetSize());//代码编写结束 } (七)图形的存取 (八)滚动窗口 (九)分割窗口 (十)拖放与注册 MFC编程实验总结报告 知识总结+个人心得 2011年暑期MFC编程实验报告 / 6 MFC编程实验个人总结报告 一、MFC类、函数等知识小结: 1、SetTimer(1, m_intLevel, NULL);在MFC程序中SetTimer被封装在CWnd类中,调用就不用指定窗口句柄了于是SetTimer函数的原型变为: UINT SetTimer(UINT nIDEvent,UINT nElapse,void(CALLBACK EXPORT *lpfnTimer)(HWND,UINT ,YINT ,DWORD)) 当使用SetTimer函数的时候,就会生成一个计时器。函数中nIDEvent指的是计时器的标识,也就是名字。nElapse指的是时间间隔,也就是每隔多长时间触发一次事件。第三个参数是一个回调函数,在这个函数里,放入你想要做的事情的代码,你可以将它设定为NULL,也就是使用系统默认的回调函数,系统默认认的是onTime函数。这个函数怎么生成的呢?你需要在需要计时器的类的生成onTime函数:在ClassWizard里,选择需要计时器的类,添加WM_TIME消息映射,就自动生成onTime函数了。然后在函数里添加代码,让代码实现功能。每隔一段时间就会自动执行一次。 例: SetTimer(1,1000,NULL); 1:计时器的名称; 1000:时间间隔,单位是毫秒; NULL:使用onTime函数。 当不需要计时器的时候调用KillTimer(nIDEvent); 例如:KillTimer(1); KillTimer(1); 2、typedef struct{};(1)struct{ int x;int y;}test1;好,定义了 结构 test1,test1.x 和 test1.y 可以在语句里用了。 (2)struct test {int x;int y;}test1;定义了结构 test1,test1.x 和 test1.y 可以在语句里用了。与(1)比,省写 了 test (3)typedef struct test / 6 {int x;int y;}text1,text2; 此处时说了这种结构体(类型)别名 叫 text1 或叫 text2,而不是定义了结构体变量.真正在语句里用,还要写: text1 test1;//定义结构体变量 然后好用 test1.x test1.y 或写 text2 test1;//定义结构体变量 然后好用 test1.x test1.y 3、Invalidate();//让客户区无效,即时重新绘制客户区 void Invalidate(BOOL bErase = TRUE); 该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。 4、CDC::Rectangle(左上x,左上y,右下x,右下y);使用该函数画一个矩形,可以用当前的画笔画矩形轮廓,用当前画刷进行填充。 函数原型:BOOL Rectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); hdc:设备环境句柄。 nLeftRect:指定矩形左上角的逻辑X坐标。 nTopRect:指定矩形左上角的逻辑Y坐标。 nRightRect:指定矩形右下角的逻辑X坐标。 nBottomRect:指定矩形右下角的逻辑Y坐标。 5、CBrush:: CBrush//画刷类 eg:CBrush brushStick(RGB(127, 127, 127));四种构造函数: CBrush(); CBrush(COLORREF crColor); CBrush(int nIndex, COLORREF crColor); CBrush(CBitmap* pBitmap); / 6 参数说明: crColor指定画刷的前景色(RGB方式)。如果画刷是阴影线型的,则指定阴影线的颜色。 nIndex指定画刷阴影线采用的风格,取值如下: HS_BDIAGONAL45度的向下影线(从左到右) HS_CROSS水平和垂直方向以网格线作出阴影 HS_DIAGCROSS 45度的网格线阴影 HS_FDIAGONAL 45度的向上阴影线(从左到右) HS_HORIZONTAL 水平的阴影线 HS_VERTICAL 垂直的阴影线 pBitmap指向CBitmap对象的指针,该对象指定了画刷要绘制的位图。 构造函数说明: 类CBrush一共有四个覆盖的构造函数。不带参数的那个构造函数构造一个未初始化的CBrush对象,在使用该对象之前需要另外初始化。如果使用了不带参数的那个构造函数,则必须用CreateSolidBrush、CreateHatchBrush、CreateBrushIndirect、CreatePatternBrush或CreateDIBPatternBrush来初始化返回的CBrush对象。如果使用了带参数的构造函数,则不再需要初始化CBrush对象。带参数的构造函数在出错时会产生一个异常,而不带参数的构造函数总是成功返回。只带有一个参数COLORREF的构造函数用指定的颜色构造一个实线型的画刷。颜色是一个RGB值,可以用WINDOWS.H中的宏RGB构造出来。带两个参数的构造函数构造一个阴影线型的画刷,参数nIndex指定了阴影线模式的指数(index)。参数crColor指定了画刷的颜色。带有一个CBitmap型参数的构造函数构造一个模式化的画刷。参数指定一个位图。该位图应该是已经用CBitmap::CreateBitmap、CBitmap::CreateBitmapIndirect、CBitmap::LoadBitmap或CBitmap::CreateCompatiableBitmap建立或加载的位图。填充模式下的位图的最小尺寸为8像素×8像素。 6、MessageBox(“Game Over!”);MessageBox(NULL,“text”,“title”,BUTTON);参数title:string类型,指定消息对话框的标题。text:指定消息对话框中显示的消息,该参数可以是数值数据类型、字符串或boolean值。icon:Icon枚举类型,可选项,指定要在该对话框左侧显示的图标。button:Button枚举类型,可选项,指定显示在该对话框底部的按钮。default:数值型,可选项,指定作为缺省按钮的按钮编号,按钮编号自左向右依次计数,缺省值为1,如果该参数指定的编号超过了显示的按钮个数,那么MessageBox()函数将使用缺省值返回值Integer。函数执行成功时返回用户选择的按钮编号(例如1、2、3等),发生错误时返回-1。如果任何参数的值为NULL,4 / 6 MessageBox()函数返回NULL。 函数原型:MessageBox.Show(Text,Title,MessageBoxButtons,MessageBoxIcon ,MessageBoxDefaultButtons) 参数说明: (1)Text:必选项,消息框的正文。(2)Title:可选项,消息框的标题。 (3)MessageBoxButtons:可选项,消息框的按钮设置,默认只显示【确定】按钮。 OK――确定 OKCancel――确定和取消 AbortRetryIgnore――终止、重试和忽略 YesNoCancel――是、否和取消 YesNo――是和否 RetryCancel――重试和取消 (4)MessageBoxIcon:对话框中显示的图标样式,默认不显示任何图标。 Question――问号 Information、Asterisk――i号 Error、Stop、Hand――错误号 Warning、Exclamation――!号 None――不显示任何图标 (5)MessageBoxDefaultButtons:可选项,对话框中默认选中的按钮设置。 DefaultButton1――第1个button是默认按钮 DefaultButton2――第2个button是默认按钮 DefaultButton3――第3个button是默认按钮 7、Memcpy(拷贝目的地,拷贝对象,拷贝长度);包含在头文件#include 函数原型: extern void *memcpy(void *destin, void *source, unsigned n);功能: 由source指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内。eg: int a=5,b=9;memcpy(a,b,sizeof(a));//将b按位拷给a;说明: 1.source和destin所指内存区域不能重叠,函数返回指向destin的指针。 2.与strcpy相比,memcpy并不是遇到' '就结束,而是一定会拷贝完n个字节。 / 6 3.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。 //注意,source和destin都不一定是数组,任意的可读写的空间均可。 二、MFC个人学习心得: 1、问题的解决:: 绘制窗口时会出现严重的刷屏问题,问了解决这一问题,通过改变背景位图来替代过多的部分的重绘达到更好效果。 一个满载的二维、三维数组都可以用一个足够长的一维数组来装下。 2、MFC基础细节学习: 学习了位图的使用,CBrush类,CDC类,CDialog类的基本使用,对于菜单的设置初步了解了。 3、mfc编程的初步理解: 通过自学了解到mfc编程的实现是通过建立消息映射表来实现各个函数的调用。(1)通过DECLARE_MESSAGE_MAP声明消息映射;(2)通过BEGIN_MESSAGE_MAP和宏END_MESSAGE_MAP来包含消息映射宏,创建消息映射列表;(3)为消息处理函数添加代码,实现需要的响应。通过以上三大步实现消息映射。 每种对话框的操作要通过先建立相应的CDialog类来具体进行。 MFC编程只是一种工具,而编程的核心还是代码的实现。我们在使用MFC编程时要想学得更好就要不断练习,更具体的了解其中的各种类、函数,各种工具,MFC是一个巨大的工具箱,但是如果不知道工具箱里面的工具怎么用,那在好的工具也无用武之地。所以,我认为此次编程小实习主要是让我初步接触了MFC如何实现可视化编程。未来要想真正掌握MFC编程还要不断的深入了解各种MFC工具,真正的与代码结合起来实现高效实用的编程效果。 4、这次编程实习过程中,另一点感受最深的就是团队合作,一支团队要想有好的工作效率和质量就必须有足够的队伍成员间的默契。如果仅仅靠个别人去完成,其实是很不科学的,不仅费时而且可能会白白做很多无用功,因此,在以后的小组中一定要加强团队合作意识。另一点就是一个队伍的成员可以不是特别出色,但是队伍的领导者一定要负责,领导者可以不是特别杰出的技术骨干人员,但必须懂得怎样协调、安排工作,这也是实现高效团队的关键因素。 通过这次暑期编程实验,不仅充实了暑期生活,也让我学到了一些新的知识,让我更加深刻的理解了团队合作的重要性。在以后的学习生活要积极参加类似的活动,加强知识学习,能力提高,为未来的职业生涯逐渐打下一个坚实的基础。谢谢! / 6 桂林电子科技大学信息科技学院2011级面向对象实训任务书 文本编辑器 一:基本任务 设计一个基于对话框的文本编辑器,实现常用文本编辑器的基本功能。 二:要求和评分标准 1、基本要求 (1)按照题目要求独立设计文本编辑器所需的所有按钮,并完成程序源码编写、调试及关键代码注释。(40分) (2)能够实现文本文档的创建与保存。(10分) (3)能够实现文本信息的编辑。(15分) (4)能够实现文字的字体、颜色等设置。(15分) 2、发挥部分 能够实现文本编辑器的其它功能。(20分) 三、实训报告格式 1、任务题目; 2、性能、指标、要求; 3、方案设计: ① 方案论证 ② 工作原理 4、软件设计 5、制作与调试过程; 6、实训心得体会。第四篇:MFC编程实验个人总结报告
第五篇:基于vc6.0 MFC对话框的文本编辑器设计报告,附程序