博文

第10课(2007-05-01 15:37:00)

摘要:
1.画图:
   a.创建四个菜单,为其添加消息响应;
   b.在View中添加m_DrawType,保存绘画类型;
   c.增加成员变量,m_PtOrigin,当按下鼠标左键时,保存此点;
   d.在OnLButtonUp中画点,线,矩形,椭圆,别忘记设置成透明画刷
2.为其添加一个设置对话框(线型和线宽)
   a.创建对话框,为其创建一个新类关联它;
   b.为其中的线宽关联成员变量;
   c.在View中增加一个菜单,响应新的对话框;
   d.添加线型选项设置,将其Group属性选中,并为单选按纽关联成员变量。在view中增加一个线型变量m_nLineStyle
3.添加一个颜色对话框
   a.实例化一个CColorDialog
   b.调用DoModal方法
4.添加字体对话框,将选择的字体在View中显示出来。
   a.实例化一个对象;
   b.为View添加一个字体成员变量,得到用户选择的字体。
   c.调用Invadate()发出重绘消息;
   d.再次注意一个对象只能创建一次,故要再次创建,必须将原告的删除!
5.为设置对话框增加示例功能。
   a.当控件内容改变时,发出En_change消息。而Radio按纽则为Clicked。需先UpdateData()。另外还需要ScreenToClient(&rect)
6.改变对话框的背景色和控件颜色。
  每个控件被绘制时都发出WM_CTlColor消息,
7.如何改变OK按纽的字体和背景?
  OK按纽
  a.创建一个新类,CTestBtn,基类为CButton
  b.在类中增加虚函数,DrawItem,添加代码。
 &......

阅读全文(2032) | 评论:0

第9课(2007-05-01 15:37:00)

摘要:
1.修改外观和图标可以在MainFrm中进行,而修改背景和光标只能在View中进行。为什么?因为view的显示挡 在了MainFrame的前面。
  a.在MainFrame中
      PreCreateWindow()中,在窗口创建之前,用重新注册窗口类的方法,比较麻烦。在PreCreateWindow ()中修改
      也可以用简单的方法,用全局函数
//cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,0,0,
// LoadIcon(NULL,IDI_WARNING));
     在窗口创建之后,在OnCreate()中修改
//SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);
//SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE) & ~WS_MAXIMIZEBOX);
// SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));
  b.在View中
    PreCreateWindow()中
//cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
// LoadCursor(NULL,IDC_CROSS),(HBRUSH)GetStockObject(BLACK_BRUSH),NULL);
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
    OnCreate()中
SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)Ge......

阅读全文(2060) | 评论:0

第8课  对话框(2007-05-01 15:36:00)

摘要:
1.如何改变按纽的字体?在对话框的属性中改变字体的属性即可
2.逃跑按纽的实现
  1.从CButton派生一个类,CWeixinBtn
  2.将IDC_EDIT1关联成员变量m_btn1,类型为CWeixinBtn,注意要包含头文件。
  3.在CWeixinBtn中加一个指针成员变量CWeixinBtn *pWeixinBtn,然后将其地址初始化。
  4.在新类中增加鼠标移动的消息处理。
3.属性表单
  1.插入属性页资源。Insert->new Resource->Dialog
  2.当选择Classwizard菜单时,系统提示是否为创建新的类,我们将其从CPropertyPage派生!这样可以为 方便为其增加消息响应函数。
  3.插入新的从CPropertySheet派生的类,在类中增加3个CPropertyPage的实例。
  4.在view中增加菜单项,当点击时显示属性表单,出现中文乱码,修改CPropertyPage属性为中文,另外将 其字体设为宋体。
  5.在CPropertyPage中设置SetWizardButtons可将其属性改为上一步、完成!
  6.为IDC_RADIO1关联成员变量,需要先设置Group属性才行。另外别忘记调用UpdateData().
  7.为CPropertyPage增加虚函数,OnWizardNext,如果用户点击下一步时,不想让他进入下一步,刚返回-1 !
  8.将用户的选择输出到屏幕上,此时可以在View中增加几个成员变量,用来接收用户选择的数据。
4.memset()的用法! memset(m_bLike,0,sizeof(m_bLike));......

阅读全文(2402) | 评论:0

第7课(2007-05-01 15:36:00)

摘要:
1.如果在SDI中要调用对话框
  a.先插入一个对话框资源;
  b.然后在ClassWizards中为其创建一个类。其目的是比较方便为添加按纽和消息响应函数。
  c.然后实例化它。在实例化时,必须将其头文件包含进去。
2.创建非模态对话框,注意它不能是局部变量。当 点击非模态对话框的OnOK按纽时,它并没有关闭,而是隐藏了。需要调用destroyWindow().
3.一个对象只能一个按纽。为什么?因为在Wincore.cpp的628行有代码 ASSERT(pWnd->m_hWnd == NULL);   // only do once而创建后它的m_hWnd就不为0了。此处ASSERT的用法是如果括号里面不为真,则程序崩溃。
4.如何为静态文本框增加消息响应?首先将IDC_STATIC改名。同时还需要将Notify特性复选中。
5.完成加法功能。
  a.GetDlgItem();
  b.GetDlgItemText();
  c.GetDlgItemInt();
  d.将IDC_EDIT1关联CEDIT类型变量
  e.将IDC_EDIT1关联int型变量。注意调用 UpdateData();
  f. //::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
//::SendMessage(m_edit1.m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
//GetDlgItem(IDC_EDIT1)->SendMessage(WM_GETTEXT,10,(LPARAM)ch1);
m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);
  g. SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LPARAM)ch1);......

阅读全文(2302) | 评论:0

第6课(2007-05-01 15:35:00)

摘要:
1.当对某菜单添加消息响应函数时,4个类的消息响应优先次序分别是:1.View;2.CDOC;3.CMainFrame.4.CWinAPP.为什么?请参阅《深入浅出》
2.消息分类:a;标准消息(以WM_开头的消息,但不包括ON_COMMAND);b;命令消息 ON_COMMAND(IDM_PHONE1, OnPhone1),菜单和工具栏的消息。c.通告消息:按钮,列表框发出的消息。
CCmdTarget只能接受命令消息。而从CCmdTarget派生的CWnd可以接收命令消息,也可以接受标准消息。
3.确定菜单的索引号,注意从0开始,分隔符也算数。什么叫弹出菜单(Popup Menu)?一个子菜单只能有一个缺省菜单。 //GetMenu()->GetSubMenu(0)->SetDefaultItem(5,TRUE);
str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),
   GetSystemMetrics(SM_CYMENUCHECK));//获得系统的菜单的位图的大小。
/* SetMenu(NULL);//移除菜单 CMenu menu;
menu.LoadMenu(IDR_MAINFRAME);
SetMenu(&menu);
menu.Detach();*/增加菜单,此处detach(),如果是局部变量。
4.
void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)
{
if(2==pCmdUI->m_nIndex)
  pCmdUI->Enable();//当此菜单显示时,设为可用。
}
5.右键弹出菜单功能的实现方法有两个:
  a.Project->Add to Project->component and controls->文件夹VC components->Popup Menu OK
  b.用TrackPopupMenu()实现。
CMenu menu;
menu.LoadM......

阅读全文(2464) | 评论:0

第5课(2007-05-01 15:35:00)

摘要:
1.CWnd::CreateSolidCaret创建插入符,ShowCaret()显示插入符。GetTextMetrics(),获得当前字体的一些信息。CWnd::CreateCaret()创建图象插入符
bitmap.LoadBitmap(IDB_BITMAP1);//此处的bitmap为成员变量!!!
CreateCaret(&bitmap);
ShowCaret();
TEXTMETRIC tm;//字体结构体
dc.GetTextMetrics(&tm);//
m_ptOrigin.y+=tm.tmHeight;//获得字体高度。
2.VC中CString::LoadString(ID号),比较方便。
3.路径层的概念:有两种方法创建路径层:
  (1)
pDC->BeginPath();
pDC->Rectangle(50,50,50+sz.cx,50+sz.cy);
pDC->EndPath();
pDC->SelectClipPath(RGN_DIFF);
   (2)
        CSize sz=pDC->GetTextExtent(str);
        CRgn rn;
        rn.CreateRectRgn(0,50,sz.cx,sz.cy);
        pDC->SelectClipRgn(&rn,RGN_DIFF);
路径层有什么作用?可以保护我们先前的文本或者图像不被后来画的覆盖。
4.在View上输入文字的步骤。
CFont font;//创建字体对象
font.CreatePointFont(300,"华文行楷",NULL);//设置
CFont *pO......

阅读全文(2323) | 评论:0

第4课(2007-05-01 15:35:00)

摘要:
1.在单文档中view挡在MainFrame的前面。此时如果编写针对MainFrame的mouseClick事件,将不会有反应。
2.消息响应会在3处修改代码,1处是在头文件中,
//{{AFX_MSG(CDrawView)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
另一处是cpp文件的begin MessageMap和End MessageMap之间,
BEGIN_MESSAGE_MAP(CDrawView, CView)
//{{AFX_MSG_MAP(CDrawView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
最后是要有函数实现的代码。
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TOD Add your message handler code here and/or call default
m_ptOrigin=m_ptOld=point;
m_bDraw=TRUE;
CView::OnLButtonDown(nFlags, point);
}
3......

阅读全文(2039) | 评论:0

第3课(2007-05-01 15:34:00)

摘要:
1.在main或WinMain之前,全局变量已经被分配内存并初始化了。
2.在MFC中在WinMain之前有个theApp全局变量先被构造并被初始化,而由于子类构造函数执行前,其父类的构造函数先被执行,所以CTestApp的父类CWinAPP的构造函数先执行。产生了theApp对象后,在WinMain()中的指针*pThread和*pApp就有了内容。
3.MFC大致流程:
CTestApp theApp;//构造全局对象
WinMain()
{
AfxWinMain();//调用下面的函数
}
AfxWinMain()
{
pThread->Initinstance();//初始化工作和注册窗口类,窗口显示和更新
pThread->Run();//消息循环
}
而在BOOL CTestApp::InitInstance()中的代码
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
  IDR_MAINFRAME,
  RUNTIME_CLASS(CTestDoc),
  RUNTIME_CLASS(CMainFrame),       // main SDI frame window
  RUNTIME_CLASS(CTestView));
AddDocTemplate(pDocTemplate);
完成了将这三个类关联起来的工作。
4.如何在单文档文件中显示一个CButton的对象?
在CMainFrame::OnCreate()中定义一个CButton的对象btn;然后调用btn.Create("维新",WS_DISABLED   |WS_CHILD | WS_VISIBLE | BS_AUTO3STATE,
  CRect(0,0,300,100),/*GetParent(),*/this,123);
注意点:
&......

阅读全文(1835) | 评论:0

第2课(2007-05-01 15:34:00)

摘要:
1.定义结构体和类时别忘记在最后加入";"号!例如Class Point{int x;int y;};
2.#include <xxx.h>与#include "xxx.h"的区别:<>不查找运行时目录,""查找运行时目录!
3.类的定义中,如果未指明成员类型,则缺省为private.而结构体中则缺省为public.
4.引用:引用经常用在函数的传参上。另外数值交换函数也经常用引用。例
change(int &x,int &y){int temp;temp=x;x=y;y=x}调用时即可以用 int a=3;int b=4;change(a,b);一般不用指针来作为参数进行数值交换。因为会引起歧义。
5.通常将类的定义放.h文件,而将其实现放在cpp文件中,别忘记了在cpp文件中#include "xxx.h"
6.如何防止类的重复定义?
用#inndef Point_H_H
#define Point_H_H
class Point{};
#endif来防止
7.源文件cpp文件单独编译成obj文件。最后由链接器将与将要使用到的C++标准库类链接成exe文件,头文件不参加编译。所以在cpp文件中别忘记了加入#include "xxx.h"
8.函数的覆盖,在子类中重写父类的函数,此时采用早期绑定的方法。如果加入了virtual,则将采用迟绑定的技术,在运行时根据对象的类型确定调用哪一个函数。此迟绑定技术是MFC的类的继承的精髓。
9.强制类型转换。如果CFish从CAnimal派生而来。则可以将鱼的对象转换为CAnimal的对象,而反之则不行。从现实中理解也是正常的,鱼可以是动物,而动物却不是鱼。再如int可以强制转换成char型。而反之则出错。 ......

阅读全文(1781) | 评论:0

第一课(2007-05-01 15:34:00)

摘要: 1.MFC生成的C++源文件中都有StdAfx.h,此文件包含了常用的AFX函数的声明,其中有afxwin.h,此文件包含了CRECT,CPoint,CWnd等许多类及其方法的声明。
2.Project->Setting->Debug可以加入命令行参数。
3.在SDK中要加入"windows.h"和stdio.h。因为LoadCursor,MessageBox等函数的声明在这个文件中。
4.创建一个完整的窗口的四个步骤SDK,1设计窗口类,2注册窗口类,3创建窗口,4显示窗口
5.函数名可以代表函数代码的首地址,即可作为函数指针。
6.要查看VC数据类型,可以在MSDN中输入“BOOL”然后选择“DATA TYPE”。
7.atof将字符串转化为float,atoi将字符串转化为int型。
8.所有从CWnd类派生的类都有m_hWnd句柄。
9.变量的生命周期:可以认为出了包含它的大括号,这个变量的生命周期结束。所以全局变量的声明位于所有大括号之外。但是用new声明的变量和用static声明的变量除外。
10.SDK示范程序,见下面。
11.sprintf格式化字符,其头文件为stdio.h,在MFC中格式化字符用CString.Format
12.GetDC()与ReleaseDC()要成对使用,否则会内存泄漏。同样,BeginPaint()与EndPaint()。
13.GetStockObject()得交省⒒ⅰ⒆痔濉⒌魃宓木浔褂檬北匦胗美嘈妥弧?br>14.什么时候用NULL,什么时候用0.答,对指针赋值时用NULL,对变量赋值时用0.
15.什么是野指针?答:将指针指向的变量的内存释放后,此指针即变成野指针!如何避免野指针?答:将此指针指向NULL即可。p=NULL;
16.SDK代码流程:
#include "windows.h"//包含头文件LoadCursor,TextOut等函数
#include "stdio.h"//包含sprintf,printf等函数
LRESULT CALLBACK MyProc(...);//声明回调函数
int WINAPI WinMain()
{
WNDCLASS w......

阅读全文(1777) | 评论:0