C++经典语法与应用 类的编写与应用\EX09
#include <iostream.h>
class Base
{
public:
virtual void xfn(int i)
{
cout<<"Base::xfn(int i)"<<endl;
}
void yfn(float f)
{
cout<<"Base::yfn(float f)"<<endl;
}
void zfn()
{
cout<<"Base::zfn()"<<endl;
}
};
class Derived : public Base
{
public:
void xfn(int i) //覆盖了基类的xfn函数
{
cout<<"Drived::xfn(int i)"<<endl;
}
void yfn(int c) //隐藏了基类的yfn函数
{
cout<<"Drived::yfn(int c)"<<endl;
}
void zfn() //隐藏了基类的zfn函数
{
cout<<"Drived::zfn()"<<endl;
}
};
void main()
{
Derived d;
Base *pB=&d;//基类指针指向派生类对象
Derived *pD=&d;
pB->xfn(5);//Drived::xfn(int i)
pD->xfn(5);//Drived::xfn(int i)
pB->yfn(3.14f);//Base::yfn(int c)
pD->yfn(3.14f);//Drived::yfn(int c)
pB->zfn();//Base::zfn()
pD->zfn();//Drived::zfn()
char i;
cin>>i;
}
讲述MFC AppWizard的原理与MFC程序框架的剖析\Test
法一:
1.在CMainFrame类中定义私有 CButton m_btn
2.在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
m_btn.Create("按钮",WS_CHILD | BS_DEFPUSHBUTTON,CRect(0,0,100,100),this,123);
m_btn.ShowWindow(SW_SHOWNORMAL);
return 0;
或
2.在BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
法二:
1.在CTestView类中定义私有 CButton m_btn
2.
int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
// m_btn.Create("维新",WS_CHILD /*| WS_VISIBLE | BS_AUTO3STATE*/,
// CRect(0,0,100,100),/*GetParent(),*/this,123);
// m_btn.ShowWindow(SW_SHOWNORMAL);
// m_btn.Create("按钮",WS_CHILD | BS_DEFPUSHBUTTON,CRect(0,0,100,100),GetParent(),123);//框架区 包括工具栏
// m_btn.Create("按钮",WS_CHILD | BS_DEFPUSHBUTTON,CRect(0,0,100,100),this,123);//视图区
// m_btn.ShowWindow(SW_SHOWNORMAL);
return 0;
}
Chapter4——MFC消息映射机制的剖析 讲述如何运用ClassWizard\Draw
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
#if 0
// 首先获得窗口的设备描述表
HDC hdc;
hdc = ::GetDC(m_hWnd);//class CDrawView : public CView class CView : public CWnd m_hWnd 是 CWnd的公有成员
//移动到线条的起点
MoveToEx(hdc, m_ptOrigin.x, m_ptOrigin.y, NULL);//CDrawView 类无该成员函数 加不加::都可以
//画线
LineTo(hdc, point.x, point.y);//有个 CDC::LineTo 但和本类无关 这里加不加::都可
//释放设备描述表
::ReleaseDC(m_hWnd,hdc);
#endif
#if 0
//hWnd [in] Handle to the window whose DC is to be retrieved. If this value is NULL, GetDC retrieves the DC for the entire screen.
//If the function succeeds, the return value is a handle to the DC for the specified window's client area.
CDC* pDC = GetDC();//CWnd::GetDC CWnd类的成员函数
pDC->MoveTo(m_ptOrigin);//上面 MoveToEx //CPoint MoveTo( int x, int y ); CPoint MoveTo( POINT point );
pDC->LineTo(point);//CDC::LineTo //BOOL LineTo( int x, int y ); BOOL LineTo( POINT point );
ReleaseDC(pDC);
#endif
#if 0
CClientDC dc(GetParent());//线可在工具栏上出现不会进入菜单栏不会进入菜单栏和标题栏和程序窗口外
// CWindowDC dc(GetDesktopWindow());//在程序视图区做画线动作 线可以画到程序窗口外面
// CWindowDC dc(GetParent());//线可在标题栏 菜单栏 工具栏 视图区出现
dc.MoveTo(m_ptOrigin);//class CClientDC : public CDC
dc.LineTo(point);
#endif
#if 0
/*
CPen( );
CPen( int nPenStyle, int nWidth, COLORREF crColor );
CPen( int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL );
*/
//CPen pen();
CPen pen(PS_DOT,1,RGB(255,0,0));
/*
class CDrawView : public CView
#ifdef _AFXDLL
class CView : public CWnd
#else
class AFX_NOVTABLE CView : public CWnd
#endif
//C++基础知识,子类指针赋给父类指针不需要显式转换。this的类型是CDrawView* const,参数要求CWnd*,而CDrawView从CWnd继承
*/
CClientDC dc(this);//CClientDC( CWnd* pWnd );
/*
CPen* SelectObject( CPen* pPen );
CBrush* SelectObject( CBrush* pBrush );
virtual CFont* SelectObject( CFont* pFont );
CBitmap* SelectObject( CBitmap* pBitmap );
int SelectObject( CRgn* pRgn );
*/
CPen* pOldPen = dc.SelectObject(&pen);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
dc.SelectObject(pOldPen);
#endif
#if 0
/*
CBrush( );
CBrush( COLORREF crColor );
throw( CResourceException );
CBrush( int nIndex, COLORREF crColor );
throw( CResourceException );
CBrush( CBitmap* pBitmap );
throw( CResourceException );
*/
//创建一个红色画刷
CBrush brush(RGB(255,0,0));
//创建并获得设备描述表
CClientDC dc(this);
/*
网录wl
CRect()是CRect类的构造函数, 返回一个CRect对象。
CRect会构造一个对象传给函数,不需要返回值。
m_btn.Create("按钮",WS_CHILD | BS_DEFPUSHBUTTON,CRect(0,0,100,100),this,123);
在CRect构造的对象不需要返回,而是直接放在Create函数的参数栈里面去了。 如果不明白也可以认为这个C++的一个特性。
operator LPCRECT Converts a CRect to an LPCRECT.
operator LPRECT Converts a CRect to an LPRECT.
Ellipse(CRect(0,20,100,120))
CRect(0,20,100,120)是构造了一个CRect对象,Ellipse函数的参数要求是LPCRECT类型,CRect对象可以隐式转换成LPCRECT类型。
请问在CRect中定义的操作符operator LPRECT();是什么意思啊?他的内部是怎么实现的?
对于函数CreateEllipticRgnIndirect,它需要的是一个CRect的指针类型,但是为什么调用时使用下面两种方式都可以呢?LPRECT是怎样起作用的?
CRect m_Rect;
rgn.CreateEllipticRgnIndirect((LPRECT)&m_Rect);
rgn.CreateEllipticRgnIndirect(&m_Rect);
rgn.CreateEllipticRgnIndirect(m_Rect);
以上三种方式都可以!我也没有看到CreateEllipticRgnIndirect有多个重载函数啊?
他的内部是怎么实现的?????我再CRect的头文件只能看见其声明。
有了它就可以实现CRect对象到RECT指针的直接转换,这样的话,凡是输入参数是LPRECT的都可以直接使用CRect对象
CRect是通过RECT结构体派生的,所以
rgn.CreateEllipticRgnIndirect((LPRECT)&m_Rect);
rgn.CreateEllipticRgnIndirect(&m_Rect);
并不调用任何函数,直接把m_Rect转回到RECT,明白?就像把CButton转换成CWnd,不需要任何条件
第三个则是通过operator LPRECT();把CRect对象转化成LPRECT,OK?
LPRECT不是操作符,operator才是操作符,
CRect::operator LPRECT
operator LPRECT( );
Remarks
Converts a CRect to an LPRECT. When you use this function, you don 't need the address-of (&) operator. This operator will be automatically used when you pass a CRect object to a function that expects an LPRE
看看下面这句:
LPCRECT A 32-bit pointer to a constant (nonmodifiable) RECT structure.
LPCRECT仅仅是一个指针
怎样自定义我自己的 LPMYCLASS,其功能跟 LPRECT 一样!
class MyClass:public MYCLASS//要从MYCLASS结构体派生!
{
...
operator LPMYCLASS(){return this;};//LPMYCLASS要之前先定义!
...
}
*/
/*
http://www.vcshare.net/jichu/jichu_212.htm
typedef const RECT* LPCRECT; // pointer to read/only RECT
typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;
CRect::operator = ,重载“=”运算符,实际调用CopyRect。
CRect::operator ==,重载“==”运算符,实际调用EqualRect。
operator !=,重载“!=”运算符,实际调用EqualRect。
CRect::operator += ,重载“+=”运算符,第一个原型和第二个原型调用OffsetRect,第三个原型调用InflateRect。 CRect::operator -=,重载“-=”运算符,第一个原型和第二个原型调用OffsetRect,第三个原型调用InflateRect。 CRect::operator &=,重载“&=”运算符,实际调用IntersectRect。 CRect::operator |= 重载“|=”运算符,实际调用UnionRect。 +、-、&、|和上面的类似,就不再详细讲解了。
*/
//利用红色画刷填充鼠标拖曳过程中形成的矩形区域
dc.FillRect(CRect(m_ptOrigin,point),&brush);//void FillRect( LPCRECT lpRect, CBrush* pBrush );
#endif
#if 0
//创建位图对象
CBitmap bitmap;//CBitmap( );
//加载位图资源
/*
BOOL LoadBitmap( LPCTSTR lpszResourceName );
BOOL LoadBitmap( UINT nIDResource );
*/
bitmap.LoadBitmap(IDB_BITMAP1);//#define IDB_BITMAP1 130
//创建位图画刷
CBrush brush(&bitmap);
//创建并获得设备描述表
//CClientDC dc(this);
//利用红色画刷填充鼠标拖曳过程中形成的矩形区域
//dc.FillRect(CRect(m_ptOrigin,point),&brush);
HDC hdc=::GetDC(m_hWnd);
//::FillRect(hdc,CRect(m_ptOrigin,point),brush);
//::FillRect(hdc,(const RECT*)&CRect(m_ptOrigin,point),brush);
::FillRect(hdc,&CRect(m_ptOrigin,point),brush);
::FillRect(hdc,CRect(m_ptOrigin,point),brush);
::ReleaseDC(m_hWnd,hdc);
#endif
#if 0
//创建并获得设备描述表
CClientDC dc(this);
//创建一个空画刷
CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//GetStockObject为SDK
/*
CDC::SelectObject
CPen* SelectObject( CPen* pPen );
CBrush* SelectObject( CBrush* pBrush );
virtual CFont* SelectObject( CFont* pFont );
CBitmap* SelectObject( CBitmap* pBitmap );
int SelectObject( CRgn* pRgn );
*/
//将空画刷选入设备描述表
CBrush *pOldBrush = dc.SelectObject(pBrush);
//绘制一个矩形
/*
CDC::Rectangle
BOOL Rectangle( int x1, int y1, int x2, int y2 );
BOOL Rectangle( LPCRECT lpRect );
*/
dc.Rectangle(CRect(m_ptOrigin,point));
//恢复先前的画刷
dc.SelectObject(pOldBrush);
#endif
m_bDraw = FALSE;
CView::OnLButtonUp(nFlags, point);
}
void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
#if 1
CClientDC dc(this);
//dc.SetROP2(R2_BLACK);//画出的是黑线,画笔选择的颜色无效
dc.SetROP2(R2_MERGENOTPEN);//画笔反色OR屏幕色 怎么看不到画的线???屏幕色为255 255 255 或 任何值都为白色所以看不到
//dc.SetROP2(R2_COPYPEN);//画画笔颜色画笔选择的颜色有效 有这句和没这句画出的线都是画笔选择的颜色
//创建一个红色的、宽度为1的实线画笔
//CPen pen(PS_SOLID, 1, RGB(0,0,0));//黑
//CPen pen(PS_SOLID, 1, RGB(255,255,255));//白
//CPen pen(PS_SOLID, 1, RGB(255,0,0));
//CPen pen(PS_SOLID, 1, RGB(100,200,200));
CPen pen(PS_SOLID, 100, RGB(100,200,200));
//把创建的画笔选入设备描述表
CPen *pOldPen = dc.SelectObject(&pen);
if(m_bDraw == TRUE)
{
// dc.MoveTo(m_ptOrigin);
// dc.LineTo(m_ptOld);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
dc.LineTo(m_ptOld);
//修改线段的起点
//m_ptOrigin = point;
m_ptOld = point;
}
//恢复设备描述表
dc.SelectObject(pOldPen);
#endif
CView::OnMouseMove(nFlags, point);
}