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 |
---|---|---|
|
|
|
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 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
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.
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.
Process File Mapping Event Thread Heap Timer Module Pipe Communications Device File Mailslot Update Resource Change Notification Mutex Event Log Find file Semaphore
Window Accelerator Table Hook Window Position Icon Desktop Window Station Cursor DDE Conversation Menu Caret
Pen Region DC Brush Font Memory DC Palette Metafile Metafile DC Bitmap Enhanced Metafile Enhanced Metafile DC
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:
Here's a cute one-liner.
#include <windows.h> int main() { while (MessageBox(NULL, "Wanna quit?", "Hi", MB_YESNO) != IDYES); }
Compile and run like this:
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 * * 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:
In case you want to play a file by invoking a command line program:
// --------------------------------------------------------------------------- // 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:
Nope. That's it for my stuff. Now continue with some online tutorials. I suggest theForger's Win32 API Tutorial.