众所周知,在 STL 中,对于有序的 vector 容器,使用 binary_search、lower_bound/upper_bound 等搜索算法要比直接 find 高效得多。但是由于各个 STL 实现版本没有统一的标准,在 DEBUG 环境下各自的校验机制千差万别,这就导致可能出现一些让人郁闷的情况,比如这次的主角,微软的 STL。
TAG / vs/vc++
转载自痴痴笑笑的博客,略有删改。
尽管 C++ 社区对 C++ 0x 很是追捧,但是各厂商对于新标准的支持并不热乎。盼星星盼月亮,微软作为 Windows 平台上最强势的 C++ 编译器厂商也终于在 Visual Studio 2010 中开始支持 C++ 0x 的特性。
Visual Studio 2010 中的 Visual C++ 编译器,即 VC10, 包含了 4 个 C++ 0x 的语言特性:lambda 表达式,自动类型推演(auto 关键字),静态断言(static_assert)和右值引用(rvalue reference)。
CONTINUE READING »
微软同学永远是个把简单问题复杂化的孩子,这不,当年为了在 Windows XP 中同时支持两套控件风格(新的 XP 风格和旧的 95/98 风格),“发明”了 .manifest 这么个玩意,使以前的老程序也能自动使用上新的控件风格。
然而在 VS 里,微软并不是总是默认帮我们自动生成这个破玩意儿。最早的办法就是手写一个 .manifest XML 文件,不过这个办法在 VS 2005 编译出来的程序里似乎并不起作用。当然,新方法总是随之而出的,而且很“简单”(绕了一大圈又回来了):
在 Project Properties 对话框的 Configuration Properties | Linker | Manifest File | Additional Manifest Dependencies 选项里,填入:
"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'"
或者在程序里直接写下如下代码:
#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Test.Research.SampleAssembly' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='0000000000000000' language='*'\"")太阳又照常东升西落了
最近需要在家办公,硬盘空间又不够了,只好卸了 VS2008 重装 VS2005,结果无论通过控制面板的卸载还是通过光盘的 autorun.exe,都在检查配置的时候弹出“A problem has been encountered while loading the setup components. Canceling setup.”的错误对话框,然后就自动退出了,连修复的机会都完全不给……
放狗在 MSDN 的论坛里搜到了这篇帖子里 George175 给出的解决办法,原来是 VS2008 的一个 patch 捣的乱,直接进控制面板,进入添加/删除程序(或卸载程序),左边选择查看/卸载更新,找到“Hot Fix for Visual Studio 2008”这个玩意儿,直接咔嚓掉。
然后,VS2008 就能正常卸载了。
另,微软的一位同学说安装 VS2008 SP1 也能解决,没有验证,应该不会有错。
- 块选中
- 整行剪切 / 复制 / 粘贴
- Clipboard Ring
- 代码重构
类似 UltraEdit 里的“列模式”,按住 Alt 键再移动光标,就可以选择一块范围内的内容,而不必被束缚在只能一行接一行的选中方式了。
平时我都是用鼠标移到一行最左边的行号区去选中一行,然后执行复制或拖动等操作,其实,只要光标在某一行,直接按 Ctrl + X / Ctrl + C,就等于剪切/复制整行了,非常方便。
一直以来,当需要在多个文件中复制粘贴多个内容时,我都很笨地挨个 Ctrl + C / Ctrl + V,从来也懒得想是不是该搞个 multi-clipboard 工具来提高效率 -,-|||
其实,从 VS2003 开始,VS 就已经内置了多重剪贴板的功能,虽然只支持当前 VS 进程内多文件间的复制粘贴,这就是 Clipboard Ring。Clipboard Ring 采用 LIFO(后进先出)的方式组织,即最后被复制或粘贴的内容排在环的最前面,最大支持 10 块剪贴板。用法很简单,对需要复制的多个内容块按 Ctrl + C,然后到需要粘贴的地方按 Ctrl + Shift + V,选择需要粘贴的内容就 Ok 了。每个 VS 版本的 Clipboard Ring 操作略有不同,在此不赘述了。
待续……
CTreeCtrl 的 GetNextItem 成员函数很诡异,nCode 设为 TVGN_NEXT | TVGN_CHILD 会一直返回传进去的 hItem 值,而不是返回下一个兄弟 item “或”第一个 child item。
所以,只好自己写遍历函数,没有采用递归的做法,用了一个 STL List 容器来保存下一个兄弟 item 和第一个 child item,遍历返回的依据是 item 的 lParam 值等于给定的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | HTREEITEM CModelNodeTreePane::_GetTreeItemByID(const unsigned int uiItemID) { HTREEITEM hCurrItem = m_kModelNodeTreeCtrl.GetRootItem(), hItem; std::list kItemList; kItemList.push_back(hCurrItem); while (kItemList.size() > 0) { hCurrItem = kItemList.front(); kItemList.pop_front(); if ((unsigned int)m_kModelNodeTreeCtrl.GetItemData(hCurrItem) == uiItemID) { return hCurrItem; } if ((hItem = m_kModelNodeTreeCtrl.GetChildItem(hCurrItem)) != NULL) { kItemList.push_back(hItem); } if ((hItem = m_kModelNodeTreeCtrl.GetNextSiblingItem(hCurrItem)) != NULL) { kItemList.push_back(hItem); } } return NULL; } |
由于程序里的 CTreeCtrl 控件实例是通过 CTreeCtr::Create() 来创建的,无法通过 VS 的 Properties 面板里的 Control Events 工具来生成消息映射函数,但控件又需要响应鼠标点击事件,这时最简单的办法就是重载 CTreeCtr 实例的 owner 的 OnNotify() 成员虚函数(这个 owner 也必然是 CWnd 的子类):
protected: virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | BOOL CTreePane::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { NMHDR* pNMHDR = (NMHDR*)lParam; ASSERT(pNMHDR != NULL); switch (pNMHDR->code) { case TVN_SELCHANGED: _OnTreeCtrlSelChanged(wParam, lParam, pResult); break; default: break; } return CWnd::OnNotify(wParam, lParam, pResult); } |
Internet Explorer 8 正式版会导致 Visual Studio 2005 / 2008 里的部分 VC++ 向导出错,包括:
- Add Function
- Add Variable
- Smart Device – New Project Creation
- Smart Device – Add Class
VC++ 团队给出了解决方案:
- 运行注册表编辑器 regedit(64 位系统请使用 32 位版本)
- 定位到“HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones”下 - 新建一个名为 1000 的项
- 在 1000 这个项下,新建一个 DWORD 值,名为 1207,值为 0x000000
然后重启 VS 即可。
注意:VS 2005 必须装上 SP1。
想深究这个问题原因,可以参看原文。
