The way I view this, there are three separate things: processes, applications, and windows. In all versions of Windows, a single process/application, that the user launched exactly once, was able to have one main window and multiple other windows that could be independently manipulated, closed etc. Since Alt+F4 was added as a keyboard shortcut, it closed the currently active window, which might happen to be a confirmation dialog or anything else. If it was used to close the main window, the application/process might choose to shut down, automatically closing other windows it owned, but this was never a requirement.
Now, for the process / application distinction. By my understanding, in traditional Windows, the concept of an application is essentially an executable whose main function is WinMain. A user can spawn one or more processes from the same application executable, and these are handled differently in 16-bit vs 32-bit Windows - but they have always existed as separate copies, within the technical limitations of the time. Even in Windows 1.0, the second execution of WinMain did indeed receive a hPrevInstance and could use it to access resources of the already running instance - but it was still a separate thing, with its own window and its own event loop. Ultimately it wasn't all that different from a new process spawned from the same executable - except that memory and compute constraints at the time made it important to have a way to share certain parts of the parent (and the lack of memory isolation made it trivial to access the memory of any other thing running on the system anyway).
The concept that an application can only have 0 or 1 instances running is a very weird concept that MacOS shares only with mobile OSs and Windows Metro/Universal/UWP/whatever MS calls their mobile-style store apps today.
Edit to add a note: it's actually quite common on Windows today for programs to not actually launch, or at least not use, a second process when running the executable again. What they do instead is that during startup they check if the process is already running by checking some named mutex or other similar mechanism, and if it is, they ask that process to open a new top-level window, maybe with the new document loaded into it if you were actually opening a doc, and then the new process just exits, while the old process start a new window that for all intents and purposes looks just like a new copy of the process to the user.