A Programmer's Introduction to Windows

It’s good for programmers, even application programmers, to know what kind of services their operating system provides. Windows is a popular O.S., so let’s take a look.

Introduction

Developers and system architects really should have an understanding of their operating system and how their applications interact with the operating system. This document provides a basic overview of the Windows family of operating systems for application programmers.

Some of the members of this family include:

Pseudo-Operating Systems (DOS add-ons) Classic Operating Systems Real-Time Operating Systems
  • Windows 1.0 (1985-11)
  • Windows 2.0 (1987-12)
  • Windows 3.0 (1990-05)
  • Windows 3.1 (1992-08)
  • Windows 95 (1995-08)
  • Windows 98 (1998-06)
  • Windows ME (2000-06)
  • Windows NT 3.1 (1993-08)
  • Windows NT 3.5 (1994-09)
  • Windows NT 3.51 (1995-06)
  • Windows NT 4.0 (1996-07)
  • Windows 2000 (2000-02)
  • Windows XP (2001-10)
  • Windows Server 2003 (2003-04)
  • Windows XP x64 (2005-04)
  • Windows Vista (2006-07?)
  • Windows Server 2007 (2007?)
  • Windows CE 1.0 (1996-11)
  • Windows CE 2.0 (1997-11)
  • Windows CE 2.1 (1998-07)
  • Windows CE 3.0 (1999)

For a more complete overview see Wikipedia's Microsoft Windows article and Wikipedia's list of Microsoft Windows versions.

This page covers only the classic operating systems.

The Role of the Operating System

The most visible components of a computer are

Software, or code, has to be in memory to run. Once in memory, software is indistinguishable for other kinds of data, such as numbers or text. To execute some code in memory, you somehow place the address of the code into a processor's instruction pointer register (EIP on an x86) while the processor is running.

Most software is packaged as functions. A function is a piece of code that, after executing, jumps to the instruction following the one from which it was called (though some functions never return). Here is a function for the x86 processor that takes (from the stack) a single 32-bit integer argument — let's call it n — and returns through EAX the value 3n+1 if n is even and 4n-3 if it is odd.

8b 4c 24 04 8b c1 99 33 c2 2b c2 83 e0 01 33 c2 2b
c2 8d 44 49 01 74 07 8d 04 8d fd ff ff ff c3

(The above function uses the C calling convention. If the standard calling convention were used replace the final byte, c3, with the three-byte sequence c2 04 00.)

When you power up your computer, your processor receives a start signal; this makes it load its internal registers with specific power-on values. The instruction pointer is one of these initialized registers. Your computer's manufacturer has installed read-only memory to cover this address, and placed some startup code in this memory. The startup code eventually causes part of an operating system to be loaded into memory and executed.

The operating system is responsible for many things; some of its primary responsibilities are:

The operating system contains code to carry out tasks in these areas. There are functions to create and terminate processes, request the current time, delete and rename files, lock and unlock blocks of memory, and so on. When you write a program, most of the operating system functions are available to you. The set of functions you can call, along with their signatures, calling conventions, and associated datatypes, for most versions of the Windows family of operating systems is called the Windows API. There are thousands of functions in the Windows API. Here are the names of a very small number of them:

    CreateProcess        CreateFile           ShowWindow
    ExitProcess          OpenFile             SetSystemTime
    CreateThread         ReadFile             SetScrollRange
    GetMessage           WriteFile            RegSetValueEx
    CreateMutex          CloseFile            ResetPrinter
    WaitForSingleObject  CompareFileTime      ResumeThread
    CreatePen            GetTickCount         Rectangle
    SetCapture           CreateBrushIndirect  Ellipse
    ZeroMemory           CreateDialog         PaintDesktop
    FillMemory           SetWindowPos         ClearEventLog

A First Windows Program

Suppose you wanted to write a program to display "Hello, World" in a console window. (You knew that was what we were going to do, right?) Under Windows, most software resides in files with extensions .EXE and .DLL, though often you will see ActiveX controls packaged in .OCX files. Therefore our task is to create a file called HELLO.EXE which contains our program. After we do this we can tell the operating system to "run" HELLO.EXE. When the operating system "runs" a program, it creates a process, loads the code and data from HELLO.EXE, does some messing around with the loaded code like fixing up addresses, and creates a thread to start executing the code at the program's entry point, which is encoded in the .EXE file. Okay let's see the program:

4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00
0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f
74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00
50 45 00 00 4c 01 04 00 d5 64 85 35 00 00 00 00 00 00 00 00 e0 00 0f 01 0b 01 05 00 00 02 00 00
00 06 00 00 00 00 00 00 00 10 00 00 00 10 00 00 00 20 00 00 00 00 40 00 00 10 00 00 00 02 00 00
04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 00 50 00 00 00 04 00 00 00 00 00 00 03 00 00 00
00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
00 30 00 00 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 38 30 00 00 10 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2e 74 65 78 74 00 00 00
30 00 00 00 00 10 00 00 00 02 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 60
2e 64 61 74 61 00 00 00 15 00 00 00 00 20 00 00 00 02 00 00 00 06 00 00 00 00 00 00 00 00 00 00
00 00 00 00 40 00 00 c0 2e 69 64 61 74 61 00 00 84 00 00 00 00 30 00 00 00 02 00 00 00 08 00 00
00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 c0 53 54 41 43 4b 00 00 00 80 00 00 00 00 40 00 00
00 02 00 00 00 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 c0 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
6a f5 ff 15 40 30 40 00 a3 0d 20 40 00 6a 00 b8 11 20 40 00 50 6a 0d 68 00 20 40 00 ff 35 0d 20
40 00 ff 15 3c 30 40 00 6a 00 ff 15 38 30 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
28 30 00 00 00 00 00 00 00 00 00 00 76 30 00 00 38 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 58 30 00 00 66 30 00 00 48 30 00 00 00 00 00 00 58 30 00 00 66 30 00 00
48 30 00 00 00 00 00 00 2a 01 47 65 74 53 74 64 48 61 6e 64 6c 65 00 00 6b 00 45 78 69 74 50 72
6f 63 65 73 73 00 70 02 57 72 69 74 65 43 6f 6e 73 6f 6c 65 41 00 4b 45 52 4e 45 4c 33 32 2e 64
6c 6c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

No programmer worth minimum wage would want to produce this file with a binary editor. Fortunately there are tools to produce .EXE files from higher level language source code; here's the assembly language program from which it was made:

; ----------------------------------------------------------------------------
; hello.asm
;
; This is a Windows console program that writes "Hello, World" on one line
; and then exits.
;
; Assemble like this:
;
;   ml hello.asm /c
;
; Link with the Win32 kernel and specify your entry point like this:
;
;   link hello kernel32.lib /subsystem:console /entry:go
; ----------------------------------------------------------------------------

        .386P
        .model  flat
        extern  __imp__ExitProcess@4:near
        extern  __imp__GetStdHandle@4:near
        extern  __imp__WriteConsoleA@20:near
        public  _go

        .stack 128

        .data
msg     byte    'Hello, World', 0ah
handle  dword   ?
written dword   ?

        .code
_go:    push    -11
        call    dword ptr __imp__GetStdHandle@4
        mov     handle, eax

        push    0
        lea     eax, written
        push    eax
        push    13
        push    offset msg
        push    handle
        call    dword ptr __imp__WriteConsoleA@20

        push    0
        call    dword ptr __imp__ExitProcess@4

        end

(You'll notice our program makes calls to three "external functions." with funny looking names. It turns out that these functions are defined in Kernel32.lib, and they really just call functions with more realistic names in Kernel32.dll, but they do all the messy work of calling GetProcAddress for you. For instance, The function __imp__GetStdHandle@4 in Kernel32.lib calls the function GetStdHandle in Kernel32.dll.) First the source code in hello.asm is assembled into hello.obj and this is statically linked to Kernel32.lib, producing hello.exe. Since the system creates a process object when it launches your program, you should finish your program with a call to ExitProcess.

Programmers who prefer C to assembly language could write:

/*********************************************************************************
*  hello.c
*
*  This is a Windows program that writes "Hello, World" on one line on the
*  console and then exits.
*
*  Compile like this:
*
*    cl hello.c /c
*
*  and link with the C runtime library:
*
*    link hello.obj libc.lib /subsystem:console /entry:mainCRTStartup
*
*********************************************************************************/

#include <windows.h>
#include <wincon.h>

int main() {
    int x;
    HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    WriteConsole(h, "Hello, World\n", 13, &x, 0);
}

The function mainCRTStartup in libc.lib calls main then ExitProcess, so there is no need to explicitly call ExitProcess from your C code. There are other useful entry point functions in the C Runtime Library you can use in your programs. For example, WinMainCRTStartup calls WinMain then ExitProcess.

Windows Objects

Many of the API functions create objects of some sort, which you then manipulate and destroy with other API functions. For example you could create a window, move it, resize it and destroy it. Generally the function that creates the object returns a handle to it, which you pass to the other functions that use this object. There are really two kinds of objects: kernel objects and non-kernel objects. Non kernel objects are usually grouped into user objects and GDI objects.

Programming with the Windows API

Windows programming can be learned by reading books, doing online tutorials, or reading the development guides published by Microsoft. Selected highlights of the Microsoft documentation are:

A decent online tutorial is theForger's Win32 API Tutorial.

Here are a couple of examples I wrote myself:

An Example with a Message Box

Here's a cute one-liner.

hello.c
#include <windows.h>

int main() {
    while (MessageBox(NULL, "Wanna quit?", "Hi", MB_YESNO) != IDYES);
}

Compile and run like this:

C:\lmu\web\code\Win32>gcc hello.c C:\lmu\web\code\Win32>a

hellowin32.png

A Graphics Example with a Main Window

Here is an Windows API example application that uses windows, graphics, and messages. Programming entire applications with the API only is a nasty undertaking, but

yellowellipse.c
/*****************************************************************************
*
*  yellowellipse.c
*
*  This is a plain Win32 program, written in C, whose main window displays
*  a big yellow ellipse in the center, and responds to a left button click
*  by changing the window title.  The arrow keys grow and shrink the ellipse.
*  Its sole purpose is to demonstrate how many lines of source code are
*  required to generate a simple program.
*
*****************************************************************************/

#include <windows.h>

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
LRESULT APIENTRY WindowProcedure(HWND, UINT, WPARAM, LPARAM);

// ---------------------------------------------------------------------------
// Win32 programs begin at WinMain.  This function is passed four parameters
// from the operating system, which you are free to use or ignore.
// ---------------------------------------------------------------------------

int WINAPI WinMain(
    HINSTANCE currentInstance,             // handle of current instance
    HINSTANCE previousInstance,            // handle of previous instance
    LPSTR commandLine,                     // command line string (ANSI)
    int showState) {                       // show state of main window

    // C programs require all object declarations to come before code

    char* className = "Hello";
    WNDCLASS thisClass;
    HWND mainWindow;
    MSG message;

    // 1. Register a class for the main window.  This involves telling the
    // operating system that you are making a new type of window and giving
    // this new type (class) a name and lots of other properties.

    thisClass.style = CS_HREDRAW | CS_VREDRAW;
    thisClass.lpfnWndProc = WindowProcedure;
    thisClass.cbClsExtra = 0;
    thisClass.cbWndExtra = 0;
    thisClass.hInstance = currentInstance;
    thisClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    thisClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    thisClass.hbrBackground = GetStockObject(WHITE_BRUSH);
    thisClass.lpszMenuName = NULL;
    thisClass.lpszClassName = className;
    RegisterClass(&thisClass);

    // 2. Create the main window (of the class you just registered),
    // show it, and paint it for the first time.

    mainWindow = CreateWindow(
        className,                         // window class name
        "Hello, World",                    // window caption
        WS_OVERLAPPEDWINDOW,               // window style
        CW_USEDEFAULT,                     // initial x position
        CW_USEDEFAULT,                     // initial y position
        CW_USEDEFAULT,                     // initial x size
        CW_USEDEFAULT,                     // initial y size
        NULL,                              // handle of parent window
        NULL,                              // handle of the menu
        currentInstance,                   // program instance handle
        NULL);                             // creation parameters
    ShowWindow(mainWindow, showState);
    UpdateWindow(mainWindow);

    // 3. Enter the message loop for the main window.  Windows will fill a
    // message queue for each thread; we have to read from the queue and tell
    // the O.S. to call our window procedure with the message.  The function
    // GetMessage() returns 0 if the message is WM_QUIT, or a negative value
    // on error.  We return from WinMain the wParam in the WM_QUIT message,
    // or, in the case of GetMessage failing, complete garbage.

    while (GetMessage(&message, NULL, 0, 0) > 0) {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }
    return message.wParam;
}

// ---------------------------------------------------------------------------
// Win32 programs need a main window procedure.  This is the function that
// you specified in the lpfnWndProc field of the class you registered.
// ---------------------------------------------------------------------------

LRESULT APIENTRY WindowProcedure(
    HWND hwnd,                             // handle of window
    UINT messageID,                        // message identifier
    WPARAM wParam,                         // first message parameter
    LPARAM lParam) {                       // second message parameter

    // Declare some local variables for your window procedure.  If they need
    // to exists across calls, they need to be made static.

    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;
    HBRUSH hBrush;
    HPEN hPen;
    LPCSTR prompt = "Try the mouse buttons and arrow keys";
    static int hPad = 10, vPad = 10;

    // Include handlers for all the messages you are interested in.  Return 0
    // from the procedure if you handle a message.

    switch (messageID) {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
            hBrush = SelectObject(hdc, CreateSolidBrush(RGB(255, 255, 0)));
            hPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, RGB(0, 0, 0)));
            GetClientRect(hwnd, &rect);
            Ellipse(hdc, rect.left+hPad, rect.top+vPad,
                rect.right-hPad, rect.bottom-vPad);
            SetBkMode(hdc, TRANSPARENT);
            DrawText(hdc, prompt, strlen(prompt), &rect,
                DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            EndPaint(hwnd, &ps);
            DeleteObject(SelectObject(hdc, hBrush));
            DeleteObject(SelectObject(hdc, hPen));
            return 0;

        case WM_LBUTTONDOWN:
            SetWindowText(hwnd, "You pressed the left button");
            return 0;

        case WM_KEYDOWN:
            if (wParam == VK_LEFT) hPad -= 2;
            else if (wParam == VK_RIGHT) hPad += 2;
            else if (wParam == VK_UP) vPad += 2;
            else if (wParam == VK_DOWN) vPad -= 2;
            InvalidateRect(hwnd, NULL, TRUE);
            UpdateWindow(hwnd);
            return 0;

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }

    // If there are any messages you do not handle yourself, pass them back
    // to Windows for handling.

    return DefWindowProc(hwnd, messageID, wParam, lParam);
}

Compile and run like this:

C:\lmu\web\code\Win32>gcc yellowellipse.c -lgdi32 C:\lmu\web\code\Win32>a

yellowellipse.png

Playing Sound Files

In case you want to play a file by invoking a command line program:

play.c
// ---------------------------------------------------------------------------
// play.c
//
// Win32 program to play a wave file.  Link it with the Windows winmm library.
//
// With Visual C++
//   cl play.c winmm.lib
//
// With GCC
//   gcc play.c -lwinmm
//
// This program could easily be made better by taking in a second command
// line argument which would map to one of the many possible arguments
// allowed to PlaySound().
// ---------------------------------------------------------------------------

#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>

int main(int argc, char** argv) {
    if (argc < 2) {
        printf("Need command line argument specifying the wave file\n");
    } else {
        PlaySound(argv[1], 0, SND_FILENAME);
    }
}

Try it:

C:\lmu\web\code\Win32>gcc play.c -lwinmm C:\lmu\web\code\Win32>a \windows\media\ringin.wav

More Examples?

Nope. That's it for my stuff. Now continue with some online tutorials. I suggest theForger's Win32 API Tutorial.