Understanding the Shell Behavior for the CE Platforms
Even though the physical difference in screen size between the HPC and the palmtop isn't that large, we do cross a dramatic threshold in the transition between these two devices. You can make a good, usable HPC application without huge changes in your Win32 approach to user interface issues. To make a good, usable palmtop application, you have to embrace the spirit of CE's PPC shell, and this means leaving a lot of familiar and comfortable desktop application design ideas behind.
Though it's possible for a palmtop CE application to do several things simultaneously, designing a PPC application that depends on the user's ability to discern the state of background tasks constitutes a drastic error in judgment. From a user's point of view, a palmtop CE device does one thing at a time: the thing they can see. This isn't a technological limitation; it's a cognitive limitation.
- Provide visual cues for whatever an application is doing
- Take full advantage screen real estate
You'll probably want to rethink many aspects of your Win32 application's visual presentation if it's headed for the PPC. A single dialog, which encapsulates access to all application behavior, is a good basic model with which to start. Difficult choices and possibly a bit of painful pruning lie ahead. That's the bad news. Now for the good news: It's true there isn't much screen real estate available on a PPC, but when your application is active it can take it all.
In the FullScreenDialog example, we'll look into how to take over the entire screen, including the areas normally occupied by the taskbar, the SIP button and the Windows Start logo.
Figure 5- The FullScreenDlg Example Running on the PPC Emulator
Looking At The FullScreenDlg Example
With the exception of FullScreenDlgProc(), almost all of this program was generated by the development environment wizard. However, we see some important differences between this project and earlier examples, because in this case we are looking at code generated specifically for the smaller CE devices. We'll look into the generated code a bit before moving on to the specifics of handling the dialog box.
First, notice that we see some new header files in this application:
#include <aygshell.h> #include <sipapi.h>
These files are specific to the PPC platforms, and contain declarations you'll need in order to call shell functions. If you get linker errors for shell functions, make sure you have #included these.
In the global variables section we see the following new declaration for a SHACTIVATEINFO structure. This is provided as an argument to a function call we see in the main message switch. SHHandleWMSettingChange().
static SHACTIVATEINFO s_sai;
One very good bit of news about the strange new world of the PPC shell is that, by default, you enjoy an almost complete lack of responsibility for maintaining it. However, an important difference for PPC applications is that they must share screen real estate with the Supplementary Input Panel( SIP ), better known as the "chicklet keyboard". Users show and hide this small, screen-based keyboard on demand, which could create real headaches for application programmers. We get a break on this, however, because the system arbitrates SIP screen real estate use in response to the WM_SETTINGCHANGE message:
case WM_SETTINGCHANGE: SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai); break;
The global SHACTIVATEINFO structure maintains data that allows the system to toggle the visibility of the SIP, automatically restoring whatever it covered.
Now let's take a look at how the FullScreenDlg example appropriates system screen real estate to itself.
Taking Over The Entire Screen
In the FullScreenDlg example, we start with an ordinary "Hello World" application. The only significant modification we make is the addition of three items to its menu resource template: "Tacos", "Burritos" and"Enchiladas".
case IDM_TACO: case IDM_BURRITOS: case IDM_TAMALES: DialogBox(hInst, TEXT("FullScreenDlg"), hWnd, FullScreenDlgProc ); break;
If the user chooses any of these, we launch the FullScreenDlgProc(). In the dialog's initialization sequence, we cause it to take over screen real estate that would normally be allotted to shell components. Notice this declaration at the top of the dialog box procedure:
//declaration of the shell's init dialog structure SHINITDLGINFO shidi;
The SHINITDLGINFO structure contains information that determines how a dialog looks when it is invoked. Here are the structure members and their meanings:
Table 1 - SHINITDLGINFO Structure Members and Their Meanings
|DWORD dwMask||Always set to SHIDIM_FLAGS. Indicates that the flags member is initialized|
|HWND hDlg||Handle to the dialog|
|DWORD dwFlags|| SHIDIF_DONEBUTTON- adds an OK button to the navigation bar |
SHIDIF_SIZEDLG- causes the dialog to be sized
SHIDIF_SIZEDLGFULLSCREEN the gets dialog full screen, but leaves the menu bar
SHIDIF_SIPDOWN-shows the dialog and the SIP
SHIDIF_FULLSCREENNOMENUBAR- the dialog gets the whole screen, obscuring the menu bar
We initialize the SHINITDLGINFO structure, and pass it to the SHInitDialog() function.
shidi.hDlg = hWnd; shidi.dwMask = SHIDIM_FLAGS; shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN; SHInitDialog(&shidi);
The function SHInitDialog() is specifically intended to be used to create full screen dialog boxes. One of its advantages is that it places an "Ok" button in the navigation bar, freeing application screen real estate that would have been used for this purpose.
SHInitDialog is fairly flexible — you can take pretty much any combination of screen areas for your own application, depending on the initialization flags you specify. Using the SHIDIF_FULLSCREENNOMENUBAR the dialog starts up using the entire screen. However, you don't have to start with the full screen, because you can dynamically size and position the dialog using the function SHFullScreen(). The parameters to SHFullScreen() are the handle to the window being sized and a flag which defines which real estate it is gaining or relinquishing. Here are the flags and their meanings:
Table 2- SHFullScreen Flags and Their Meanings
|SHFS_SHOWTASKBAR||Show the taskbar|
|SHFS_HIDETASKBAR||Dialog hides task bar|
|SHFS_SHOWSIPBUTTON||Show the SIP button|
|SHFS_HIDESIPBUTTON||Dialog hides SIP button|
|SHFS_SHOWSTARTICON||Show the Windows Start icon|
|SHFS_HIDESTARTICON||Dialog hides Start icon|
Here's how we hide the taskbar and the SIP button:
SHFullScreen(hWnd, SHFS_HIDETASKBAR ); SHFullScreen(hWndParent, SHFS_HIDESIPBUTTON );
Notice that we make one call for each element we change. Next, we move the dialog to its new size and position.
First, we hide the window.
Next we get a DC so that we can get the exact size of the screen in device units.
hdc = GetDC(hWnd); cx = GetDeviceCaps(hdc, HORZRES); cy = GetDeviceCaps(hdc, VERTRES); ReleaseDC(hWnd, hdc); rc.left = 0; rc.top = 0; rc.right = cx; rc.bottom = cy; MoveWindow(hWnd, rc.left, rc.top, rc.right, rc.bottom, TRUE);
Finally, we move the dialog to it's new size and position, wit MoveWindow(). Setting the last parameter to TRUE instructs MoveWindow() to allow the window to make the window visible.
Next, we replace the navigation bar's text string:
Finally, we restore the "Ok" button to the navigation bar so that the user will have a way to dismiss the dialog:
With our examination of the CE shells, we complete a series of articles on getting the "Look and Feel" of CE. In essence, we've seen what we can do with CE. Now that you should understand the form, we are ready to tackle the substance. To me this is the more exciting subject. In coming articles, we'll learn about what's under the hood: memory, the registry, files, databases, and more.
Download source: FullScreenDlg.zip - 4kb
About the Author
Nancy Nicolaisen is a software engineer who has designed and implemented highly modular Windows CE products that include features such as full remote diagnostics, CE-side data compression, dynamically constructed user interface, automatic screen size detection, entry time data validation.
In addition to writing for Developer.com, she has written several books including Making Win 32 Applications Mobile.
# # #