最近从架构的角度做了一个 Windows 8 下 Metro Style 应用程序开发介绍的讲座。以下是讲稿。
如有问题欢迎指正。
下载地址:
这篇的标题叫做Windows RT Introduction而非Windows 8 Introduction是想强调此次介绍是从开发人员的角度而不是普通用户的角度出发的。同时,我们关注的是Metro Style应用而不是传统的Win32应用程序的开发。
实际上,使用C#或者HTML + Javascript书写一个Hello world应用的代码例子已经在网上泛滥了。但是仅有一个Hello world并不能够说你掌握了Win RT的开发。从Pro的角度来说我们应该弄清楚整件事情的细节。那么首先就应当是他的架构。这样写起程序来才能心定。
2 Windows 8 Metro与Desktop模式 2.1 两种模式Windows 8的应用程序显示模式目前有两种,定义在METRO_MONITOR_MODE中:即传统的桌面模式(MMM_Desktop)以及Metro模式(MMM_Metro)。如果你是Windows Phone用户的话可能就会对Metro比较熟悉。事实上,微软在2009年启动Windows 8的研发工作时目标是创造一个完全不同以往的操作系统,完全不以之前的操作系统为蓝本。而后发现Desktop应用是不可或缺的部分而将两个部分进行合并。一开始用可能会有些别扭,但是我估计开发人员半天之内就能够熟练使用这个系统了。
2.2 Metro和Desktop的一些不同既然有两种模式那么我们自然就会关注他们的不同点。这个问题应该从架构图上做一下说明但是我们可以先有一些直观的认识。
2.2.1 Message Loop消息处理的编程是传统Desktop应用程序的重要部分。你需要书写维护Message Loop的代码。例如:在WinMain调用(或者其子例程中)你需要书写类似
while (::GetMessage(&message, NULL, 0, 0)) {
::TranslateMessage(&message);
::DispatchMessage(&message);
}
而在Window创建之前候你一定指定了
WNDCLASS wndClass;
// ...
wndClass.lpfnWndProc = WndProc;
这样你就可以在WndProc函数中决定特定message的流向了。对于绘图来说,你一定是接受了WM_PAINT消息,然后执行了区域重绘。
但在Metro App中这些都已经隐藏了,而且消息的细节也可能发生了变化。Metro App中你看不到消息循环。一切关于界面消息的分发都隐藏在了CoreDispatcher中。因此如果你用Spy++去试探Metro App的消息循环那么你什么都抓不到。
2.2.2 Display在传统的Desktop应用程序中,绘图可能通过GDI,GDI+,DirectDraw,DirectX进行。同样通过捕获WM_PAINT消息或者当系统处于IDLE的时候进行绘图(对于游戏编程来说)。
而Metro App不会再支持GDI和GDI+,在Metro App中绘图只能通过DirectX来进行。确切的说是Direct3D和新公布的Direct2D、Direct Write API。因此Metro应用的所有绘图都是希望是硬件加速的。这种绘图更高效,解放CPU,而且一般不需要处理复杂的Dirty Region Repaint。
2.2.3 Life CycleMetro App并没有关闭窗口这种按钮。其生命周期是由系统托管的。系统会决定仅仅是挂起应用执行还是需要完全销毁应用进程。这和一般意义上的Desktop应用程序不一样。(当然,你也可以使用Alt+F4显示的结束Metro App的执行)。
2.2.4 Share & Communication传统的桌面应用程序有多种手段进行公共组建的公用或IPC。但是在Metro App中,隔离是一个很重要的概念,应用的可执行部分,运行库,Isolated Storage都是独立的,不能够共用。同样,不能够使用传统的IPC机制。应用程序的互动仅仅可以通过内置的Contracts进行,关于这一部分内容可以查看MSDN:
2.2.5 Portability传统的Desktop应用程序的支持大多为x86/64架构的处理器。由于Metro环境可以完整运行在ARM处理器上是一个重要的特性,因此Metro App可以运行在ARM处理器上,美国服务器,即同时部署在PC和移动设备上。
2.2.6 OS Access当然为了Portability的要求,必然要求应用不能够越过Win RT的抽象,因此Metro是不能像Desktop App那样访问所有的Windows API的。
3 从Windows 8 API的架构图看Windows RT我们对Windows RT的介绍都将围绕着这个图展开。
在这个图中,最底层的是NT的内核;在其上是Windows子系统。实际上NT至少有三个子系统,Windows子系统,POSIX子系统(Unix)和OS/2子系统。POSIX子系统和OS/2子系统实际还是在使用Windows子系统。 在Windows子系统上划分了不同的运行时(橙色)和程序库(浅蓝色),最上面的绿色是我们使用的各种开发语言。
这个架构图实际上说明了一切。并且消除了很多误解:
(1) 第一个误解是INFOQ指出的Windows RT和Win32是完全分开的。这源于微软发布的一幅饱受批评的架构图,在那张架构图中,Windows RT和Windows子系统竟然是并排排列的。这是很荒谬的,Windows RT实际上基于Windows子系统。首先Windows RT完全基于COM;其次Windows RT利用了一部分现有的Win32 API;其余的部分Windows RT则直接访问NT内核。
(2) 第二个误解是C++/CX。C++/CX是微软推荐的开发Windows RT的方式。他主要隐藏了COM的复杂性。关于这个问题我们后续会有说明。这个误解是C++/CX实际就是C++ CLI。实际上这是两个完全不同的东西,C++ CLI是运行在托管环境下的,香港服务器租用,而C++/CX完全是Native的。
3.1 Windows RT仅用于Metro应用从架构图中可以看出,Win RT仅仅用于Metro应用。并秉承了我们刚才介绍的,简单部署,没有共享的组件,没有IPC,等等。
3.2 Windows RT构建与COM之上这也是为什么说Windows RT是构建与Win32之上,因为COM是Win32重要的组成部分。这意味着:
(1) 你可以用之前所有的消费COM的方式来使用Windows RT,你可以用C,你可以用ATL或者新的WRL;