Windows Programming for Palm OS
Why You Need It
Once you've decided to develop an amazing new game for the Palm OS, you need to discover how to implement your brilliant idea. In simple cases, you propably can end up on the standard Form Manager API. In more interesting cases, Form Manager does not provide sufficient functionality. You then can develop a new custom gadget that will fit perfectly with your needs. But, who knows? Maybe straightforward drawing on the screen will simplify your life much more effectively.
Window Manager also can help you in different situations when you want to display some waiting message on the screen during lengthy operations, a progress bar, and so forth. This article will discuss how to manage windows under Palm OS.
Palm OS Does Windows
But, let's stop the common discussions and move to more practical stuff. You'll find, in Window.h, about a hundred functions covering different aspects of window management. The first thing you will look at is the notion of display window. The system creates a special window at startup. It has the same size as the Palm OS drawable area of the physical display. You can obtain it calling the following:
WinHandle WinGetDisplayWindow(void);
Usually, you won't use this window, but it's nice to know that you at least have such capability. Next, you have a bunch of functions for window management. Below, the most useful APIs are listed. You can gather some sense from their names of what they actually do:
//-----------------------------------------------
// Routines relating to windows management
//-----------------------------------------------
WinHandle WinCreateOffscreenWindow (Coord width, Coord height,
WindowFormatType format,
UInt16 *error)
WinHandle WinCreateBitmapWindow (BitmapType *bitmapP, UInt16 *error)
void WinSetActiveWindow (WinHandle winHandle)
WinHandle WinSetDrawWindow (WinHandle winHandle)
WinHandle WinGetDrawWindow (void)
WinHandle WinGetActiveWindow (void)
void WinGetWindowFrameRect (WinHandle winHandle, RectangleType *r)
void WinDrawWindowFrame (void)
void WinEraseWindow (void)
WinHandle WinSaveBits (const RectangleType *source, UInt16 *error)
void WinRestoreBits (WinHandle winHandle, Coord destX, Coord destY)
void WinCopyRectangle (WinHandle srcWin, WinHandle dstWin,
const RectangleType *srcRect, Coord destX,
Coord destY, WinDrawOperation mode)
void WinScrollRectangle (const RectangleType *rP,
WinDirectionType direction,
Coord distance, RectangleType *vacatedP)
void WinGetDisplayExtent (Coord *extentX, Coord *extentY)
void WinGetDrawWindowBounds (RectangleType *rP)
void WinGetBounds (WinHandle winH, RectangleType *rP)
void WinSetBounds (WinHandle winHandle, const RectangleType *rP)
void WinGetWindowExtent (Coord *extentX, Coord *extentY)
void WinDisplayToWindowPt (Coord *extentX, Coord *extentY)
void WinWindowToDisplayPt (Coord *extentX, Coord *extentY)
void WinGetClip (RectangleType *rP)
void WinSetClip (const RectangleType *rP)
void WinResetClip (void)
void WinClipRectangle (RectangleType *rP)
This is yet a shortened list of calls, but it gives you a general picture of your opportunities. The next sections describe how to work with Window Manager in more detail.
Working with Windows
The usual scenario, which you will implement in your application, can be as with the following:
- Create an offscreen window, which will keep all of the drawing
- Get and store the current Draw Window handle
- Proceed with the required operations for display—draw, copy, or scroll
- Restore the original Draw Window
You can start with offscreen window creation. The offscreen window is a logical structure that enables you to prepare all necessary blocks of the display contents and then actually show them on the physical screen. This window can be bigger or smaller than the full screen. Such a concept is tightly connected to the meaning of device context in MS Windows. The following code creates an offscreen window:
static WinHandle gOffscreenWinH = 0;
...
static Err AppStart(void)
{
Err error;
gOffscreenWinH =
WinCreateOffscreenWindow(g_nWidth,g_nHeight, nativeFormat,
&error);
return errNone;
}
I'd like to point to the third parameter of this function (of the WindowFormatType type). It defines a behavior of created windows in terms of screen features, such as screen depth, density, and pixel format. You can choose from the following:
- screenFormat—bitmaps will be of low density, accept pen input
- genericFormat—the same as screenFormat, but does not accept pen input
- nativeFormat—uses actual hardware screen formats; apps must use graphic APIs to draw
Once you've created the offscreen window, you can draw on it. At any moment, there is only one window in the system that is active. Here, you're approaching the next cluster of functions:
WinHandle WinSetDrawWindow (WinHandle winHandle) WinHandle WinGetDrawWindow (void) WinHandle WinGetActiveWindow (void)
Window Manager lets you get either the active or draw window on demand. Besides, common and apt practice is to set the draw window before you do something, and restore original one at the end:
static void DrawBitmap(WinHandle winHandle, Int16 resID, Int16 x,
Int16 y)
{
MemHandle resH;
BitmapPtr resP;
WinHandle currDrawWindow;
if (winHandle)
currDrawWindow = WinSetDrawWindow(winHandle);
resH = DmGetResource(bitmapRsc, resID);
ErrFatalDisplayIf(! resH, "no bitmap found");
resP = (BitmapPtr)MemHandleLock(resH);
WinDrawBitmap (resP, x, y);
MemPtrUnlock(resP);
DmReleaseResource(resH);
if (winHandle)
WinSetDrawWindow(currDrawWindow);
}
Page 1 of 2
