Windows 1.03的SDK (1986)

有微软控为自己搞到并成功跑起Windows 1.x而兴奋异常,然而Windows 1.x的开发工具呢?就不是每个人都能跑起的了。至少我,就只能说部分跑起。
Windows 1.03 SDK应该不是唯一一个微软公开的Win1.x SDK,但却是现在唯一好找到的一个。

磁盘镜像们
图1 Win1.03 SDK的磁盘组成

七张360K的软盘镜像,在86年其实真的不算小了。。。
其实现在用虚拟机跑个DOS,远远比虚拟机跑更现代的系统麻烦。光往里面导入导出文件这一点,虚拟机的Additions当然不可能支持,网络就更麻烦(在DOS下想把网络驱动起来并支持TCP/IP,研究几个小时估计都只能找到Packet Driver什么的。。)因此,干脆不用虚拟机跑,用小模拟器DOSBox!

不过用DOSBox也一样有个麻烦,那就是DOSBox没有一个外部控制台,运行程序中更换软盘镜像不那么简单,因此还得用工具来把软盘镜像里的东西全弄出来。我用的是WinImage。

WinImage
图2 WinImage打开Win1.03 SDK的软盘镜像
解压出来的东西
图3 解出的文件和install.bat

系统要求:DOS 2.x或者3.x(这和Win1.x的要求一样,但用SETVER驱动设置或者dosver.exe辅助启动完全没问题),Windows 1.03或者更高,MSC 4.0/MSPascal 3.3/MASM4.0…..
MSC4.0什么的,我貌似有个不完整的版本。其实我还可以测试一下用MSC5.1。MASM么,我只有MASM5.1,得看看。
话说那个BAT我以前在DOSBOX就没执行成功过。。,干脆直接按照BAT手工复制了。
自带samples丢到samples目录下。
把那个MSC4.0,还有MASM5.1的masm.exe和cmacros.inc拷进去,还要一份Windows 1.01,得到如下目录结构。
其实还可能要一个DOS工具exe2bin,我直接把Win8 7850 里的丢进去了。。

Folder PATH listing for volume WIN7
Volume serial number is 754DC768 CC72
E:.
├─msc4
│  ├─bin
│  ├─include
│  │  └─sys
│  └─lib
├─samples
│  ├─CARDFILE
│  ├─CLOCK
│  ├─DEBUG
│  ├─FONTTEST
│  ├─HELLO
│  ├─MAPMODES
│  ├─MOTION
│  ├─MUZZLE
│  ├─NODEBUG
│  ├─SAMPLE
│  ├─SHAPES
│  ├─TEMPLATE
│  ├─TERMINAL
│  ├─TRACK
│  ├─TYPE
│  └─USER
└─WIN101
└─win1apps

配置环境变量(bin, include, lib)后试试看编译个自带sample。(CARDFILE)

MSC4编译器每次都要输入输出名什么的。。。(其实是因为我的MSC4不完整,少了cl.exe,我用msc.exe改名(4.0以后直到现在统一用cl.exe了)代替的,而它就是这样。。。

MSC4一直要求手工输入某些参数
图4 MSC 4.0 msc.exe运行

编译完成。去Windows1.01,运行下看看:

Win103 SDK Sample的Cardfile运行在Windows 1.01下
图5 编译的CARDFILE win1.01下运行

再编译几个
结果到template出错了。找不到MLIBC.lib

找不到mlibc
图6 找不到MLIBC

普及下背景知识,由于8086下64K一个段,总寻址空间1M的限制,DOS实模式(以及Windows1.x,2.x/286,3.0的实模式)下的C编译器都有好几种内存模式,比如很多人的入门编译器TC2.0就有6种内存模式。分这些内存模式主要是为多种情况优化所用,比如如果程序只需要跑在一个段中,那么使用tiny模式可以完全不生成远指针(跨段的指针,包括段号+地址)以加快速度和减少内存占用。
关于这个的深入了解,请参考TC的书(谭浩强那本没怎么讲这个),http://edu.codepub.com/2010/0512/22651.php这里也很有意思的。
C语言基本运行库大量涉及到内存操作,必须对这些不同的内存模式分别优化,因此才出现了每个内存模式一个libc的现象。以后还有浮点模型(模拟FPU,8087,无FPU)之分,运行库种类就更多了。。。
至于微软的C编译器,据说最初是买来的。它支持编译纯16位DOS/Win16程序的版本大概从2.0发展到7.0(现在VS2010中的版本是16.0),在4.0和5.x中支持Compact,Small,Medium和Large四个内存模式。我这个MSC4只有Small和Large的。。
cl/msc中设置内存模型的参数应该是-A?(-AL, -AS, -AM什么的)。
下面是编译出来的部分程序。什么?窗口不能重叠?你才知道Win1.x因为苹果的要求不能搞重叠多窗口么。。。

Win101跑SDK里的部分sample
图7 编译出的部分程序

其实这些程序一部分甚至可以在Win8 7850的NTVDM下正常使用的。你说刚打开窗口缩到左上角?你说图标是花的?这点等会再解释。

w8 ntvdm下的那些程序
图8 Win8 7850 NTVDM运行编译出的部分程序

Windows SDK从来都包含资源编辑器什么的小工具,1.03的sdk也不例外。
这三个,Shaker、Heapwalk是显示句柄和内存分配信息的调试类工具,Slapjr是个截图器(保存黑白图像到剪贴板而已。。)

w103sdk调试类工具
图9 Win1.03 SDK的调试类工具

这两个,ICONEDIT和dialog就不用说了,图标编辑和对话框资源生成。。。

win103 sdk 辅助类工具
图10 Win1.03 SDK的辅助类工具

好了。看过这么多图,想不想看个最简单的Win1.03程序是什么样的?我临时写了一个。。。
首先看主文件my101.c

#include 
#include 
#include "my101.h"

FARPROC pMy101Dlg;
char winver[10];
BOOL FAR PASCAL My101Dlg( HWND, unsigned, WORD, LONG );
/*注意,MSC4.0还是K&R C标准的,不能用ANSI式的函数声明*/
int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
	pMy101Dlg = MakeProcInstance( (FARPROC)My101Dlg, hInstance ); /*Win16中函数指针不能直接作为回调函数传,必须加这么一个。。*/
	if(pMy101Dlg)
		DialogBox(hInstance, MAKEINTRESOURCE(MY101DLG), 0, pMy101Dlg);
}

BOOL FAR PASCAL My101Dlg( hDlg, message, wParam, lParam )
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
	static WORD wver;
	static WORD mav,miv;
	switch(message)
	{
	case WM_INITDIALOG:
		wver=GetVersion(); /*获取版本号*/
		mav=LOBYTE(wver);
		miv=HIBYTE(wver);
		sprintf(winver, "%d.%2d", mav, miv);
		SetDlgItemText(hDlg, VERTXT, winver);
		break;
    case WM_COMMAND:
		switch (wParam)
		{
		case IDOK:
		case IDCANCEL:
			EndDialog( hDlg, TRUE );
			return TRUE;
		case ABOUTME:
			MessageBox(hDlg, "By yksoft1 in 2011.5.29 \nfor Windows 1.03 SDK",
				"Created",MB_OK|MB_ICONEXCLAMATION);
			break;
		}
		break;
	default:
		return FALSE;
	}
	return TRUE;
}

包含文件my101.h

#define MY101DLG   1
#define VERTXT     1800
#define ABOUTME    1801
#define ABOUTBOX 2

资源脚本my101.rc

#include 
#include "my101.h"

MY101DLG  DIALOG  12, 19, 107, 63
STYLE WS_POPUP | WS_DLGFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "yksoft1's Win103SDK test1"
BEGIN
    LTEXT  "Winver" -1, 14, 12, 24, 8
    EDITTEXT  VERTXT, 57, 10, 32, 12,  WS_GROUP
    DEFPUSHBUTTON "OK" IDOK, 15, 36, 24, 14, WS_GROUP
    PUSHBUTTON "About" ABOUTME, 61, 35, 27, 14, WS_GROUP
END

链接信息文件my101.def

NAME my101
DESCRIPTION 'yksoft1''s Win1.03SDK Test'
STUB    'WINSTUB.EXE'
CODE    MOVEABLE
DATA    MOVEABLE MULTIPLE
HEAPSIZE  512
STACKSIZE 4096
EXPORTS
    My101Dlg @1

其实做过纯Win32 SDK的肯定发现,除开.def,这里面几乎所有东西都是熟悉的。这才是Windows一直有那么好的向下兼容性的根本原因,也是Windows多年来在应用层那些新东西总是替代不了原有的东西的根本原因。那个.def其实只是描述链接时可执行文件中应当有的段,堆和栈的大小,导出函数(Win16不是有内存保护的系统,所有程序的回调函数必须直接在系统调用表中)等的描述文件。其实我还忘了贴上Makefile,但是完全是抄袭的示例中的HELLO的Makefile,就算了。
看看这程序在多个系统下运行情况吧。

my101 on win101
图11 例子在Windows1.01下运行
My101 on win31
图12 例子在Windows3.1下运行
my101 on w87850
图13 例子在Windows 8 7950 NTVDM下运行

什么你看到了3.95? 当初微软将Win3.1作为最后的16位Windows,既为了兼容性又为了方便16位程序识别Win95和NT4以上,才对16位的GetVersion返回3.95这个虚构的版本号。
现在说说为何高版本系统下跑Win1.x的程序,窗口缩在左上角吧。看HELLO中的一段代码:

    hWnd = CreateWindow((LPSTR)szAppName,
                        (LPSTR)szMessage,
                        WS_TILEDWINDOW,
                        0,    /*  x - ignored for tiled windows */
                        0,    /*  y - ignored for tiled windows */
                        0,    /* cx - ignored for tiled windows */
                        0,    /* cy - ignored for tiled windows */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

ignored for tiled windows? 问题是这是程序主窗口的CreateWindow!Win2.x和后来的所有Windows中, WS_TILEDWINDOW等于 WS_OVERLAPPEDWINDOW,不会忽略窗口的尺寸值,直接在1.x SDK编译的程序,在高版本Windows中,按0,0的坐标建立长0宽0的标准窗口,自然缩到左上角去了。高版本Win那个CW_USEDEFAULT,在这里其实可以加进去,反正1.x会ignore掉。
图标乱掉是肯定的,Windows 1.x和2.x资源格式和后来的系统不通用,不支持彩色图标和位图。而且由于Windows 3.0以前的程序喜欢直接调DOS中断、直接访问内存什么的,Windows 3.1,各版本NTVDM都有了这么个提示(Win9x会直接不让运行):

win3.1 compatbility warningw8ntvdm compatbility tip
图14,15 对小于Win3.0的程序的警告

作为本博第一篇第三方文章,这篇文还是很有意思吧~为了保持神秘感暂时不放出什么下载,看评论情况了。yksoft1保留此文版权,有权把文章发表至其他地方。

Windows 1.03的SDK (1986)》有43个想法

  1. 小邪

    你临时写了一个?。。。。太凶残了。。。直接在文本编辑器下面?
    P.s. 前段时间失踪,补课老文章中。嘎嘎嘎。

    Google Chrome 13.0.782.24 Google Chrome 13.0.782.24 Windows 7 x64 Edition Windows 7 x64 Edition
    回复
  2. overmind

    大哥 我想拜你为师 不过我是男人 可以么
    我在北京 想请你吃饭 并且求win1.0的安装盘 我在dos7.1下面怎么都装不上的 应该如何办?

    Google Chrome 16.0.912.63 Google Chrome 16.0.912.63 Windows Vista Windows Vista
    回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注