Microwindows API

Message-passing architecture

The fundamental communications mechanism in the Microwindows 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-3. Microwindows Messaging Functions

FunctionDescription
SendMessageSend a message directly to a window.
PostMessageQueue a message on the application's message queue for later dispatch.
PostQuitMessageQueue a WM_QUIT message telling the application to terminate when read.
GetMessageBlock until a message is queued for this application.
TranslateMessageTranslate up/down keystrokes to WM_CHAR messages.
DispatchMessageSend 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-4. Microwindows Window Registration, Creation & Destruction Functions

FunctionDescription
RegisterClassDefine a new window class name and associated window procedure.
UnRegisterClassUndefine a window class.
CreateWindowExCreate an instance of a window of a certain class.
DestroyWindowDestroy a window instance.
GetWindowLongReturn information about a window.
SetWindowLongSet information about a window.
GetWindowWordReturn user information about a window.
SetWindowWordSet user information about a window.
GetClassLongReturn information about a window class.
GetWindowTextGet a window's title or text.
SetWindowTextSet 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 discussed in the section called Device-Independent Engine Features.

Table 1-5. Microwindows Graphics Drawing API

FunctionDescription
SetTextColorSet the foreground text color in a DC.
SetBkColorSet the background color in a DC.
GetSysColorGet the system color defined for the current look and feel scheme.
SetSysColorSet a system color.
SetBkModeSet the use background flag in a DC.
SetROP2Set the drawing mode (XOR, SET, etc) for drawing.
SetPixelDraw a pixel in the current fg color.
MoveToExPrepare to draw a line.
LineToDraw a line from the last location to this one in the current fg color.
RectangleDraw a rectangle in the current pen color.
FillRectFill a rectangle with the current brush color.
TextOutDraw text in the current fg/bg color.
ExtTextOutDraw text in the current fg/bg color.
DrawTextDraw text or compute text height and width sizes.
DrawDIBDraw a color bitmap.
SelectObjectSelect a pen, brush or font to use in a DC.
GetStockObjectGet a predefined standard pen, brush or font.
CreatePenCreate a pen of a certain color.
CreateSolidBrushCreate a brush of a certain color.
CreateCompatibleBitmapCreate an offscreen area to draw onto.
DeleteObjectDelete a pen, brush or bitmap.
CreateCompatibleDCCreate an offscreen DC.
DeleteDCDelete an offscreen DC.
BitBlitCopy from one bitmap in a DC to another.
GetSystemPaletteEntriesGet the currently in-use system palette entries.

Utility functions

A number of routines are provided for various purposes, described below. In addition, Microwindows currently exports some helper routines, named WndXXX, that are useful but subject to change. These are detailed following:

Table 1-6. Microwindows Utility Functions

FunctionDescription
WndSetDesktopWallpaperSet the desktop background image.
WndSetCursorSet the cursor for a window.
WndRaiseWindowRaise a window's z-order.
WndLowerWindowLower a window's z-order.
WndGetTopWindowReturn the topmost window's handle.
WndRegisterFdInputRegister to send a message when file descriptor has read data available.
WndUnregisterFdInputUnregister file descriptor for read data messages.
GetTickCountReturn # milliseconds elapsed since startup.
SleepDelay processing for specified milliseconds.
SetTimerCreate a millisecond timer.
KillTimerDestroy a millsecond timer.
GetCursorPosReturn mouse cursor coordinates.

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-7. Microwindows Rectangle & Region Functions

FunctionDescription
SetRectDefine a rectangle structure.
SetRectEmptyDefine an empty rectangle.
CopyRectCopy a rectangle.
IsRectEmptyReturn TRUE if empty rectangle.
InflateRectEnlarge a rectangle.
OffsetRectMove a rectangle.
PtInRectDetermine if a point is in a rectangle.
PtInRectDetermine if a point is in a rectangle.
IntersectRectIntersect two rectangles.
UnionRectUnion two rectangles.
SubtractRectDifference two rectangles.
EqualRectDetermine if two rectangles are the same.

The following functions are used for region creation and manipulation:

Table 1-8. Microwindows Region Creation & Manipulation Functions

FunctionDescription
CreateRectRgnCreate a rectangular region.
CreateRectRgnIndirectCreate a rectangular region from a RECT.
SetRectRgnSet a region to a single rectangle.
CreateRoundRectRgnCreate a round rectangular region.
CreateEllipticRgnCreate an elliptical or circular region.
CreateEllipticRgnIndirectCreate an elliptical or circular region from a RECT.
OffsetRgnOffset a region by x, y values.
GetRgnBoxGet a region's bounding rect.
GetRegionDataGet a region's internal data structure.
PtInRgnDetermine if a point is in a region.
RectInRegionDetermine if a rectangle intersects a region.
EqualRgnDetermine if two regions are equal.
CombineRgnCopy/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-9. Microwindows Clip Region Functions

FunctionDescription
SelectClipRegionAssign a user specified clipping region.
ExtSelectClipRegionAnd/Or/Xor/Subtract user clipping region with another region.