分析Hilo项目

image

Hilo项目的类关系图,使用Visual Studio 2010的可视化和建模功能包创建。

Hilo项目是微软的一个用于演示Windows 7 API和Visual C++ 2010的功能的一个开源项目。这个项目不仅演示了Windows API的使用,而且也提供了设计和开发高性能Windows程序的建议。这个项目的目标在它的twitter主页表现无遗:将开发本地代码重新作为重点。

这个项目是基于免费的Visual C++ Express和Windows 7 SDK,这意味着更多的程序员可以尝试这个项目而不必购买Visual Studio 2010。这有助于扩展这个项目的影响力。不过这也意味着不能使用成熟MFC和ATL类库。作为替代,Hilo项目包含了以下类

  • ComPtr COM指针管理
  • WindowApplication 消息循环处理
  • Window 窗口API封装
  • WindowFactory 窗口类和窗口过程
  • WindowLayout 窗口布局
  • WindowMessageHandler 窗口消息分发

可以很明显地看到,这些类都被放在了一个比较容易重用的DLL模块里面,文档中也允许程序员在自己的程序中直接拿来使用。

由于WIndows Vista/7中WDDM 1.0的驱动是没有GDI硬件加速的,直到WDDM1.1才有有限度的支持,所以在不支持DirectX 10.1的显卡下GDI会很慢。在对于用户界面技术的选择上,Hilo项目组根据这个现象选择了在现代硬件上更快、更节省内存和CPU(当然,这也意味着更耗显存和GPU)的DirectX,而不是比较慢的GDI。这也减少了窗口的数目,整个程序现在只有一个窗口。这样做的好处是发明MFC的消息映射的时候所针对的项目需求,例如大量的窗口、很小内存、派生类需要继承消息处理函数现在都不成为问题了,所以在这唯一的一个窗口的过程里面可以放一个大大的switch语句。

Hilo在模块化这方面做得比较深好,基本上看到类名字就知道这个类是做什么的,不像看文档里面成员函数看到眼花的CWnd,可以看到Hilo对窗口的各个方面处理是分开的。而且虽然Hilo并不是一个COM服务器,但是在耦合的时候是使用COM的接口而不是直接使用类的名字,这样在编译的时候就可以执行类型检同时也保留可扩展性。MFC就做得比较差,不但CObject::IsKindOf需要在运行的时候判断,而且有引用视图类的头文件之前必须先包含文档类的头文件的问题。

比较遗憾的是,在推广本地代码开发方面,Hilo项目似乎做得还不够。Visual C++ Express的使用者主要是学生和业余人员,而这个项目演示的代码复用、COM和模板对于他们来说需要花一些时间来理解。另外,项目的许可协议看起来也让人一头雾水,里面把Hilo描述为软件而不是源代码。不过Visual C++项目组宣布这个项目的时候声称Hilo只是本地开发示例系列的第一个例子,作为原形来说,Hilo的作用在把”Cool”这个词和Windows本地开发联系起来这个方面还是做得不错的。上一次VC开发被人称为Cool的时间应该是远在98年了吧……

Posted in MFC, Visual C++, Visual Studio | Tagged , , , | 1 Comment

DirectUI和无窗口用户界面

DirectUI/DirectUser是一个微软的一个用户界面框架(http://msdn.microsoft.com/en-us/library/system.windows.automation.automationelement.automationelementinformation.frameworkid.aspx)。用Spy++可以在MSN Messenger、Windows XP、Office、IE和Windows Media Player中看到窗口类名字是DirectUIHWND的窗口。

从文件描述来看,DUI70.dll和DUser.dll看起来是这个框架的实现文件,而没有导入这些DLL的软件应该是复制了这个库的代码。举例来说,Windows Vista和IE7的测试版的IEFrame.dll导入了DUser.dll(http://social.msdn.microsoft.com/Forums/en-US/windowsuidevelopment/thread/6b801577-1699-4093-8a58-198c64b120e0)而正式版使用IEUI.DLL。这应该是微软不愿意公开支持这个功能变化频繁的框架,而反垄断案禁止非Windows组件调用未公开Windows API的缘故。

再看看DUser.dll的函数导出表(http://www.webtropy.com/articles/dll-api.aspx?dll=duser),可以看到Gadget这个词被广泛使用,而没有具体的控件。因为没有窗口句柄,所以控件不会是用的窗口类来区分,而是可能和Windows Vista Sidebar Gadgets一样采用HTML做接口(更正)从Office Communicator的资源来看,是用的XAML做的接口。

从这个类库的名字和行为来看,实际上应该是基于DirectX,和WPF类似的界面类库框架。在微软的招聘网站上可以看到Office Communications项目组的一个职位的介绍中描述说“Native Win32/64 UX experience via DirectUI, and Web UX experience via Silverlight”,说明这个项目组把它和Silverlight同等对待。DirectUIHWND窗口可以在需要性能和安全性的场合看到,例如IE的Tab窗口、Shell中的DefView、Windows登录界面等等。在Windows Vista上使用DirectUI的微软程序和WPF程序一样兼容Desktop Composition和远程桌面,应该是直接或者间接调用的Direct3D。

那么我们怎么做到类似的效果?

无窗口模式的用户界面并不是一个新的概念(http://blogs.msdn.com/oldnewthing/archive/2005/02/11/371042.aspx),VC的应用程序向导就可以创建无窗口ActiveX。但是做过无窗口模式的RichEdit的实现的人都知道,微软的系统控件集中了各种各样的功能,比如各种快捷键、滚动条、界面风格、Accessibility、用户界面自动化等等,要像IE项目组那样几乎完全实现无窗口并不容易。Raymond Chen在(http://blogs.msdn.com/oldnewthing/archive/2005/02/11/371042.aspx)提到可以使用DrawThemeBackground和DrawFrameControl这两个API,不过这只对和Windows界面风格一致的程序有用。要是界面不复杂的话,可以简单的集成IE的Trident引擎,比如使用MFC的CHTMLView和CDHTMLDialog,以及Windows Forms的WebBrowser类。这样做的代价就是程序需要牺牲性能和可能在严格的IE安全性配置下无法工作,Visual Studio.Net开始的各种向导、Google Task、Microsoft Outlook、Outlook Express等就是使用的这种方案。

另外一个方案就是集成WPF或者Silverlight。VC项目组在用户调查中发现,需要使用WPF的Visual C++用户大都用C#编写WPF代码再用C++/CLI和非托管代码做接口(http://social.msdn.microsoft.com/forums/en-US/wpf/thread/dd1e31bb-feb4-4d77-b524-42a282f519b1/),所以他们决定致力于改进更多用户使用的功能,例如编辑器的智能感知,而不提供对WPF的支持。Visual Studio 2010就是使用这种方案。

更新:泄漏出来的Windows 8的代号朱庇特的界面引擎是基于Direct UI。这个界面引擎同时支持托管和非托管语言。看来微软终于要开放这个API给程序员使用了。另外,最近XAML项目组分成Windows、Windows Phone和Visual Studio三个组,则可能意味着WPF/Silverlight会和朱庇特/Windows Phone更加紧密地集成。这可能也造成在跨平台Silverlight方面投入减少,目前Silverlight 5的新功能很多在和Windows集成方面。

为什么不能使用未公开的API?如果想看恐怖故事的话,可以参考

http://blogs.msdn.com/oldnewthing/archive/2003/12/23/45481.aspxhttp://blogs.technet.com/stefan_gossner/archive/2005/07/27/undocumented_API_Part1.aspx

题后话:

*如果微软在产品文档中讨论未公开的API,那么API还是未公开的吗?(http://msdn.microsoft.com/en-us/library/aa140182(office.10).aspx)

*Visual Studio代码画廊中有个叫作DirectUI的类库,设计思想和微软的DirectUser库类似(http://visualstudiogallery.msdn.microsoft.com/en-us/1B69C9FE-E422-4799-9EB5-6AC7034C52E1),不过也有人误认为这就是微软用来实现MSN Messenger界面的库。

*IE9使用Dierct2D作为渲染引擎。微软在一次Windows 8演示中曾经提到过如何用HTML5编写基于朱庇特和IE的渲染加速的程序,以至于很多WPF和Silverlight程序员大呼狼来了。估计在微软的Build会议之前,关于WPF和Silverlight的谣言仍旧会满天飞。

Posted in Visual C++ | Tagged , , , , | Leave a comment

Visual Studio 2010: Class Wizard重返Visual C++… Control Shift X.

image

在消失4个版本之后,类向导终于重返Visual C++。新的功能:搜索现在可以部分匹配而不是从字符串开始匹配。

测试版还是存在一些问题,向导不是总能找到现存的函数,以致删除函数功能不是总有效。在打开很多文档的时候尝试打开Class Wizard会出现“value does not fall in expected range” 错误。再就是性能问题,打开的文档越多,类向导启动所需的时间就越长。

Posted in 未分类 | 5 Comments

关于最近Visual Studio的ATL更新

如果使用Visual C++ 2005或者2008,那么这个更新可能已经被自动安装了。这个更新修补了ATl库中的一些安全问题。在安装这个更新之后,Visual C++运行时刻库会升级。这意味着如果代码面向的CRT版本是_CRT_ASSEMBLY_VERSION或者_BIND_TO_CURRENT_VCLIBS_VERSION,那么要随着新编译的程序发布新版本的CRT。如果程序没有定义这些宏,那么安全更新安装的重定向策略会把绑定到旧版本的引用自动转向新的CRT版本。

一个常见的问题是链接到旧版本的编译器生成的库文件。这样会在编译器生成的应用程序清单中生成两个不同版本的CRT引用。这时候要用合并模块或者手动编辑策略文件,确保重定向策略被正确安装到系统。

由于用户未必安装了Windows Update补丁,程序员需要随程序发布最新的Visual C++文件。对于vcredist发布的程序,可以直接下载Microsoft Visual C++ 2005 Service Pack 1 Redistributable Package ATL Security Update。这个再发布包也可以在安装了Visual Studio的计算机中找到。对于使用安装程序制作工具的场合,Visual Studio会更新安装和部署项目使用的合并模块(Program Files\Common Files\Merge Modules)和bootstrapper(Program Files\Microsoft SDKs\Windows\版本号\Bootstrapper\Packages或者Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages),第三方安装程序制作软件则可能需要安装补丁或者手动替换Visual C++文件。如果应用程序把VC文件发布到安装文件夹,那么安装文件夹内的文件也需要更新以使用最新的运行时刻库和版本重定向策略。

一些旧版本的Windows SDK也包含ATL,建议使用新版本的ATL以避免安全问题。如果在安装了Visual Studio 2008 SP1之后安装了Windows SDK 6.1,那么在编译ATL项目时会出现编译错误

error C2039: ‘_Swap_adl’ : is not a member of ‘std’ c:\program files\microsoft visual studio 9.0\vc\include\xutility 2764
error C3861: ‘_Swap_adl’: identifier not found c:\program files\microsoft visual studio 9.0\vc\include\xutility 2764

这是由于Windows SDK 6.1包含Visual Studio 2008版本的ATL。解决办法是卸载SDK和VisualStudio,先装SDK,后装Visual Studio、SP1和ATL更新。

这个更新包含的不只是ATL的头文件,可以在KB971092里面看到大堆的PDB和再发布文件也被更新了。不建议手动更改ATL头文件来绕过安全问题,这样的话微软的更新程序不能更新修改过的文件。如果你已经手动更改了ATL的头文件,可以重新运行VisualStudio安装程序,卸载VisualC++之后重新安装,再应用SP1和ATL更新。下次修改系统头文件的时候,可以把文件复制到自己的目录,修改之后更改Visual C++的目录搜索路径。

关于这个更新的更多信息,可以参考MSDN第9频道的视频

Posted in 未分类 | Tagged , | 2 Comments

415 Unsupported Media Type when WSE is NOT configured

I have a web service that runs fine on my Windows XP. However, when I deploy to the production server, the web service returns 415 Unsupported Media Type when calling.

I have seen this error when WSE is not enabled on the client. The problem is, the web service is NOT using WSE. so I did the usual, uninstall ASP.Net, reinstalling, adding asmx extension to IIS, same error.

Now I need to fire a debugger to see what’s going on. Surprisingly, Microsoft.Web.Services3.dll is loaded even when there is no trace of it in my projects. Now I probably know what’s going on. There is another web service in a different virtual directory that uses WSE.

OK, I will isolate my web service to a new application pool. Well, that does not help. In the end I have to add WSE configuration to both my web service and my Windows client.

Posted in 未分类 | Tagged | Leave a comment

VC项目组关于C++0x的主题讨论

VC项目组的成员正在Codeguru上接受关于C++0x的反馈和提问,地址是http://www.codeguru.com/forum/forumdisplay.php?f=98

上一次Visual C++ Yesterday, Today and Tomorrow的主题讨论地址在http://www.codeguru.com/forum/forumdisplay.php?f=89

Posted in 未分类 | Leave a comment

Visual C++ 10 和 MFC 10的新特性

Boris Jabes 和Damien Watkins将会在PDC上演示Visual C++10中的新功能。IDE的新功能包括基于SQL Compact的智能提示支持自定义插件的新的项目和编译系统、面向大型应用的优化和改善的调试体验。MFC库增加了对Windows 7 中新增的多点触摸检测功能高DPI支持,以及Windows Vista中集成的功能,例如高彩图标Windows 搜索重启管理器。Visual C++程序员们才习惯不用MFC来直接调API。

MFC是很老了,不容易学,也不优雅,但是很稳定,也有很多第三方扩展和示例支持。其他的用户界面库还有很多,但是单单用户界面并不能完成一个程序。在调用操作系统的底层功能的时候,有一个面向对象的接口还是很方便的。

Posted in 未分类 | Leave a comment

Type ‘System.Web.UI.WebControls.Parameter’ does not have a public property named ‘DbType’

In Visual C# 2005 SP1, I added an object data source to a web page that uses my business class as the select method. The method has one parameter of type Guid. The data source wizard generates code like this

<asp:Parameter DbType="Guid" Name="rowId" />

Although the web server has .Net 2.0 SP1 installed (I checked the registry), it still throws an error

Type ‘System.Web.UI.WebControls.Parameter’ does not have a public property named ‘DbType’

The walk around is easy:

<asp:Parameter Type="Object" Name="rowId" />

Posted in 未分类 | Leave a comment

MFC Feature Pack发布

Visual C++项目组今天发布了Visual C++ 2008 Feature Pack。这个Feature Pack包含了一些以前需要付费给BCG Soft才可以使用的控件,例如BCG著名的窗口布局和风格自定义功能,不过也有一些有用的控件,例如文件夹列表文件夹树属性窗格等等。

这个Feature Pack也包含从Dinkumware获得授权的一些对STL的扩展,实现了TR1草案。这包含新的随机算法、集合类和正则表达式支持。关于TR1的更多信息,可以参考Dinkumware的网站

安装了这个Feature Pack之后,生成的应用程序在发布时需要同时发布新版本的MFC和CRT组件。预计对这个Feature Pack的技术支持策略会和VC6中从Dinkumware获得授权的STL库会是一个级别,也就是说,BCG Soft、Dinkumware和微软都会提供技术支持。如果在安装了这个Feature Pack之后需要安装Windows SDK 6.1,那么在安装完SDK之后需要修复Visual Studio 2008以保持文件是最新的。

目前发布的这个补丁只支持英文版的Visual Studio 2008 标准版或更高版本,其他语言版的Visual Studio 2008 要获得这些新的功能的话,需要等到Visual Studio 2008 SP1发布。Visual Studio 2008会包含这个Feature Pack。

Posted in 未分类 | Leave a comment

MFC更新Beta版

一个面向Visual C++ 2008的MFC更新测试版已经发布,同时也提供了文档的下载。这个版本包含新的界面的特性,例如Office Ribbon、2003和XP风格,Visual Studio风格和MDI标签。另外,这个版本也包含部分TR1的实现,例如正则表达式、更加丰富的集合和智能指针。

另外,在下载页面居然说这个版本还不支持Visual Studio 2008 Service Pack 1的Beta版,正式版才出来几天SP1的测试版就出来了?

Posted in 未分类 | 1 Comment