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
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.
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
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.
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.
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.
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.
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.
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
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. |
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
Function | Description |
---|---|
WndSetDesktopWallpaper | Set the desktop background image. |
WndSetCursor | Set the cursor for a window. |
WndRaiseWindow | Raise a window's z-order. |
WndLowerWindow | Lower a window's z-order. |
WndGetTopWindow | Return the topmost window's handle. |
WndRegisterFdInput | Register to send a message when file descriptor has read data available. |
WndUnregisterFdInput | Unregister file descriptor for read data messages. |
GetTickCount | Return # milliseconds elapsed since startup. |
Sleep | Delay processing for specified milliseconds. |
SetTimer | Create a millisecond timer. |
KillTimer | Destroy a millsecond timer. |
GetCursorPos | Return mouse cursor coordinates. |
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.
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.
There are a number of functions that are used for rectangles and regions. Following is the group:
Table 1-7. Microwindows Rectangle & Region Functions
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. |
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-8. Microwindows Region Creation & Manipulation Functions
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: