The 16-bit versions of Windows (which contain, it must be said, some 32-bit code; they are known as being 16-bit because they are primarily 16-bit and directly support only 16-bit programs) run on top of the DOS operating system, and use its features for their own purposes. Windows 3.0 and 3.1 did use the enhanced features of the 386 internally (to implement virtual DOS machines and inside some Windows functions) however writing properly 32-bit programs was still well nigh impossible.
Microsoft invented two solutions to this problem. The first was something called Windows NT (New Technology?), designed primarily for networking. Because of its needs it was more powerful (with a 32-bit kernel) and more secure. NT does have the ability to run 16-bit Windows programs and DOS programs, although NT does restrict direct hardware access etc which can cause compatibility issues. Also, it used a different file system (the NTFS or "NT file system") than DOS.
[Interestingly enough, Windows NT has been developed for platforms other than IBM/Intel machines. The NT API has been standardized so that (theoretically) properly written NT applications can be compiled for any 32-bit machine that is running Windows NT.]
The second solution to the 32-bit dilemma was something called Win32s, which when run inside Windows 3.1 or later actually provided a 32-bit API almost the same as that which NT provides. This allowed Windows 3.1 to run 32-bit programs, and the difference between 16-bit and 32-bit programs is ultimately transparent to the user. Even some programs written for NT could potentially run in a Win32s environment.
The next step of Windows evolution occurred with the development of Windows '95. Win95 is something of a mix between Windows 3.x and Windows NT. It incorporates a new-look GUI (with basically the same functionality as the old one) and is now, Microsoft claims, an operating system in its own right. This has been disputed. Cetainly it is possible to use only the DOS-like portion of Windows '95, without loading the GUI or most of the Win95 kernel. [for those who don't believe this, try pressing F8 on the 'Starting Windows' message on bootup and selecting 'Command Prompt only'. Then, try and execute a Windows program - the resulting message usually states that 'This program requires Windows', which implies that Windows is not running.]
Essentially, Win95 looks very much like a 32-bit version of Windows which has been closely interwoven with what has become known as DOS v7.0. One important improvement was the support for long file names (as opposed to the maximum-of-11 character restriction imposed by the original DOS/Windows combination). The GUI appearance was also slightly modified (note also that newer versions of Windows NT have the same GUI as Win95).
[At about the same time Win95 was released, an OS for pocket-sized computers was released and named 'Windows CE'. It appears very different in nature from the other flavours of Windows. I'm not even sure of what processor(s) it runs on. Because of this, no further mention of Windows CE will be made. This SDK makes no effort to cover Windows CE programming.]
After Windows 95 we saw the release of Windows 98 (very similar to Win95, with a few minor enhancements and GUI changes - the two are essentially the same), and the planned release of Windows 2000. The newer 'year number' versions of Windows are likely to become more and more like Windows NT, as Microsoft tries to phase out the older DOS/Windows system. I have heard that Windows 98 supports NT device drivers, for instance.
Windows NT, on the other hand, maintains no such conventional memory structure, and very possily does not need to drop the processor back to real or V86 mode at all. NT still allows 'DOS boxes' to be created and DOS programs to be run (in V86 mode 'virtual machines') but these VMs are created from NTs own resources and are not copied from the conventional memory structure (as is the case with the other Windows flavours). Windows programs all run together in a single, protected mode 'Virtual Machine', however 32 bit programs are each assigned a seperate virtual address space whereas 16 bit programs share the same address space.
In either case, device drivers are needed to access devices on the machine. However, because of the fundamental differences of operation between NT and Win 3.x/9x (henceforth referred to as 'WinDos'), the device drivers for the two types operate very differently. WinDos also allows the creation of 'VxDs' (Virtual device drivers) which are used to resolve conflicts in device usage by 'virtualising' access to the device. VxDs can also be used for other purposes, because of the high privelege level at which they run (ring 0). They use a special interface to make requests to Windows, not relying on the usual function call methods (The '95 interface is compatible with the 3.x interface, but has been enhanced for increased functionality). NT does not support VxDs, instead supporting 'Kernel Mode Drivers'. Windows 3.x only allows loading VxDs when it starts up.
Both NT and WinDos support DLLs. 'DLLs' (Dynamic Link Libraries) are special programs designed to be shared between multiple applications, to avoid duplication of similar code, and also to prevent device conflict (the WinSock.DLL is a good example). DLLs can be partially integrated into applications so that the application will not run if the DLL is not available, or they can be explicitly loaded by an application at run time.
WinDos drivers for common devices such as the display and printer are in the form of special DLLs with special functions. These drivers are loaded when WinDos starts up. WinDos can call on such a driver to perform any task it requires (such calls will usually be initiated by an application calling the WinDos kernel). Note that Windows '95, which supports 32-bit programs, runs 16-bit printer drivers and very possibly other devices must also be 16-bit.
The most notable component of Windows not yet mentioned is the 'registry'. The registry, which has a tree like structure, contains information about the machine on which it resides including user options and functional details. The registry can also be used by applications to store their own data. Another method of doing this is to use .INI (initialization) files, and indeed some system level information is often stored in .INI files as well as or instead of in the registry. The 'WIN.INI' and 'SYSTEM.INI' files contain such information. Generally, the registry is the preferred storage system.
The low level element of the user interface is the window. A window is a rectangular area of the screen which can be given a certain appearance. The screen itself is covered with the 'desktop window', which may appear as a bitmap set by the user to be the background. Windows are used to provide visual information to the user, and to provide a channel for user input (from the mouse and keyboard) to be passed to a program.
In Windows 95+ and Windows NT 4.0+, there is also generally a 'taskbar' which has a 'start' button, and contains icons for the main open windows so that the user can easily switch between one and the other. The taskbar may also contain small icons which allow the user to access certain programs or settings, for instance a volume control. The taskbar is, it should be noted, part of the shell. If the shell is replaced, the taskbar will not be present unless it is implemented by the replacement shell.
Other 'main' windows are called 'top level' windows. These usually act as the main windows of applications, and do not have a parent window or owner. Top level windows are always overlapped windows, and may sometimes (also) be pop-up windows. (Overlapped windows have a title bar and border; pop-up windows are a special type of overlapped window which does not necessarily have a title, they are generally used for temporary information display such as dialog boxes and menus).
There are two kinds of direct hierarchial relationship a window can have with another window (not including none at all) - these are parentship (one window is the parent of the other) and ownership (one window owns another). The differences are that child windows are contained within the area of their parent when displayed (owned windows are not contained within the area of their owners), they move with the parent, and child windows cannot be pop-up windows. Child windows are used for various purposes, including sub-dividing the main window area, and acting as controls such as push buttons and scroll bars (note, child windows may themselves have children, and owned windows may themselves be owners).
Window 'z-order' refers to the location of a window in terms of the virtual 3rd screen dimension. A window at the top of the z-order appears 'on top' of all windows lower than it in the z-order. However, there are important points to be made:
Within each generation of windows, one window may have 'the focus'. This means that it recieves all input from the user. For a particular child window to have the focus, it's parent must also have the focus (so, when the parent loses the focus, it's child which currently has the focus also loses the focus. If this occurs, and the parent regains the focus, the child which was focused originally also regains the focus).
Windows are then created, using the window classes registered. They may then be moved, resized, hidden, mad visible, etc. The way in which this is done depends, of course, on the nature of the program. Whenever the user takes action on a window (with the mouse or keyboard), the window is "sent a message" to let it know what has happened (see below).
Once this is done, the interface is set up; the program then begins what is known as the 'message loop'. Messages are pulled off the 'message queue' using appropriate API function(s), possibly translated by other functions (to turn otherwise obscure events into useful ones: for instance, the 'Key down' event followed by a 'Key up' event can be translated into a 'Key pressed' event, which is generally easier to process), and then dispatched to the appropriate window procedure which takes the appropriate action.
Window messages are processed by the window procedure. The procedure is passed the various values which make up the message, which it then 'cracks' to determine the subject and nature of the message, and then takes the appropriate action (depending on what the program is designed to do). The API provides various functions to perform the 'default behaviour' for certain types of message.