← 返回信息流
AI 资讯Hacker News·2 天前

Windows 1.0与WinAPI诞生40周年

原标题:Windows 1.0 and the WinAPI, 40 Years Later

速览

本文回顾了Windows 1.0及其核心应用编程接口WinAPI发布40周年的历史。作为微软早期图形界面的里程碑,WinAPI奠定了现代Windows软件开发的基础架构。这一历程展示了从早期个人电脑到现代计算环境的巨大技术变迁。

AI 深度解读

Windows 1.0 与 WinAPI:40 年后的兼容性回顾

背景

Windows 1.0 发布于 1980 年代中期,那是一个 16 位处理器、MS-DOS 占据主导以及协作式多任务处理(cooperative multitasking)盛行的时代。乍看之下,早期的 Windows 与现代操作系统似乎毫无共同之处,但在应用程序接口(API)层面,情况却截然不同。

为了探索这种差异,作者决定编写一个针对 Windows 1.0 的应用程序,旨在仅利用该版本最初的功能,构建一个包含图形渲染、键盘输入、定时器以及持续重绘机制的小型完整游戏——Xonix。这一实验不仅是为了重现历史,更是为了验证现代 WinAPI 与 40 年前最初版本之间的连续性。

核心内容

工具与架构:回归 K&R C 时代

项目使用了 Microsoft C 4.0 编译器,这是 Windows 早期的一款编译器,在 ANSI C 标准确立之前实现了 K&R C 标准。因此,代码采用了旧式的函数声明风格以及诸如 FARPASCAL 等已过时的编译器扩展。

这种风格在今天看来相当古老,但它精确地反映了原始的 WinAPI 编程模型:没有 C++,没有现代抽象层,只有纯粹的 C 语言和直接的系统调用。当时的窗口过程(Window Procedure)定义如下:

LRESULT FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND hWnd; unsigned int message; WPARAM wParam; LPARAM lParam;
{
    …
}

尽管系统年代久远,但应用程序架构却出人意料地熟悉。即使在当时,几乎所有核心的 WinAPI 机制已经存在,包括窗口过程、消息循环、定时器、资源管理、键盘处理和鼠标输入。

经典的 Win32/Win16 消息循环结构与今天几乎完全一致:

while (GetMessage(&msg, NULL, 0, 0))
{
    if (!TranslateAccelerator(hWnd, hAccelTable, &msg))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

这是整个实验中最令人惊讶的部分:尽管 Windows 内部在几十年间发生了巨大变化,但其应用程序接口保持了惊人的稳定性,使得 1980 年代中期编写的代码在今天看来依然完全熟悉。

游戏实现:极简主义与原生依赖

游戏实现仅使用了最基本的系统功能:

  • WM_PAINT 消息处理
  • SetTimer 定时器
  • 通过 GDI(图形设备接口)进行图形输出
  • 键盘消息处理

项目没有使用任何外部库或非标准组件,仅依赖 Windows 1.0 原生提供的功能。作者刻意遵循当时的编程风格,力求在原始 IBM PC 的最小硬件资源下实现流畅的性能。

值得注意的是,这段代码可以在不同的 Windows SDK 版本中无需修改即可编译,从 Windows 1.0 一直到现代的 64 位系统。除了早期 WinAPI 头文件中缺少少量定义外,代码具有完全的便携性。对于一款面向 1980 年代中期操作系统的软件而言,这种级别的兼容性显得非同寻常。

局限性:早期 Windows 的约束

尽管代码兼容性好,但早期 Windows 版本的局限性在今天看来依然明显:

  1. 协作式多任务:如果应用程序阻塞消息处理时间过长,整个系统将会冻结。
  2. 无双缓冲(Double Buffering):导致在活动重绘期间出现明显的闪烁。
  3. 内存极度受限:许多如今习以为常的功能在当时需要手动实现。

兼容性测试:二进制层面的奇迹

实验的另一部分是对已编译的 16 位 EXE 文件在后续 Windows 版本中的兼容性进行测试。

  • 成功运行的系统:该程序在从 Windows 1.x 到 32 位版本的 Windows 10 上均能无需修改地运行。
  • 例外情况
    • Windows 95:程序无法启动。这很可能是由于 Windows 9x 系列中 Win16 子系统的兼容性差异所致,而非 Win16 本身的根本性限制。
    • 现代 64 位 Windows:程序无法运行,因为现代 64 位版本的 Windows 已移除了对 16 位 Windows 应用程序的支持。

这一结果证明了真正的二进制级兼容性:同一个编译后的 EXE 文件可以在不同系统上运行,而无需重新编译或修改。

关键要点

  • API 的稳定性:尽管 Windows 内部架构历经数十年巨变,但其核心应用程序接口(WinAPI)保持了极高的稳定性。
  • 代码的长寿性:为 Windows 1.0 编写的代码,在 40 年后不仅依然可读,在某些情况下甚至可以直接编译和运行。
  • 原生依赖:通过仅使用 GDI、消息循环和基础系统调用,可以构建出功能完整的图形化应用程序,无需现代依赖库。
  • 二进制兼容性:16 位可执行文件在 32 位 Windows 系统(除 Windows 95 等特定版本外)上具有广泛的兼容性,体现了微软在向后兼容上的巨大投入。
  • 历史局限性:早期系统缺乏双缓冲、内存受限以及协作式多任务的缺陷,导致了闪烁和系统冻结等问题,这些是当时技术条件下的必然产物。

意义与影响

本次实验得出的主要结论是:原始的 WinAPI 设计取得了巨大的成功。尽管过去几十年间 Windows 经历了无数内部变革,但微软以极少的改动保留了核心应用程序模型。

在技术框架往往几年内就会过时的科技行业中,这种长达四十年的兼容性显得尤为非凡。它不仅展示了微软在 API 设计上的前瞻性,也证明了良好的软件架构设计能够跨越硬件代际和操作系统版本的更迭,保持长久的生命力。对于开发者而言,这也提醒我们,理解底层 API 的稳定性有助于构建更具韧性和可移植性的软件系统。

查看原文 →medium.com