TONT 37533 即使是内部数据也会有兼容性约束的需求

原文链接:https://devblogs.microsoft.com/oldnewthing/20041019-00/?p=37533

The Listview control when placed in report mode has a child header control which it uses to display column header titles. This header control is the property of the listview, but the listview is kind enough to let you retrieve the handle to that header control.

当Listview控件置于报表模式下时,其内有一个表头控件,用来展示列标题。这个表头控件是属于Listview的“私有财产”,不过Listview很大方,允许你去获取这个表头空间的句柄。

And some programs abuse that kindness.

而有些应用程序就滥用了这种大方。

It so happens that the original listview control did not use the lParam of the header control item for anything. So some programs said, “Well, if you’re not using it, then I will!” and stashed their own private data into it.

凑巧,原始版本的Listview没有使用这个表头控件的lParam,这时个别程序就决定,『你不用的话,我就用一下好了!』然后将其内部数据塞了进去。

Then a later version of the listview decided, “Gosh, there’s some data I need to keep track of for each header item. Fortunately, since this is my header control, I can stash my data in the lParam of the header item.”

后续版本的Listview做了个决定:『哎呀,这些个表头有些数据我得跟踪监视,不过还好,这个表头控件是属于我的,只要把数据藏进lParam里去修好了。』

And then the application compatibility team takes those two ingredients (the program that stuffs data into the header control and the listview that does the same) to their laboratory, mixes them, and an explosion occurs.

后来,应用程序兼容性团队把这两种成分(把私有数据塞进表头控件里的应用、和同样这样做的Listview)带进了实验室,将二者混合,然后就炸了。

After some forensic analysis, the listview development team figures out what happened and curses that they have to work around yet another program that grovels into internal data structures. The auxiliary data is now stored in some other less convenient place so those programs can continue to run without crashing.

经过一番正经八百的论证,Listview控件的开发团队找到了问题的原因,并选择在这又一个随便挖进内部数据结构的应用程序面前退让一步。前面提到的辅助数据现在被放进了不太容易被乱来的地方,这样那个乱改(Listview)内部数据的程序就能继续运行而不崩溃了。

The moral of the story: Even if you change something that nobody should be relying on, there’s a decent chance that somebody is relying on it.

故事的寓意是:即便你修改了别人不该依赖的位置,还是有相当的可能有人是依赖它的。

(I’m sure there will be the usual chorus of people who will say, “You should’ve just broken them.” What if I told you that one of the programs that does this is a widly-used system administration tool? Eh, that probably wouldn’t change your mind.)

(我敢肯定肯定又有很多人要说,『别管那家伙不就好了』,要是我告诉你这样做的程序之一是某个被广泛使用的系统管理工具呢?不过,这大概也不会让你收回前言吧。)

TONT 37623 为什么会有一个单独的 GetSystemDirectory 方法?

原文链接:https://devblogs.microsoft.com/oldnewthing/20041008-00/?p=37623

If the system directory is always %windir%\SYSTEM32, why is there a special function to get it?

如果系统目录总会是 %windir%\SYSTEM32,为什么还有专门的一个方法来获取它?

Because it wasn’t always that.

因为并不总是如此。

For 16-bit programs on Windows NT, the system directory is %windir%\SYSTEM. That’s also the name of the system directory for Windows 95-based systems and all the 16-bit versions of Windows.

对于 Windows NT 下的 16 位应用程序来说,系统目录是 %windir%\SYSTEM。对于以 Windows 95 为基础、以及所有16位版本的 Windows 来说也是如此。

But even in the 16-bit world, if it was always %windir%\SYSTEM, why have a function for it?

然而,即便在16位的世界里,如果系统目录总会是 %windir%\SYSTEM 的话,那为什么还需要专门的一个方法呢?

Because even in the 16-bit world, it wasn’t always %windir%\SYSTEM.

因为即使在16位的世界里,也并不总是如此。

Back in the old days, you could run Windows directly over the network. All the system files were kept on the network server, and only the user’s files were kept on the local machine. What’s more, every single computer on the network used the same system directory on the server. There was only one copy of USER.EXE, for example, which everybody shared.

在过去,你可以直接通过网络来运行Windows。所有的系统文件都存放在网络服务器上,只有用户的文件保存在本地。另外,网络上的所有计算机都会调用服务器上相同的系统目录,例如,只会有一份USER.exe供所有人共享使用。

Under this network-based Windows configuration, the system directory was a directory on a server somewhere (\\server\share\somewhere) and the Windows directory was a directory on the local machine (C:\WINDOWS). Clients did not have write permission into the shared system directory, but they did have permission to write into the Windows directory.

在这种以网络为基础配置的Windows环境下,系统目录是存放在服务器上的某处的(例如\\server\共享名\共享目录),而Windows目录是本机上的某个文件夹(例如C:\WINDOWS)。客户端没有权限写入系统目录,不过的确有权限对Windows目录进行写入。

That’s why GetSystemDirectory is a separate function.

这就是为什么GetSystemDirectory是单独存在的一个方法。

TONT 37903 有时候游戏的 bug 不玩到后期是体现不出来的

原文链接:https://devblogs.microsoft.com/oldnewthing/20040910-00/?p=37903

I didn’t debug it personally, but I know the people who did. During Windows XP development, a bug arrived on a computer game that crashed only after you got to one of the higher levels.

我并不亲自进行调试工作,不过我认识做这项工作的人。在 Windows XP 的开发过程中,曾经有款游戏的一个 bug,只有玩到进度比较深入的时候才会显现,并使游戏崩溃。

After many saved and restored games, the problem was finally identified.

存档读档很多次之后,问题终于定位出来了。

The program does its video work in an offscreen buffer and transfers it to the screen when it’s done. When it draws text with a shadow, it first draws the text in black, offset down one and right one pixel, then draws it again in the foreground color.

游戏的程序在一处屏幕外的缓冲区中处理图像,当处理完成后,再传输到屏幕上。绘制带阴影的文字时,程序会先以黑色将文字绘制一遍,将其向右、向下移动各1个像素,然后再用前景色将文字绘制出来。

So far so good.

到此为止还没什么问题。

Except that it didn’t check whether moving down and right one pixel was going to go beyond the end of the screen buffer.

只是开发商忘了检查向右、向下移动各1个像素的时候,有没有超出屏幕缓冲区的边界。

That’s why it took until one of the higher levels before the bug manifested itself. Not until then did you accomplish a mission whose name contained a lowercase letter with a descender! Shifting the descender down one pixel caused the bottom row of pixels in the character to extend past the video buffer and start corrupting memory.

这就是为什么只有打到高等级的时候 bug 才会显现,因为直到那时才会完成一个任务,而这个任务的名字里有一个带下延部(注1)的小写字母!将这个字母的下延部下移1个像素,会导致底部一行的像素超出视频缓冲区,进而损毁了内存数据。

Once the problem was identified, fixing it was comparatively easy. The application compatibility team has a bag of tricks, and one of them is called “HeapPadAllocation”. This particular compatibility fix adds padding to every heap allocation so that when a program overruns a heap buffer, all that gets corrupted is the padding. Enable that fix for the bad program (specifying the amount of padding necessary, in this case, one row’s worth of pixels), and run through the game again. No crash this time.

找到问题的根源后,修复起来就相对比较容易了。应用程序兼容性团队有一口袋的戏法,其中之一名叫『HeapPadAllocation』。这一兼容性修复补丁会为每个堆分配增加一块补丁,这样当程序发生了堆缓冲区溢出的问题时,弄坏的就只是这块补丁而已。为这个惹事的程序启用这个补丁(指定所需的补丁大小,此处即1行像素的尺寸),再运行游戏,就不会再崩溃了。

What made this interesting to me was that you had to play the game for hours before the bug finally surfaced.

这件事让我感到有趣的一点是,你得把这款游戏先玩上4个小时,然后bug才会崭露头角。


注1:在西文字体排印学中,降部(英语:Descender)指的是一个字体中,字母向下延伸超过基线的笔画部分,也称为下延部。如图所示,字母y第二笔的“尾巴”部分就是降部。另外字母v两条对角线连接的时候也有超过基线的部分,虽然很少,但也是降部。(以上信息来自维基百科『降部』词条

TONT 37983 为什么Windows会将你的BIOS时间设定为本地时间?

原文链接:https://devblogs.microsoft.com/oldnewthing/20040902-00/?p=37983

Even though Windows NT uses UTC internally, the BIOS clock stays on local time. Why is that?

尽管 Windows NT 内部使用 UTC 时间,但 BIOS 的时钟却仍然设定为本地时间,这是为什么呢?

There are a few reasons. One is a chain of backwards compatibility.

原因有几个,其中之一是一系列向下兼容性问题。

In the early days, people often dual-booted between Windows NT and MS-DOS/Windows 3.1. MS-DOS and Windows 3.1 operate on local time, so Windows NT followed suit so that you wouldn’t have to keep changing your clock each time you changed operating systems.

早年间,人们经常在 Windows NT 和 MS-DOS / Windows 3.1 之间双启动。MS-DOS 和 Windows 3.1 使用本地时间,所以 Windows NT 延续了这一设计,以便你每次更换(启动的)操作系统的时候不用总是去修改时间。

As people upgraded from Windows NT to Windows 2000 to Windows XP, this choice of time zone had to be preserved so that people could dual-boot between their previous operating system and the new operating system.

后来人们从 Windows NT 升级到了 Windows 2000 直至 Windows XP,对于时区的设定也需要被保留,以便于人们可以在以前和后来的操作系统间进行双启动。

Another reason for keeping the BIOS clock on local time is to avoid confusing people who set their time via the BIOS itself. If you hit the magic key during the power-on self-test, the BIOS will go into its configuration mode, and one of the things you can configure here is the time. Imagine how confusing it would be if you set the time to 3pm, and then when you started Windows, the clock read 11am.

另一个将 BIOS 时钟设定为本地时间的原因是避免使人们通过 BIOS 设置程序设定时间时产生疑惑。如果在开机自检的时候按下相关的按键,BIOS 会进入设置模式,其中一项可以进行设置的就是当前时间。想象一下如果你把时间设置为下午3点,等进了 Windows 时却发现时间变成了早上11点的感觉。

“Stupid computer. Why did it even ask me to change the time if it’s going to screw it up and make me change it a second time?”

『电脑这玩意简直太蠢了,既然它又会把时间设置搞乱再让我去修改第二次,那从一开始为啥要让我去改呀?』

And if you explain to them, “No, you see, that time was UTC, not local time,” the response is likely to be “What kind of totally propeller-headed nonsense is that? You’re telling me that when the computer asks me what time it is, I have to tell it what time it is in London? (Except during the summer in the northern hemisphere, when I have to tell it what time it is in Reykjavik!?) Why do I have to remember my time zone and manually subtract four hours? Or is it five during the summer? Or maybe I have to add. Why do I even have to think about this? Stupid Microsoft. My watch says three o’clock. I type three o’clock. End of story.”

这时候如果你像这类人去解释:『不是的,那个时间是 UTC 时间,不是本地时间』,很可能会被回击『那又是他喵的什么鬼东西?你是说电脑让我设置时间的时候,我得把伦敦时间给输进去?(除了北半球夏季的时候,那就得输入雷克雅未克的时间了!?)凭什么我得记住我所在的时区,然后手工减去四个小时,或者夏令时的时候得减五个小时?哦,有时候还得用加的,为什么我非得做这些事不可啊?傻×微软,我的手表说现在是三点,我就输入三点,完事。』

(What’s more, some BIOSes have alarm clocks built in, where you can program them to have the computer turn itself on at a particular time. Do you want to have to convert all those times to UTC each time you want to set a wake-up call?)

(更有甚者,有些 BIOS 还有内置的闹钟功能,可以通过设置它来让计算机在特定的时间启动。你会乐意每次设置它之前,手工先将所有的时间转成 UTC 时间吗?)

Day 5151 长颈鹿复制器

  日常工作中,本人遇到一个非常具体的问题:由于日常需要将书籍印刷的文件进行归档处理,而这些文件中,很大一部分是InDesign设计文件的链接图(即印刷文件中调用的图片),而这些链接图的文件名由于编辑和排版人员的习惯问题,常常会遇到文件名超级长的场合,例如:

北京故宫南北长961米,东西宽753米,面积约为725000平方米,四周环以城墙,外围有护城河保护。有四门:正南为午门,东为东华门,西为西华门,北为玄武门(神武门)。现神武门为故宫博物院正门。城墙高9.9米厚8.26米.jpg

  类似这样的文件名,在存在于单层目录中时问题不大,然而归档的时候,由于需要按照日期等建立深层目录,形如:

Z:\排版文件\已定稿印刷\故宫的历史(全12册)\故宫的历史(2020年第1期)\Links

  此时会撞上Windows传统的路径长度260字符限制,以往的处理方式都是将复制时出现这样问题的文件名进行缩短,直至路径长度达到允许值为止,但在某次某本书里有几十个类似情况后,深感崩溃。

  读到这里,急着抬杠的大聪明请先看以下几条,不服的请关掉本窗口,因该工具与您无关:

  1、由于印刷文件后期需要进行导出PDF等操作,必须将排版文件内的图片与实际文件进行链接,故不宜将文件名胡乱修改为1.jpg、2.jpg这样毫无意义的文件名,不然在InDesign中进行重新链接时,就只能根据图像内容人眼识别了(InDesign没有根据图片内容或特征自动重新链接的功能),而这项工作是非常劳累的;

  2、原文件名中可能包含一些排版中没有的信息,如图片的作者姓名等,由于总数据量略多(大约50年左右的数据),实在无暇进行手工数据清洗;

  3、想提通过修改组策略或注册表在Win10下突破260字符路径长度的不必提了:首先目标机器是一台群晖,SMB共享无法突破此限制;其次,即使搞定了我的机器和群晖,还有众多最低使用XP的用户会访问这个资料库,升级系统是不可能的,故最终不要考虑该方式

  4、想让我去跟编辑、排版人员谈谈的可以休矣,我的职权有限,无权干涉别人的工作方式;

  5、想让我换工作的,您给介绍?不给就算了。

  如果到此还没有关掉窗口,请继续阅读。

  本软件的功能很简单,仅仅是调用了C#中最基本的File.Copy进行文件复制,唯对文件名缩短这一流程进行了自动化,即:当遇到文件名过长、导致路径超过260字符限制时,自动将文件名(不含扩展名部分)一个一个字符地进行缩短,直至可以成功复制为止,最大限度保留原文件名。最坏的情况为缩至1个字符仍无法复制,则会复制失败。

  由于该工具只是本人辅助工作的小工具,故可能永远保持目前的单一功能,不会进行更新,但欢迎有相同需要的用户进行试用、并反馈bug。

  本工具不能对长颈鹿进行复制(“长颈鹿”实际是对“长路径”的揶揄)。

  本工具实际与赤蛮奇没有关系(同样只是对“长颈鹿”的揶揄)。

  本工具需要 .Net Framework 4.6.1。

  下载地址

Day 5050 使用群晖作为UPS服务器联动Windows服务器关机

单位之前买了一台群晖DS416作为资料存储器,并在其后追加购置了一台APC BK650-CH的UPS作为掉电保护措施。该型号为后备式,并具备通讯端口,主要用于在市电断开时通知与之相连的设备进行关机,对群晖的硬盘起到保护作用。

后来,在群晖的旁边放置了一台组装的小服务器,运行 Windows Server 2008 R2 处理一些额外的事务。然而,该型号UPS只有一个通讯口,无法由UPS自身同时通知群晖和小服务器进行紧急关机。幸而,群晖支持作为UPS服务器使用,可由其通知其它最多5个设备的UPS客户端进行关机操作,以下为具体的配置过程,及尝试过程中遇到的一些问题的附录。

继续阅读 “Day 5050 使用群晖作为UPS服务器联动Windows服务器关机”

TONT 38233 时常被误解的 /3GB 选项

原文链接:https://devblogs.microsoft.com/oldnewthing/20040805-00/?p=38233

It’s simple to explain what it does, but people often misunderstand.

解释这个选项“是什么”很容易,但人们又误解它的含义。

The /3GB switch changes the way the 4GB virtual address space is split up. Instead of splitting it as 2GB of user mode virtual address space and 2GB of kernel mode virtual address space, the split is 3GB of user mode virtual address space and 1GB of kernel mode virtual address space.

/3GB 选项使得 4GB 虚拟地址空间的划分方式发生了变化。原来是划分为 2GB 的用户模式虚拟地址空间和 2GB 的内核模式虚拟地址空间,启用后则变成了 3GB 用户模式虚拟地址空间和 1GB 内核模式虚拟地址空间。

That’s all.

仅此而已。

And yet people think it does more than that.

然而人们却仍然想太多。

I think the problem is that people think that “virtual address space” means something other than just “virtual address space”.

我认为,问题可能出在人们认为『虚拟地址空间』这个说法有其字面含义之外的东西。

The term “address space” refers to how a numerical value (known as an “address”) is interpreted when it is used to access some type of resource. There is a physical address space; each address in the physical address space refers to a byte in a memory chip somewhere. (Note for pedants: Yes, it’s actually spread out over several memory chips, but that’s not important here.) There is an I/O address space; each address in the I/O address space allows the CPU to communicate with a hardware device.

术语『地址空间』指的是当存取某种类型的资源时,一个数字值(即所谓『地址』)是如何被对应解释的。一种地址空间被称作物理地址空间,每个物理地址空间中的『地址』都指向在内存芯片中的某个字节。(致读死书者:没错,这个地址的确是囊括了多块内存芯片的范围,不过在这里这不是重点。)还有一种叫I/O地址空间,其中的地址使得CPU得以与某个硬件设备进行通讯。

And then there is the virtual address space. When people say “address space”, they usually mean “virtual address space”.

再来就是虚拟地址空间了。当人们提及『地址空间』时,通常指的就是『虚拟地址空间』。

The virtual address space is the set of possible pointer values (addresses) that can be used at a single moment by the processor. In other words, if you have an address like 0x12345678, the virtual address space determines what you get if you try to access that memory. The contents of the virtual address space changes over time, for example, as you allocate and free memory. It also varies based on context: each process has its own virtual address space.

虚拟地址空间是在某一时刻处理器可以使用的一组可能的指针值(地址)。换句话说,如果你有一个类似0x12345678这样的地址,那么如果试图访问这个地址的内存的话,是由虚拟地址空间来决定你获取到的内容的。虚拟地址空间的内容随时间不断变化,例如,每当分配和释放内存时(都会发生变化)。依据场景不同,虚拟地址空间的所指也会发生变化,每个进程都有其自己的虚拟地址空间。

Saying that 2GB (or 3GB) of virtual address space is available to user mode means that at any given moment in time, out of the 4 billion virtual addresses available in a 32-bit value, 2 billion (or 3 billion) of them are potentially usable by user-mode code.

有2GB(或3GB)虚拟地址空间对用户模式可用这个说法,意味着在任何给定的时刻,在32位值、共40亿的虚拟地址中,有20亿(或30亿)的地址对用户模式的代码是潜在可用的。

Over the next few entries, I’ll talk about the various consequences and misinterpretations of the /3GB switch.

在接下来的几篇文章中,我将讨论有关人们对/3GB选项的不同拓展解释,以及由此引发的误解。

TONT 38303 为什么应该使用凹陷的用户区域?

原文链接:https://devblogs.microsoft.com/oldnewthing/20040729-00/?p=38303

The WS_EX_CLIENTEDGE extended window style allows you to create a window whose client area is “sunken”. When should you use this style?

扩展窗体样式 WS_EX_CLIENTEDGE 允许你创建一个用户区域(client area)具有『凹陷』效果的窗口。为什么要使用这种窗口风格呢?

The Guidelines for User Interface Developers and Designers says in the section on the Design of Visual Elements that the sunken border should be used “to define the work area within a window”.
Specifically what this means is that a sunken client area indicates that the window is a “container”. So, for example, the Explorer contents pane gets a sunken client area since a folder “contains” its elements. Users expect to be able to manipulate the items inside a container. By contrast, a dialog box is not a container, so it doesn’t get a sunken client area.

《面向开发者和设计师的用户界面参考》在“视觉元素设计”一节(译注:原文链接已失效,按照下文提及该设计原则为1995年时的事,可能指的是这本书PDF文件原始链接在此)中,将凹陷的边框描述为“用以在窗口中划定工作区”。确切来说,其含义是指凹陷的用户区域表明该窗口是一个『容器』。因此,以资源管理器为例,其内容面板即为一个凹陷的用户区域,正是由于文件夹『容纳』了其中的元素,用户会期望在容器中对项目进行操控。反之,对话框并非一个『容器』,故其外观不会表现为凹陷的用户区域。

At least those were the rules back in 1995. Perhaps the rules have changed since then. (Indeed I wouldn’t be surprised if they have.)

至少1995年的时候规则是这样的。在那以后,规则大概已经发生变化了。(如果确实发生了变化,我也不会感到惊讶就是。)

TONT 38313 Windows UI 中『睫毛膏』(mascara)的进化史

原文链接:https://devblogs.microsoft.com/oldnewthing/20040728-00/?p=38313

The “look” of the Windows user interface has gone through fashion cycles.

Windows 用户界面的『观感』经历了几轮时尚风格的更迭。

(译注:下文中的 Windows 1.0 截屏链接已失效,上图来自 ToastyTech

In the beginning, there was Windows 1.0, which looked very flat because screen resolutions were rather low in those days and color depth was practically nonexistent. If you had 16 colors, you were doing pretty good. You couldn’t afford to spend very many pixels on fluff like borders, and shadows were out of the question due to lack of color depth.

一开始,是 Windows 1.0,那时候用户界面看上去非常平坦,因为那时的屏幕分辨率很低,并且色彩深度差不多还是不存在的东西。如果能用到16种色彩,就已经做得很不错了。你没有办法在例如边框这种小细节上浪费太多像素点,而阴影这种东西由于没有色彩深度,是完全不可能的事。

(译注:下文中的 Windows 3.0 截屏链接已失效,上图来自 ToastyTech

The “flat look” continued in Windows 2.0, but Windows 3.0 added a hint of 3D (notice the beveling in the minimize/maximize buttons and in the toolbar buttons on the help window).

这种『平面观感』延续到了 Windows 2.0 中,不过到了Windows 3.0 增加了一丁点的 3D 效果(注意观察最小化、最大化按钮以及在帮助窗口的工具栏按钮上出现的斜边)。

Other people decided that the 3D look was the hot new thing, and libraries sprung up to add 3D shadow and outlining effects to nearly everything. The library CTL3D.DLL started out as just an Excel thing, but it grew in popularity until it became the “standard” way to make your dialog boxes “even more 3D”.

其它人感到这种 3D 效果在当时是热门的新事物,为几乎所有东西增加3D阴影和边线效果的库突然开始涌现。CTL3D.DLL 一开始只是 Excel 的一个组件,但却逐渐普及开来,直到最终成为了使对话框变得『更加3D』的标准方式。

(译注:下文中的 Windows 95 截屏链接已失效,上图来自 ToastyTech

Come Windows 95, even more of the system had a 3D look. Notice the beveling along the inside edge of the panes in the Explorer window. Furthermore, 3D-ness was turned on by default for all programs that marked themselves as “4.0”; i.e., programs that were designed for Windows 95. For programs that wanted to run on older versions of Windows as well, a new dialog style DS_3DLOOK was added, so that they could indicate that they wanted 3D-ization if available.

到了 Windows 95 的年代,系统中有越来越多的组件拥有了 3D 外观,可以注意观察资源管理器窗口中面板内角的斜边效果。此外,3D 效果对于将自己标记为『4.0』的——亦即为 Windows 95 而设计——的应用程序是默认开启的。至于那些仍然希望可以在旧版本 Windows 上运行的应用程序,系统为其增加了一种新的对话框样式:DS_3DLOOK,以便程序向系统提出其在可用时对其应用3D效果。

(译注:若读者不是从 Windows 3.x 年代过来的人,可能理解不了下文中『睫毛膏涂坏』的效果,上图为调用了CTL3D32.DLL 的对话框样例,截图来自 malSmith.net

And if the 3D provided by Windows 95 by default wasn’t enough, you could use CTL3D32.DLL to make your controls even more 3D. By this point, things started getting really ugly. Buttons on dialog boxes had so many heavy black outlines that it started to look like a really bad mascara job.

如果 Windows 95 提供的 3D 效果还不够的话,你还可以调用 CTL3D32.DLL 来让你程序中的控件闲得更加 3D。至此,一切已经开始变得非常丑陋了。对话框中的按钮被添加了太多粗重的黑色边线,看上去就像把睫毛膏涂坏了一样。

Fortunately, like many fashions that get out of hand, people realized that too much 3D is not a good thing. User interfaces got flatter. Instead of using 3D effects and bold outlines to separate items, subtler dividers were used. Divider lines became more subdued and sometimes disappeared entirely.

幸运的是,就像那些失控的时尚潮流一样,人们开始意识到太多的 3D 效果并不是一件好事。用户界面(由此又)变得平面化起来。抛弃了运用 3D 效果和粗重的边线来划分窗体组件的做法,人们开始改用不易察觉的分隔线,而分隔线也变得越来越柔和,有时甚至完全消失了。

(译注:下文中的 Microsoft Money 截屏链接已失效,上图来自 Vector

(译注:下文中的 Office 2000截屏链接已失效,上图来自 Wikipedia

Microsoft Office and Microsoft Money were two programs that embraced the “less is more” approach. In this screenshot from Microsoft Money, observe that the beveling is gone. There are no 3D effects. Buttons are flat and unobtrusive. The task pane separates itself from the content pane by a simple gray line and a change in background shade. Even the toolbar has gone flat. Office 2000 also went largely flat, though some 3D effects linger, in the grooves and in the scrollbars (not visible in picture).

Microsoft Office 和 Microsoft Money 是两套拥抱『简单即为美』做法的应用程序。观察 Microsoft Money 的截屏,你会发现斜边效果不见了,3D 效果消失了,按钮变得平面化的同时也不再那么张扬了,任务面板通过划出一条简单的灰色直线、并改变其背景阴影的做法来将其与内容面板分隔开来,甚至工具栏都变『平』了。Office 2000 的界面也大范围变得平面化了,尽管在一些沟槽和滚动条上还是保留了一些 3D 效果(图中未展现)。

(译注:下文中的 Windows 95 截屏链接已失效,上图来自 ToastyTech

Windows XP jumped on the “flat is good” bandwagon and even got rid of the separator line between the tasks pane and the contents pane. The division is merely implied by the change in color. “Separation through juxtaposition.”

Windows 追随了『平面即是美』的风尚,甚至将任务面板和内容面板(译注:大概指的是资源管理器左侧的信息栏和右边驱动器内容)之间的分隔线都给去掉了,二者之间仅仅用颜色的变化稍作分隔,即所谓的『以反差做分隔』。

(译注:下文中的 Office XP 的截屏链接已失效,上图来自 Wikipedia

(译注:下文中的 Outlook 2003 的截屏链接已失效,上图来自 POP2IMAP.com

Office XP and Outlook 2003 continue the trend and flatten nearly everything aside from the scrollbar elements. Blocks of color are used to separate elements onscreen, sometimes with the help of simple outlines.

Office XP 和 Outlook 2003 延续了这一趋势,并将除了滚动条之外的几乎所有组件都扁平化了。色块被用来分隔屏幕上的元素,有时也会附加简单的边线。

So now the pendulum of fashion has swung away from 3D back towards flatness. Who knows how long this school of visual expression will hold the upper hand. Will 3D return with a vengeance when people tire of the starkness of the flat look?

现在时尚的钟摆又从 3D 荡回了平面,谁也不知道这一风潮能占上风多久。等到人们厌倦了平面观感的时候,3D 会不会杀个回马枪呢?

TONT 38343 二十英尺长的电脑

原文链接:https://devblogs.microsoft.com/oldnewthing/20040726-00/?p=38343

Back in the days of Windows 95, when Plug and Play was in its infancy, one of the things the Plug and Play team did was push the PCI specification to an absurd extreme.

回到 Windows 95 那时候,当即插即用(译注:链接已失效,指向页面为微软网站上介绍即插即用机制的页面,Web Archive 链接点击此处)年纪还小的时候,即插即用功能的研发组做了一件将 PCI 规范推向极致的事情。

They took a computer and put it at one end of a hallway. They then built a chain of PCI bridge cards that ran down the hallway, and at the end of the chain, plugged in a video card.

他们搬来一台电脑,将其置于走廊的一头,然后用一大溜 PCI 桥接卡从走廊的一头一直串联到另一头,最后在这个桥接卡链的末端插上了一张显卡。

And then they turned it on.

然后他们将电脑启动了起来。

Amazingly, it actually worked. The machine booted and used a video card twenty feet away. (I’m guessing at the distance. It was a long time ago.) It took two people to operate this computer, one to move the mouse and type, and another to watch the monitor at the other end and report where the pointer was and what was happening on the screen.

令人惊讶的是这事还真成了。机器启动了起来,并调用了20英尺(译注:约6米以上)外的那块显卡。(距离我是用猜的,这已经是很久以前的事情了。)操作这台电脑需要两个人,一个人(在一头)移动鼠标、敲打键盘,另一个人在另一头盯着显示器,汇报鼠标箭头在什么地方、以及屏幕上显示的内容。

And the latency was insane.

至于延迟,已经达到了难以言喻的地步。

But it did work and thereby validated the original design.

不过说到底是能正常工作的,也由此证实了设计是有效的。

Other Plug and Play trivia: The phrase “Plug and Play” had already been trademarked at the time, and Microsoft had to obtain the rights to the phrase from the original owners.

另一则关于即插即用的琐事:『即插即用』这个短语当时已经是商标了,所以微软不得不从其持有人那里获取使用权。