≡≡≡≡≡初学者学习VC++的一点心得≡≡≡≡≡
作为一个初学者,如何能够迅速掌握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、MFC CString、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。
这样,不多写一行代码,搞定,而且和系统的完全一致。
呵呵,我是初学者,本文只代表我个人观点,欢迎排砖。