转载自痴痴笑笑的博客,略有删改。
尽管 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)。
[ more... ]
微软同学永远是个把简单问题复杂化的孩子,这不,当年为了在 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 也能解决,没有验证,应该不会有错。
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。
想深究这个问题原因,可以参看原文。