The Evolution of API

It is my premise that, despite its monopolistic practices, Microsoft has succeeded by winning the minds of software developers. The Windows API, OLE/COM, the Win32 API, the distributed systems architecture, ODBC, .NET – these are all examples of API provided by Microsoft that have had tremendous impact on the industry. Even as developers decry their dependence on a single vendor, even as they install Eclipse and study Ruby, they can’t deny that it’s simply easier to run Visual Studio and program in C#/.NET.

There are chinks in Microsoft armor. PHP is pretty hard to beat for simple web apps. Microsoft’s share of the mobile device business is pretty small, too, regardless of how cool the Compact Edition of .NET might be. Overall, however, I can think of no other company or technology that has as much influence over developers as Microsoft.

To more clearly demonstrate how Microsoft achieved this hegemony, I thought it might be interesting to review the history of a particular API call and to note Microsoft’s involvement with it. Any programmer that’s read Kernighan and Ritchie’s The C Programming Language, is familiar with the “Hello World” program. (Any programmer that hasn’t read this book should be ashamed of his/herself. This would be akin to an English Lit major not having read any Shakespeare.) Let’s consider how the implementation of “Hello World” (on a PC) has changed over the years.

In 1981, when the first PC became available, the BIOS provided one way of implementing the program:

.data
    Message DB "Hello World"
.ends
.code
    MOV AX,1300h       ; set function code for "Write string", don't move cursor
    XOR  BX,BX         ; write to page 0 with no character attribute
    MOV CX, 11         ; write 11 characters
    PUSH DS
    POP ES
    LEA BP, Message    ; set ES:BP to the address of the message
    INT 10h            ; do it!
.ends

If you didn’t care about screen location or video attributes, MSDOS provided a simpler way:

.data
    Message DB "Hello World"
.ends
.code
    MOV AH,9           ; set function code for "write string at cursor"
    LEA DX, Message    ; set DS:DX to the address of the message (DS is already set)
    INT 21h            ; do it!
.ends

In the early 80’s when high-level languages (other than BASIC) started arriving on the PC, you could do it like K&R:

    int main()
    {
        printf("Hello World");
    }

The arrival of Microsoft Windows in 1985 made life much more complicated. Displaying a label on a dialog box was pretty simple (you could just place it there in the dialog box editor). If you wanted to display text in your application’s client window, that meant you had to write a window procedure and process the WM_PAINT message. Processing this message typically meant deciding on a font to use, figuring out colors to use and dealing with opacity:

    void HandlePaint(HWND hwnd)
    {
        /* Get device context for window */
        HDC hdc = GetDC(hwnd);

        /* Create a font and select it, keeping the old one around */
        HFONT hf = CreateFont(...lots of args...);
        HFONT hfOld = SelectObject(hdc, hf);

        /* Get the client rectangle for the whole window */
        RECT rect;
        GetClientRect(hwnd, &rect);

        /* Draw the text at the top left of the window */
        rect.left = rect.top = 10;
        DrawText(hdc, "Hello World", 11, &rect, DT_SINGLELINE);

        /* Select the old font */
        SelectObject(hdc, hfOld);

        /* delete created resources */
        DeleteObject(hf);
    }

No wonder so many programmers had a hard time moving to Windows! And yet move they did! What were the alternatives? VisiOn was cool but it was a pig. TopView was character-mode only. OS/2 Presentation Manager was Windows run through the IBM bureaucracy filter (e.g. put Win in front of all the API and flip the Y axis top to bottom!). The Mac was equally complicated and less capable (no multitasking, no child windows).

The arrival of 32-bit programming didn’t affect “Hello World” all that much, but it did accomplish two things. First, it freed programmers from having to worry about segmentation (putting code into 64K groups that could be efficiently swapped in and out). Second, it performed better process cleanup meaning that users had to worry less about depleting system resources (as could happen, for example, if you forgot to call DeleteObject in Win16).

OLE/COM affected “Hello World” to the extent that you could now write a “Hello world” application that could be embedded in another one, saved to a single file and printed in composite form. Your code had to worry about garbage collection (maintaining proper reference counts) and implementing appropriate COM interfaces. I’ll not cover this here as I still have scars from those days. Alternatives? None. Corba was still working on PL/1 and Ada support when OLE/COM first shipped. Microsoft was willing to punt on this problem in exchange for 99% market share.

As the final installment, let’s consider “Hello World” in the .NET era. First of all, Winforms programs are very often forms-oriented these days; you might very well choose to implement the program by simply creating a form and dragging a label there in Visual Studio. A Webforms program would do it the same way. If you do need to write a Winforms program that fully handles its client area, you’d write an event handler for a form’s Paint event:

    void Paint(object sender, PaintEventArgs e)
    {
        // get the Graphics object from the event arguments
        Graphics g = e.Graphics;

        // draw our string
        g.DrawString("Hello World", new Font("Arial", 10),
                         Brushes.Black, new Point(10, 10));
    }

If you compare this to the previous version, you can see a lot of similaries. The Graphics object is the equivant of the Windows device context. You still have to create a font. The difference is that C#/.NET has some “syntactic sugar” that makes life easier, for example, simplified arguments when creating fonts and the ability to create objects in-line. Additionally, C#/.NET perform automatic garbage collection so you don’t have to worry about deleting any created objects.

“Hello World” is an extremely simple example that demonstrates how APIs have changed over the course of 27 years. I chose it because, even this simple example, demonstrates how Microsoft has affected developers lives (both positively and negatively). There are better examples (OLE/COM and ODBC/ADO/LinQ) that demonstrate Microsoft’s contributions to the industry but none that can be so easily summarized in an already too long blog!