瓜瓜派的瓜瓜
分类: C/C++
2012-01-09 16:44:35
作为一个初学者,如何能够迅速掌握VC++? 我的总结是,从框架源代码和官方例子着手。 大家可能会说,MFC那么复杂的框架,初学者如何能够很快掌握?其实不然,现在想想,去看教程和视频才误导了我,看似捷径,实际上绕弯路。 MFC源代码固然复杂,可是原理并不复杂,它体现了一种风格,使用框架库编程的捷径就是充分理解框架库的脾气,感觉你的程序可以和框架库无缝连在一起。 我偶然之间获得了MSC C/C++7.0,我花了一个晚上,通读了全部源代码,其实也就十万行规模,甚至还不如我的项目的代码多。MFC最难理解的是动态创建和消息映射,看了源代码,豁然开朗。尤其是消息映射是如何变成了消息循环,这个在wincore.cpp里面有。 看完MFC1.0之后,我又看了MFC 2.5 MFC 3.0的源代码。MFC 3.0最重要的改进是增加了对Doc/View的支持。让人兴奋的是,我发现MFC基类已经处理了很多东西。 MFC4.2源代码太大了,而且架构变化不大,我阅读它的方法是,从最终调用着手,往里面看。MFC的例子代码很多,但是我不建议你去网上搜索一般的代码,而应该关注微软的例子,典型的是WordPad,还有AppWizard生成的代码。 C/C++是一个庞大而且复杂的体系,比如说,字符串,他的处理C语法 char[]、CRT string、STL、MFCCString、OLE的BSTR,有无数种实现,再比如有的调用,API、MFC都可以实现,对于MFC开发,我看到很多代码,虽然也能达成目的,但是代码很不自然,感觉是在“打补丁”。这种代码隐患很大,下面说明: 我举一个例子,我们需要创建一个工具条,有一个功能是在查看菜单下,增加一个菜单,用来切换这个工具栏是否显示。 初学者很喜欢看孙鑫的视频,他怎么说的呢?他说我们增加一个菜单,编写响应代码。 判断工具栏目前状态,如果显示,则隐藏,如果隐藏,则显示。 运行,结果发现工具栏没了,Controlbar容器还在。 好,他说,我们需要reclac layout,搞定了。 把Toolbar拖出来,隐藏了,显示,又不对了,工具栏出现在dock的状态…… 很悲哀,这么常用的一个操作,越搞越复杂,而第三方的书籍、源代码往往都是这个思路,不过是有的人多做了一点,bug少一点,有的人少作了一点,bug多一点。 但是看了源代码,就不同了。大家想想,appwizard创建了一个工具栏,它就很完美,你去学别的,为啥不学它呢。 经过研究发现,它是映射到Frame的OnBarCheck和OnUpdateControlBarMenu。 于是我将我的菜单也关联上这个,但是发现不行。。。这是为什么呢?还是看源代码: CControlBar* CFrameWnd::GetControlBar(UINT nID) { if (nID == 0) return NULL; POSITION pos = m_listControlBars.GetHeadPosition(); while (pos != NULL) { CControlBar* pBar = (CControlBar*)m_listControlBars.GetNext(pos); ASSERT(pBar != NULL); if (_AfxGetDlgCtrlID(pBar->m_hWnd) == nID) { ASSERT_KINDOF(CControlBar, pBar); return pBar; } } return NULL; } void CFrameWnd::OnUpdateControlBarMenu(CCmdUI* pCmdUI) { ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR); ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR); ASSERT(ID_VIEW_REBAR == AFX_IDW_REBAR); CControlBar* pBar = GetControlBar(pCmdUI->m_nID); if (pBar != NULL) { pCmdUI->SetCheck((pBar->GetStyle() & WS_VISIBLE) != 0); return; } pCmdUI->ContinueRouting(); } BOOL CFrameWnd::OnBarCheck(UINT nID) { ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR); ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR); ASSERT(ID_VIEW_REBAR == AFX_IDW_REBAR); CControlBar* pBar = GetControlBar(nID); if (pBar != NULL) { ShowControlBar(pBar, (pBar->GetStyle() & WS_VISIBLE) == 0, FALSE); return TRUE; } return FALSE; } 看到没有,需要一个nID,那么这个nID是什么呢? 看ToolBar的源代码知道,在创建Toolbar的CreateToolbarEx里面,可以绑定这个Menu的ID。 这样,不多写一行代码,搞定,而且和系统的完全一致。 呵呵,我是初学者,本文只代表我个人观点,欢迎排砖。 |