分享
 
 
 

对MFC指手划脚(1)

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

我MFC没咋用过,虽然现在Java,C#等语言风头狠劲,Java,.Net平台也是逐渐取代Win32平台,但我认为,MFC也是有值得一学的必要,嗯,看在市场的面子上吧,明天我可是要去找工作了,:),

学win32 api + C++已经近2年,Delphi也有2个月了,相对于动则编程经验10年的老鸟来说,我可能连小鸟都算不上,没有任何VC项目的经验(Delphi的项目做过一些)。但初生牛犊不怕虎,但现在社会民风开放,在网络崇尚言论自由,我也想来言论自由一些。没有人敢说VC的不是,但提起MFC,大都说是垃圾,MFC是不是垃圾,最好要有真凭实据:正比如,你骂一个是笨蛋,还要拿出证据来说它是笨蛋!

嗯,从Delphi的TForm开始吧,在MFC中,与TForm类似的类有CView, CDialog, 先看看CView:

class CView : public CWnd

{

DECLARE_DYNAMIC(CView)

// Constructors

protected:

CView();

// Attributes

public:

CDocument* GetDocument() const;

// Operations

public:

// for standard printing setup (override OnPreparePrinting)

BOOL DoPreparePrinting(CPrintInfo* pInfo);

// Overridables

public:

virtual BOOL IsSelected(const CObject* pDocItem) const; // support for OLE

// OLE scrolling support (used for drag/drop as well)

virtual BOOL OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll = TRUE);

virtual BOOL OnScrollBy(CSize sizeScroll, BOOL bDoScroll = TRUE);

// OLE drag/drop support

virtual DROPEFFECT OnDragEnter(COleDataObject* pDataObject,

DWORD dwKeyState, CPoint point);

virtual DROPEFFECT OnDragOver(COleDataObject* pDataObject,

DWORD dwKeyState, CPoint point);

virtual void OnDragLeave();

virtual BOOL OnDrop(COleDataObject* pDataObject,

DROPEFFECT dropEffect, CPoint point);

virtual DROPEFFECT OnDropEx(COleDataObject* pDataObject,

DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point);

virtual DROPEFFECT OnDragScroll(DWORD dwKeyState, CPoint point);

virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);

virtual void OnInitialUpdate(); // called first time after construct

protected:

// Activation

virtual void OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView);

virtual void OnActivateFrame(UINT nState, CFrameWnd* pFrameWnd);

// General drawing/updating

virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);

virtual void OnDraw(CDC* pDC) = 0;

// Printing support

virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);

// must override to enable printing and print preview

virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);

virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);

virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// Advanced: end print preview mode, move to point

virtual void OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView);

// Implementation

public:

virtual ~CView();

#ifdef _DEBUG

virtual void Dump(CDumpContext&) const;

virtual void AssertValid() const;

#endif //_DEBUG

// Advanced: for implementing custom print preview

BOOL DoPrintPreview(UINT nIDResource, CView* pPrintView,

CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState);

virtual void CalcWindowRect(LPRECT lpClientRect,

UINT nAdjustType = adjustBorder);

virtual CScrollBar* GetScrollBarCtrl(int nBar) const;

static CSplitterWnd* PASCAL GetParentSplitter(const CWnd* pWnd, BOOL bAnyState);

protected:

CDocument* m_pDocument;

public:

virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,

AFX_CMDHANDLERINFO* pHandlerInfo);

protected:

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

virtual void PostNcDestroy();

// friend classes that call protected CView overridables

friend class CDocument;

friend class CDocTemplate;

friend class CPreviewView;

friend class CFrameWnd;

friend class CMDIFrameWnd;

friend class CMDIChildWnd;

friend class CSplitterWnd;

friend class COleServerDoc;

friend class CDocObjectServer;

//{{AFX_MSG(CView)

afx_msg int OnCreate(LPCREATESTRUCT lpcs);

afx_msg void OnDestroy();

afx_msg void OnPaint();

afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);

// commands

afx_msg void OnUpdateSplitCmd(CCmdUI* pCmdUI);

afx_msg BOOL OnSplitCmd(UINT nID);

afx_msg void OnUpdateNextPaneMenu(CCmdUI* pCmdUI);

afx_msg BOOL OnNextPaneCmd(UINT nID);

// not mapped commands - must be mapped in derived class

afx_msg void OnFilePrint();

afx_msg void OnFilePrintPreview();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

0:代码评释

protected:

CView(); // 表明CView只能用来继承,而不能实例化

BOOL DoPreparePrinting(CPrintInfo* pInfo); //要取得打印效果,必须Override该函数,设置打印机

virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);

// 从该函数看来,设置打印机效果必须Override该函数 该函数和DoPreparePrinting()函数如何配合呢?

BOOL DoPreparePrinting(CPrintInfo* pInfo); //要取得打印效果,必须Override该函数,设置打印机

1:既然有virtual void OnDraw(CDC* pDC) = 0,虚函数,表示该类为抽象类,类的Constructor没有必要为Protected, Public也一样可以达到要求,不过使用Protected更严格遵守C++语言的语意。

2:CView的友元类:

friend class CDocument;

friend class CDocTemplate;

friend class CPreviewView;

friend class CFrameWnd;

friend class CMDIFrameWnd;

friend class CMDIChildWnd;

friend class CSplitterWnd;

friend class COleServerDoc;

friend class CDocObjectServer;

CView的友元类都是MVC架构中的,文档类,CDocument, COleServerDoc, CDocObjectServer, 框架类:CDocTemplate, CFrameWnd, CMDIFrameWnd, 控制器类:CMIDFrameWnd, CMDIChildWnd, 视图类有:CPreviewView

3: CView类接受的消息

//{{AFX_MSG(CView)

afx_msg int OnCreate(LPCREATESTRUCT lpcs);

afx_msg void OnDestroy();

afx_msg void OnPaint();

afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);

// commands

afx_msg void OnUpdateSplitCmd(CCmdUI* pCmdUI);

afx_msg BOOL OnSplitCmd(UINT nID);

afx_msg void OnUpdateNextPaneMenu(CCmdUI* pCmdUI);

afx_msg BOOL OnNextPaneCmd(UINT nID);

// not mapped commands - must be mapped in derived class

afx_msg void OnFilePrint();

afx_msg void OnFilePrintPreview();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

该部分函数可以相当于Delphi的事件函数,OnCreate(),从名称看来,是刚创建是,用于设定View的外形,特性等,相当与TForm的procedure TForm1.FormCreate(Sender: TObject); FormCreate()事件, 而OnDestroy()则对等于:procedure TForm1.FormDestroy(Sender: TObject);

由于MFC的消息处理函数直接与WIN32消息是一一对应的,可以看出,CView类有关处理消息的函数极其缺乏的。而Delphi的TForm是极其丰富的,其实,TForm类对应的MFC类应该是CDialog,只是MFC并不打算把CDialog作为其它控件类的容器,所以在设计上,并没有处理其他的更多的消息。以下会接着讨论这个问题!

{ TForm }

TForm = class(TCustomForm)

public

...

property OnActivate;

property OnCanResize;

property OnClick;

property OnClose;

property OnCloseQuery;

property OnConstrainedResize;

property OnContextPopup;

property OnCreate;

property OnDblClick;

property OnDestroy;

property OnDeactivate;

property OnDockDrop;

property OnDockOver;

property OnDragDrop;

property OnDragOver;

property OnEndDock;

property OnGetSiteInfo;

property OnHide;

property OnHelp;

property OnKeyDown;

property OnKeyPress;

property OnKeyUp;

property OnMouseDown;

property OnMouseMove;

property OnMouseUp;

property OnMouseWheel;

property OnMouseWheelDown;

property OnMouseWheelUp;

property OnPaint;

property OnResize;

property OnShortCut;

property OnShow;

property OnStartDock;

property OnUnDock;

end;

当然了,除了几个是对应Windows api消息外,其他的消息都是VCL自身的消息!

4: 滑稽的OnDraw和OnPaint

virtual void OnDraw(CDC* pDC) = 0;

afx_msg void OnPaint();

从函数声明来看,好像OnDraw是一般的函数,而OnPaint正是WM_PAINT消息函数,可其实如果OnPaint不被Override时,OnPaint调用OnDraw来处理消息。这种手法有点接近Delphi的做法了。而不能一对一,否则,我还用MFC干吗,我直接用WIN32 API好了。

/////////////////////////////////////////////////////////////////////////////

void CEx03aView::OnDraw(CDC* pDC)

{

pDC->TextOut(300, 500, "hello CEx03aView::OnDraw(CDC* pDC) function");

}

void CEx03aView::OnPaint()

{

CPaintDC dc(this); // device context for painting

dc.TextOut(300, 400, "hello CEx03aView::OnPaint function");

}

OnPaint被Override之后,OnDraw就失去效果了。以上代码显示为“hello CEx03aView::OnPaint function”

5:Delphi的PME结构(属性方法事件)和VC的(M)FC结构(基础类),先进了整整一代,现在的Java和C#也都提供了PME结构,这是巧合吗?当然不是,Java的Javabean,正是Sun委托Borland做的,C#和.Net的设计师Anders更是Delphi的创始人。所以Java SDK和C#语言,.Net frameword和Delphi语言,VCL库神似,也就不奇怪了。至今,也没有什么消息说微软要出MFC.Net,我认为这是不可能,这不仅仅是市场原因,而是MFC的设计思想太落后了。而Delphi8的推出,VCL.Net的腾空出世,再一起证明VCL的良好设计一直都是领导Frameword的世界潮流。

6:MFC对api的封装极其落后,也极其丑陋,从技术从说就是一个失败的产品。可是它为什么成功了呢?这就说出了MFC的最大的优点:灵活,高效,简单。

灵活:这是得益于C/C++语言的缘故。我也不用多说

高效:还是得益于C/C++语言的缘故。C/C++语言的特点,灵活高效,相信大家不会忘记。

简单:大家对比MFC和VCL,都会相信VCL确实比MFC难学,VCL里面的高级技巧鬼斧神工,VCL程序码里面甚至还有许多汇编。这都是令人望而却步的。而MFC呢,简单封装,简单使用,虽然丧失了RAD,不过,这也是大家喜欢的原因吧。

MFC的成功很大程度是得益于C/C++这个语言中的日不落帝国,VCL成功在于Delphi这个优雅的,威力的,专利的OO语言

噢,MFC,当日不落帝国陨落时,还是把它放到历史的博物馆吧!

当然了,不能凭这点不像样的东西,来议论一个“伟大”的frameword---MFC,否则会让人晕倒,所以会有一系列的学习心得......

to be continued

--- 2004-7-2 by littleroy

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有