将Win16 C代码转换为Win32

16

通常情况下,将一个16位的Windows程序转换为Win32需要做些什么?我相信我不是唯一一个继承代码库并惊讶地发现16位代码潜藏在角落里的人。

这个问题涉及到的代码是C语言编写的。


这是什么类型的应用程序? - David Nehme
在我们的代码库中,我发现了几个;大多数都是带有简单GUI的模拟器。关键的一个是用于与嵌入式设备通信的串行通信模块。它也具有GUI界面。 - Zathrus
哇...我为你感到非常非常的遗憾...因为我自己也不得不处理纯Win32 API代码,试图让自己哭成遗忘,至少,我看到情况可能会更糟... :-/ - paercebal
6个回答

19
  1. wParamlParam的含义在许多地方都发生了改变。我强烈建议您要非常谨慎,尽可能地转换使用message crackers。它们将为您节省无数的头痛。如果我只能给你一个建议,那就是这个。
  2. 只要您使用消息破解程序,还要启用STRICT。它将帮助您捕获使用int而不是HWNDHANDLE或其他东西的Win16代码库。转换这些将极大地有助于本列表中的第9点。
  3. hPrevInstance是无用的。确保不要使用它。
  4. 确保您正在使用与Unicode兼容的调用。这并不意味着您需要将所有内容转换为TCHAR,但意味着您最好用CreateFile替换OpenFile_lopen_lcreat等明显的函数。
  5. LibMain现在是DllMain,整个库格式和导出约定都不同。
  6. Win16没有VMM。应该用更现代的等价物替换GlobalAllocLocalAllocGlobalFreeLocalFree。完成后,清理对LocalLockLocalUnlock等函数的调用;它们现在是无用的。虽然我想象不出您的应用程序会这样做,但请确保您不依赖于WM_COMPACTING
  7. Win16也没有内存保护。确保您不使用SendMessagePostMessage向进程外的窗口发送指针。您需要切换到更现代的IPC机制,如管道或内存映射文件。
  8. Win16也缺少抢占式多任务处理。如果您想要从另一个窗口快速获得答案,则完全可以调用SendMessage并等待消息被处理。现在可能是个坏主意。请考虑是否PostMessage不是更好的选择。
  9. 指针和整数大小会发生变化。记得仔细检查任何您正在读写磁盘数据的地方,特别是如果它们是Win16结构体。您需要手动重新编写它们以处理较短的值。同样,处理这个问题最不痛苦的方法将是尽可能使用消息破解程序。否则,您需要手动查找和转换适用的intDWORD等。
  10. 最后,当您解决了明显的问题后,请考虑启用64位编译检查。从16位到32位的许多问题与从32位到64位的问题相同,而Visual C++现在实际上非常聪明。不仅可以捕获一些悬留问题,还可以为您的最终Win64迁移做好准备。

编辑: 正如@ChrisN指出的那样,将Win16应用程序移植到Win32的官方指南已经存档,且补充并扩展了我上面的观点。


6
除了正确设置您的构建环境外,以下是您需要解决的一些问题:
  1. 包含整数的结构体需要更改为short或从16位扩展到32位。如果您更改了结构的大小,并且它被加载/保存到磁盘中,则需要编写数据文件升级代码。

  2. 每个窗口数据通常与窗口句柄一起使用GWL_USERDATA存储。如果您将一些数据扩展到32位,偏移量将发生变化。

  3. 在Win32中,POINT和SIZE结构为64位。在Win16中,它们为32位,并且可以作为DWORD返回(调用方会将返回值拆分为两个16位值)。这在Win32中不再适用(即Win32不返回64位结果),并且函数已更改为接受指针以存储返回值。您需要编辑所有这些内容。 GetTextExtent等API受此影响。此问题也适用于某些Windows消息。

  4. 在Win32中,不鼓励使用INI文件,而应使用注册表。虽然INI文件功能仍然有效,但您需要小心处理Vista问题。 16位程序经常将其INI文件存储在Windows系统目录中。

这只是我能想起的一些问题。自从我进行Win32移植以来已经过去了十多年。一旦您开始,它就会非常快速。每个代码库在移植方面都有其自己的“感觉”,您将习惯于此。您可能还会在途中发现一些错误。


3

1

原始的 win32 SDK 有一个工具,可以扫描源代码并标记需要更改的行,但我不记得工具的名称。

在过去必须这样做时,我使用了一种暴力技术 - 即: 1- 更新 makefiles 或构建环境以使用 32 位编译器和链接器。选择性地,在 IDE 中创建一个新项目(我使用 Visual Studio),并手动添加文件。

2- 构建

3- 修复错误

4- 重复步骤2和3,直到完成

这个过程的痛苦取决于您正在迁移的应用程序。我曾经在一个小时内转换了一万行程序,并在不到一周的时间内转换了七万五千行程序。我也遇到一些小型实用程序,我放弃了并重新编写了它们(主要是)从头开始。


0

我同意Alan的看法,尝试和错误可能是最好的方法。

这里有一些不错的技巧


0

同意编译器可能会捕捉到大部分错误。此外,如果您正在使用“near”和“far”指针,则可以删除这些标识 - 在Win32中,指针只是指针。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接