Chinaunix首页 | 论坛 | 博客
  • 博客访问: 640255
  • 博文数量: 233
  • 博客积分: 2221
  • 博客等级: 大尉
  • 技术积分: 3184
  • 用 户 组: 普通用户
  • 注册时间: 2010-02-16 14:01
个人简介

瓜瓜派的瓜瓜

文章分类

全部博文(233)

文章存档

2013年(28)

2012年(197)

2011年(8)

分类: 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。 
  
这样,不多写一行代码,搞定,而且和系统的完全一致。 
  
呵呵,我是初学者,本文只代表我个人观点,欢迎排砖。
阅读(1512) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

煜轩2012-01-09 20:37:33

是啊。例子很关键的!