Microwindows API

Message-passing architecture

The fundamental communications mechanism in the Microwindows Win32 API is the message. A message consists of a well-known message number, and two parameters, known as wParam and lParam. Messages are stored in an application's message-queue, and retrieved via the GetMessage function. The application blocks while waiting for a message. There are messages that correspond to hardware events, like WM_CHAR for keyboard input or WM_LBUTTONDOWN for mouse button down. In addtiion, events signaling window creation and destruction WM_CREATE and WM_DESTROY are sent. In most cases, a message is associated with a window, identified as an HWND. After retrieving the message, the application sends the message to the associated window's handling procedure using DispatchMessage. When a window class is created, it's associated message handling procedure is specified, so the system knows where to send the message.

The message-passing architecture allows the core API to manage many system functions by sending messages on all sorts of events, like window creation, painting needed, moving, etc. By default, the associated window handling function gets a "first pass" at the message, and then calls the DefWindowProc function, which handles default actions for all the messages. In this way, all windows can behave the same way when dragged, etc, unless specifically overridden by the user. Major window management policies can be redefined by merely re-implementing DefWindowProc, rather than making changes throughout the system.

The following functions deal with messages directly:

Table 1-1. Microwindows Messaging Functions - defined in winuser.h

Function

Description

SendMessage

Send a message directly to a window.

PostMessage

Queue a message on the application's message queue for later dispatch.

PostQuitMessage

Queue a WM_QUIT message telling the application to terminate when read.

GetMessage

Block until a message is queued for this application.

TranslateMessage

Translate up/down keystrokes to WM_CHAR messages.

DispatchMessage

Send a messages to it's associated window procedure.

A Microwindows application's entry point is the function WinMain, rather than main.

Window creation and destruction

The basic unit of screen organization in Microwindows API is the window. Windows describe an area of the screen to draw onto, as well as an associate "window procedure" for handling messages destined for this window. Applications programmers can create windows from pre-defined classes, like buttons, edit boxes, and the like, or define their own window classes. In both cases, the method of creating and communicating with the windows remains exactly the same. The following functions deal with window registration, creation, and destruction:

Table 1-2. Microwindows Window Registration, Creation & Destruction Functions - defined in winuser.h

Function

Description

RegisterClass

Define a new window class name and associated window procedure.

UnRegisterClass

Undefine a window class.

CreateWindowEx

Create an instance of a window of a certain class.

DestroyWindow

Destroy a window instance.

GetWindowLong

Return information about a window.

SetWindowLong

Set information about a window.

GetWindowWord

Return user information about a window.

SetWindowWord

Set user information about a window.

GetClassLong

Return information about a window class.

GetWindowText

Get a window's title or text.

SetWindowText

Set a window's title or text.

The WM_CREATE message is just after window creation, before returning from CreateWindowEx. The WM_DESTROY message is sent just before destroying a window with DestroyWindow.

When a window is registered, extra bytes can be allocated to the window structure when created. The GetWindowLong, GetWindowWord, SetWindowLong and SetWindowWord manipulate these bytes. In addition, a fixed number of extra bytes per window class can be allocated on registration and retrieved via the GetClassLong function.

Window showing, hiding and moving

The ShowWindow function allows windows to be made visible or hidden. In addition, this can be specified during the creation of the window, through CreateWindowEx. MoveWindow is called to change a window's position or size. A WM_MOVE message is sent if the window's position changes, and WM_SIZE is sent on size changes.

Window painting

The Microwindows system determines when a window needs to be initially painted or repainted as the result of other window movement, and a WM_PAINT message is sent to the associated window procedure. At this point, it's up the the application to use the graphics primitives available to paint the window, described below. Microwindows keeps track of a windows' "update" region, and sends WM_PAINT whenever the region is non-empty. For speed reasons, the WM_PAINT message is only sent when there are no other messages in the application's queue. This allows the application to repaint in one, rather than possibly many, steps. To force a repaint rather than waiting, the UpdateWindow function can be called. The InvalidateRect function specifies a rectangle to add to the update region, causing a subsequent WM_PAINT.

The window title is automatically painted and is set with the SetWindowText function, and retrieved with the GetWindowText function.

Client and screen coordinates

Every window is drawn on the screen using the device global screen coordinate system for absolute reference to any pixel on the screen. The Microwindows API allows applications programmers to be concerned with only the relative coordinates from the upper left portion of their window, not including the title bar and 3d effects. This coordinate system is called "client coordinates." As will be explained below, the Microwindows programmer has the option of getting a device context in either screen or client coordinates. If device coordinates are specified, then the coordinate system is device-based and includes the title area and 3d areas of the window. Otherwise, the drawable region is clipped to just that area that is reserved by the system for the application's drawing. The GetClientRect and GetWindowRect functions return client or screen coordinates for the passed window. ClientToScreen and ScreenToClient can be called to translate between window coordinate systems.

Device contexts

An applications programmer must obtain a "device context" before calling any graphics drawing API functions. As explained above, this specifies to the system which window and what coordinate system are desired, so that these don't have to be passed to every graphics function. In addition, various other attributes like foreground and background color are also set in a device context, so that these parameters don't have to be specified for every graphics operation. The device context selects the appropriate clipping region based on the window specified and the coordinate system. When a device context is obtained, various graphics values are set to default values.

To obtain a client device context, call GetDC. To obtain a screen device context, required when drawing onto title bars and the like, call GetWindowDC. In addition, fancy clipping operations and child/sibling window clipping can be specified if GetDCEx is called. When finished drawing, the ReleaseDC function must be called to deallocate the DC.

On receipt of the WM_PAINT message, two special calls, BeginPaint and EndPaint are called, that serve as replacements to the GetDC/ReleaseDC functions. These functions essentially allocate a DC but also validate the update region so that no subsequent WM_PAINT messages are generated. BeginPaint also combines the update region and the clipping region so that user output will only occur where previously invalidated.

Graphics Drawing Functions

There are many graphics drawing API's in the Microwindows API. Following is a list, most of these match up to the engine GdXXX functions.

Table 1-3. Microwindows Graphics Drawing API - defined in wingdi.h

Function

Description

SetTextColor

Set the foreground text color in a DC.

SetBkColor

Set the background color in a DC.

GetSysColor

Get the system color defined for the current look and feel scheme.

SetSysColor

Set a system color.

SetBkMode

Set the use background flag in a DC.

SetROP2

Set the drawing mode (XOR, SET, etc) for drawing.

SetPixel

Draw a pixel in the current fg color.

MoveToEx

Prepare to draw a line.

LineTo

Draw a line from the last location to this one in the current fg color.

Rectangle

Draw a rectangle in the current pen color.

FillRect

Fill a rectangle with the current brush color.

TextOut

Draw text in the current fg/bg color.

ExtTextOut

Draw text in the current fg/bg color.

DrawText

Draw text or compute text height and width sizes.

DrawDIB

Draw a color bitmap.

SelectObject

Select a pen, brush or font to use in a DC.

GetStockObject

Get a predefined standard pen, brush or font.

CreatePen

Create a pen of a certain color.

CreateSolidBrush

Create a brush of a certain color.

CreateCompatibleBitmap

Create an offscreen area to draw onto.

DeleteObject

Delete a pen, brush or bitmap.

CreateCompatibleDC

Create an offscreen DC.

DeleteDC

Delete an offscreen DC.

BitBlit

Copy from one bitmap in a DC to another.

GetSystemPaletteEntries

Get the currently in-use system palette entries.

 

Utility functions

A number of routines are provided for various purposes, described below. These are detailed following:

Table 1-4. Microwindows Utility Functions - defined in wintern.h and winuser.h

Function

Description

MWSetDesktopWallpaper

Set the desktop background image.

MWSetCursor

Set the cursor for a window.

MWRaiseWindow

Raise a window's z-order.

MWLowerWindow

Lower a window's z-order.

MWGetTopWindow

Return the topmost window's handle.

MWRegisterFdInput

Register to send a message when file descriptor has read data available.

MWUnregisterFdInput

Unregister file descriptor for read data messages.

in winuser.h:

 

GetTickCount

Return # milliseconds elapsed since startup.

Sleep

Delay processing for specified milliseconds.

SetTimer

Create a millisecond timer.

KillTimer

Destroy a millsecond timer.

 

Setting window focus

The SetFocus routine is used to pass keyboard focus from one window to another. Keystrokes are always sent to the window with focus. The WM_SETFOCUS and WM_KILLFOCUS messages are sent to windows just receiving and losing focus. The GetActiveWindow routines returns the first non-child ancestor of the focus window, which is the window that is currently highlighted. The GetDesktopWindow routine returns the window handle of the desktop window.

Mouse capture

Normally, Microwindows sends WM_MOUSEMOVE messages to the window the mouse is currently moving over. If desired, the applications programmer can "capture" the mouse and receive all mouse move messages by calling SetCapture. ReleaseCapture returns the processing to normal. In addition, the GetCapture function will return the window with capture, if any.

Rectangle and Region management

There are a number of functions that are used for rectangles and regions. Following is the group:

Table 1-5. Microwindows Rectangle & Region Functions - defined in winuser.h and wingdi.h

Function

Description

SetRect

Define a rectangle structure.

SetRectEmpty

Define an empty rectangle.

CopyRect

Copy a rectangle.

IsRectEmpty

Return TRUE if empty rectangle.

InflateRect

Enlarge a rectangle.

OffsetRect

Move a rectangle.

PtInRect

Determine if a point is in a rectangle.

PtInRect

Determine if a point is in a rectangle.

in wingdi.h:

 

IntersectRect

Intersect two rectangles.

UnionRect

Union two rectangles.

SubtractRect

Difference two rectangles.

EqualRect

Determine if two rectangles are the same.

The following functions are used for region creation and manipulation:

Table 1-6. Microwindows Region Creation & Manipulation Functions - defined in wingdi.h

Function

Description

CreateRectRgn

Create a rectangular region.

CreateRectRgnIndirect

Create a rectangular region from a RECT.

SetRectRgn

Set a region to a single rectangle.

CreateRoundRectRgn

Create a round rectangular region.

CreateEllipticRgn

Create an elliptical or circular region.

CreateEllipticRgnIndirect

Create an elliptical or circular region from a RECT.

OffsetRgn

Offset a region by x, y values.

GetRgnBox

Get a region's bounding rect.

GetRegionData

Get a region's internal data structure.

PtInRgn

Determine if a point is in a region.

RectInRegion

Determine if a rectangle intersects a region.

EqualRgn

Determine if two regions are equal.

CombineRgn

Copy/And/Or/Xor/Subtract a region from another.

The following regions are used to set user specified clipping regions. These regions are then intersected with the visible clipping region that Microwindows maintains prior to drawing:

Table 1-7. Microwindows Clip Region Functions - defined in wingdi.h

Function

Description

SelectClipRegion

Assign a user specified clipping region.

ExtSelectClipRegion

And/Or/Xor/Subtract user clipping region with another region.


This list is not complete by far! Check the header files in src/include for additional functions. There are also dialog functions in windlg.h, resource functions in winres.h and font functions in winfont.h. Also some tools in wintools.h. The detailed description of these functions can be retrieved from the Microsoft Windows API documentation or the ECMA-234 Standard documentation available here:
http://www.ecma-international.org/publications/standards/Ecma-234.htm.

Original by Gary James, updated 5th September 2015 - Georg Potthast