Calling the Windows CE Operating System


The desktop version of the .NET Framework is very rich. It includes classes capable of performing advanced windowing, graphics manipulation, network connectivity, and much more. The .NET Framework is nearly a platform of its own, insulating developers from needing to interact with the operating system below. The price of this power and programming convenience is a footprint too large for most devices running Windows CE.

Users of the .NET Compact Framework can invoke the Windows CE operating system to perform actions that are out of reach by using the .NET Compact Framework alone. Situations where doing so would be useful include the following:

  • Performing cryptographic manipulations, such as encrypting data and computing hashes (this subject is treated in great detail in Chapter 14)

  • Accessing the device registry

  • Playing sounds

  • Performing advanced graphics manipulations

Calling the Windows CE operating system is no different from calling native code, as we have described in detail already. In order to call the Windows CE operating system, you need to follow these steps:

  1. Determine what native Windows CE function you want to call. You may need to consult documentation, such as MSDN, to find out what function(s) you must call to get what you want. For example, the PlaySound() function can be used to play a sound file in Windows CE.

  2. Determine what DLL the Windows CE function you want to call resides in.

  3. Create a method declaration in your managed code for the function you want to call. This means understanding what parameters are passed into the function call and choosing the correct managed data types to pass in.

  4. Call the function from managed code, and handle the return value and output parameters as appropriate.

USING MSDN DOCUMENTATION

MSDN Documentation and the documentation included with Embedded Visual C++ 3.0 and 4.0 are invaluable for working through steps 1 and 2. The online documentation is easily searchable and usually states what DLL a Windows CE API function resides in.


LOCATING THE CORRECT DLL FOR WINDOWS CE API FUNCTIONS

Many API functions in Windows CE reside in coredll.dll . It is a good first guess if you can't determine the DLL for a given API function call. Many Windows CE API functions reside in coredll.dll , even if the corresponding function for the desktop versions of Windows is held in a different DLL.


If you understand all of the previous sections of this chapter, then the real challenge is in steps 1, 2, and 4. To solidify the experience of calling the Windows CE operating system, a tutorial approach is used. The goal is to use the Windows CE API to play a .wav sound file.

Calling the Windows CE API to Play a Sound

This section presents a tutorial that implements all four steps needed to call into the Windows CE operating system, as described in the preceding discussion. The goal of the tutorial is to play a .wav sound file.

Determining Which Windows CE Function to Call

The Windows CE function for playing a .wav file is PlaySound() . You can learn all about PlaySound() by consulting the documentation included with Embedded Visual C++ 3.0.

The PlaySound() function resides in coredll.dll . The function prototype, including descriptions of the input parameters, are described as follows :

 
 BOOL WINAPI PlaySound(LPCSTR pszSound, HMODULE hmod, DWORD fdwSound) 

pszSound This parameter is a pointer to a null- terminated string that holds the filename of the sound to play. If the parameter is NULL , then any sound currently playing is stopped .

hmod This parameter provides the ability to specify a sound file embedded in the resource portion of an .exe file for playing. The documentation states that it can be safely set to NULL if the goal is not to play a sound stored in the resource portion of an .exe file. The managed code value IntPtr.Zero represents the NULL value to pass in.

fdwSound This DWORD is the sum of flags we want to pass in to control how the sound is played . Flags of interest include

SND_LOOP This flag tells PlaySound() to play the sound continuously in a loop.

SND_ASYNC This flag causes the function to execute asynchronously. The function call returns immediately, even if the sound is still playing. The default behavior without this flag for the function to block until the sound is finished playing.

One question you may be asking is, How do you know the numeric values of the flags in managed code? In native code, for example, C++, you just need to include the appropriate header file and the flags as defined constants. That doesn't help if you need to know the values for use from managed code.

You may find these values in the documentation. For the constants SND_LOOP and SND_ASYNC , there were no such values in the documentation. Thus, for the tutorial, it was necessary to create a simple application called ConstFinder by using Embedded Visual C++ 3.0. In this C++ application, the constant values SND_LOOP and SND_ASYNC were assigned into DWORD variables . Then, it is easy to use the debugger to step through the code and examine the values and find that SND_LOOP = 8 and SND_ASYNC = 1 . Now one can use these numeric values within managed code and pass them into the PlaySound() function from managed code.

You can find the PlaySound ConstFinder project in the directory \SampleApplications\Chapter12\ PlaySound_ConstFinder .

Creating the Managed Code Declaration for PlaySound

The next step is to create a managed code declaration for the PlaySound function. The following declaration displays this code:

 
 C# [DllImport "coredll.dll"] private static extern bool PlaySound(string pszSound,         IntPtr hmod, uint fdwSound); VB Declare Sub PlaySound Lib "coredll.dll" (         ByVal pszSound As String, ByVal hmod As IntPtr,         ByVal fdwSound As UInt32) 
Calling the Native PlaySound Function

Now call the function as appropriate. The following code sample plays the "\ASound.wav" sound file once. The function blocks until the sound has been played.

 
 C# IntPtr l_NULL = IntPtr.Zero; PlaySound("\ASound.wav", l_NULL, 0); VB Dim l_NULL As IntPtr = IntPtr.Zero PlaySound("\Asound.wav", l_NULL, Convert.ToUInt32(0)) 

The following code sample plays the "\ASound.wav" file continuously. The function returns immediately, even as the sound plays in the background. The calling thread sleeps for five seconds, and then another call to PlaySound() stops the sound from playing.

 
 C# const int SND_LOOP = 8; const int SND_ASYNC = 1; IntPtr l_NULL = IntPtr.Zero; PlaySound("\ASound.wav", l_NULL, SND_LOOP + SND_ASYNC); System.Threading.Thread.Sleep(5000); PlaySound(null, l_NULL, 0); VB Const SND_LOOP As Integer = 8 Const SND_ASYNC As Integer = 1 Dim l_NULL As IntPtr = IntPtr.Zero PlaySound("\ASound.wav", l_NULL,         Convert.ToUInt32(SND_LOOP + SND_ASYNC)) System.Threading.Thread.Sleep(5000) PlaySound(Nothing, l_NULL, Convert.ToUInt32(0)) 

Putting It All Together with a Sample Application: PlaySound

The PlaySound sample application is available in the folder \SampleApplications\Chapter12 , where there are C# and Visual Basic versions.

The PlaySound application is a complete implementation of the issues tackled in the previous tutorial. To use it, build, deploy, and launch it on a device.

The application shows a form with a text box in which you can enter the path to a WAV file to play. The default value is a WAV file included with the Pocket PC version of Windows CE.

To play the sound just once, click the button labeled Play Sound Once. The application calls the native PlaySound function in synchronous mode. The main thread of the managed application blocks until the sound is finished being played.

To play a sound continuously, click the button labeled Play Sound Continuously. The application plays the sound by calling the Windows CE API function, PlaySound() , passing arguments to play the sound in a loop asynchronously. The Play Sound Continuously button's label changes to Stop Playing Sound!!!, and the managed application's main thread remains responsive , even as the sound plays. Click the button relabeled Stop Playing Sound!!! to stop playing the sound. The managed application responds by calling PlaySound() again with a NULL value for the sound file name argument. This causes the sound to stop playing.

This sample application helps illustrate an important point when calling Windows CE functions: Pay attention to whether the function returns immediately and how long the function will take to execute. It is easy to accidentally call a function that performs some sort of I/O in blocking mode and ties up the managed thread that makes the native call for a long time. If you call the function from the main managed thread, then your application will stop responding to user input for a potentially long time. In such cases, consider spinning off a new thread to call the Windows CE operating system. Chapter 4, "Using Threads and Timers in the .NET Compact Framework," describes threading in great detail.



Microsoft.NET Compact Framework Kick Start
Microsoft .NET Compact Framework Kick Start
ISBN: 0672325705
EAN: 2147483647
Year: 2003
Pages: 206

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net