Retrofitting the WM_COPY­DATA message onto Windows 3.1

The Old New Thing (Raymond Chen) News

Summary

This article explains how the WM_COPYDATA message, introduced for 32-bit Windows, was retrofitted onto 16-bit Windows 3.1 by taking advantage of the shared address space, requiring no changes for inter-16-bit communication.

<p>Some time ago, I talked about <a title="I can use WM_COPYDATA to send a block of data to another window, but how does it send data back?" href="https://devblogs.microsoft.com/oldnewthing/20251114-00/?p=111792"> how to return results back from the <code>WM_<wbr />COPY­DATA</code> message</a>. Which reminded me of a clever bit of history.</p> <p>The <code>WM_<wbr />COPY­DATA</code> message was introduced in 32-bit Windows. There was no need for it in 16-bit Windows because all 16-bit programs ran in the same address space. A far pointer in one process was good in any process. You could put it in the <code>lParam</code> of a window message and send it to any other window, same process or different process, doesn&#8217;t matter. But 32-bit programs ran in separate address spaces, so this trick didn&#8217;t work. Hence the need for <code>WM_<wbr />COPY­DATA</code> to pass data not only between 32-bit programs, but also between 32-bit programs and 16-bit programs.</p> <p>How did this message get retrofitted into 16-bit Windows so that Win32s could support it?</p> <p>Easy: It was already implemented, unwittingly.</p> <p>If the source and destination windows are both 16-bit windows, then the pointer to the <code>COPY­DATA­STRUCT</code> is already valid in both processes, as is the pointer inside the <code>COPY­DATA­STRUCT</code>. And the window handle in the <code>wParam</code> is also the same for both processes. Therefore, doing absolutely nothing with the <code>wParam</code> and <code>lParam</code> and simply allowing it to pass from a 16-bit program to another 16-bit program will still behave as expected.</p> <p>And it so happens that Windows 3.1 already did that: Windows 3.1 always passed the <code>wParam</code> and <code>lParam</code> unmodified, even when the message sender and receiver are in different processes, because all programs shared the same address space.</p> <p>It was just a sneaky trick to design the <code>WM_<wbr />COPY­DATA</code> message in such a way that the null marshaler is the correct behavior when it is sent between 16-bit programs.</p> <p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260616-00/?p=112430">Retrofitting the &lt;CODE&gt;WM_&lt;WBR&gt;COPY&shy;DATA&lt;/CODE&gt; message onto Windows 3.1</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
Original Article
View Cached Full Text

Cached at: 06/17/26, 12:54 PM

# Retrofitting the WM_COPY­DATA message onto Windows 3.1 - The Old New Thing Source: [https://devblogs.microsoft.com/oldnewthing/20260616-00?p=112430](https://devblogs.microsoft.com/oldnewthing/20260616-00?p=112430) Some time ago, I talked about[how to return results back from the`WM\_COPY­DATA`message](https://devblogs.microsoft.com/oldnewthing/20251114-00/?p=111792)\. Which reminded me of a clever bit of history\. The`WM\_COPY­DATA`message was introduced in 32\-bit Windows\. There was no need for it in 16\-bit Windows because all 16\-bit programs ran in the same address space\. A far pointer in one process was good in any process\. You could put it in the`lParam`of a window message and send it to any other window, same process or different process, doesn’t matter\. But 32\-bit programs ran in separate address spaces, so this trick didn’t work\. Hence the need for`WM\_COPY­DATA`to pass data not only between 32\-bit programs, but also between 32\-bit programs and 16\-bit programs\. How did this message get retrofitted into 16\-bit Windows so that Win32s could support it? Easy: It was already implemented, unwittingly\. If the source and destination windows are both 16\-bit windows, then the pointer to the`COPY­DATA­STRUCT`is already valid in both processes, as is the pointer inside the`COPY­DATA­STRUCT`\. And the window handle in the`wParam`is also the same for both processes\. Therefore, doing absolutely nothing with the`wParam`and`lParam`and simply allowing it to pass from a 16\-bit program to another 16\-bit program will still behave as expected\. And it so happens that Windows 3\.1 already did that: Windows 3\.1 always passed the`wParam`and`lParam`unmodified, even when the message sender and receiver are in different processes, because all programs shared the same address space\. It was just a sneaky trick to design the`WM\_COPY­DATA`message in such a way that the null marshaler is the correct behavior when it is sent between 16\-bit programs\. ### Category ### Topics ## Author ![Raymond Chen](https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2019/02/RaymondChen_5in-150x150.jpg) Raymond has been involved in the evolution of Windows for more than 30 years\. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie\-jeebies\. The Web site spawned a book, coincidentally also titled The Old New Thing \(Addison Wesley 2007\)\. He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information\.

Similar Articles

A compatibility note on the abuse of Windows window class extra bytes

The Old New Thing (Raymond Chen)

Raymond Chen discusses a historical Windows compatibility issue where some 16-bit programs abused window class extra bytes to store private data, and how Microsoft blocked the loophole for 32-bit and 64-bit programs while maintaining backward compatibility.

The evolution of window and class extra bytes in Windows

The Old New Thing (Raymond Chen)

The article traces the evolution of window and class extra bytes in Windows from 16-bit to 32-bit to 64-bit, detailing changes in function names and data sizes as handles and pointers expanded.

Visual Basic on the PC w/Windows 3.1

Lobsters Hottest

A retrospective on the rise and fall of Visual Basic on Windows 3.1, exploring Bill Gates' ambition and Microsoft's dominance in the personal computing landscape.

Advantages and disadvantages of Windows NT 3.1

Lobsters Hottest

A retrospective on Windows NT 3.1, Microsoft's first fully 32-bit operating system, discussing its advantages (stability, security, portability, NTFS) and disadvantages (high hardware demands, limited software support).

How can I perform a Copy­File in unbuffered mode?

The Old New Thing (Raymond Chen)

Explains how to use the COPY_FILE_NO_BUFFERING flag with CopyFileEx and CopyFile2 to copy files using unbuffered handles, and why the progress callback cannot be used to change buffering after the handles are opened.