Export (0) Print
Expand All

Creating a P/Invoke Library

.NET Compact Framework 1.0
 

Geoff Schwab
Excell Data Corporation

Contributors:
   Jonathan Wells
   Microsoft Corporation

Registry Sample:
   Dan Elliott
   Microsoft Corporation

Wave Samples:
   Seth Demsey
   Microsoft Corporation

   Jonathan Wells
   Microsoft Corporation

Keyboard Sample:
   Jason Fuller
   Microsoft Corporation

January 2004

Applies to:
   Microsoft® .NET Compact Framework 1.0
   Microsoft Visual Studio® .NET 2003

Summary: This sample demonstrates how to P/Invoke numerous useful native functions that are not directly available through the .NET Compact Framework. A test Form is provided that enumerates all available test procedures and allows the user to select and run them. (18 printed pages)

Download Sample


Contents

Introduction
The Test Application
Input
Memory
Memory Status
Performance Counters
Power Status
SIP
System Reset
System Time
Wave Out
Wave In
Windows
Registry
Phone
Folders
Keyboard

Introduction

The intent of this sample is to provide a collection of P/Invokes, as well test procedures that demonstrate their application. This sample provides several of the most commonly requested P/Invoke functions as well as a class that handles the enumeration and invoking of the various test procedures. This class is used by a Form to allow the user to select and run the tests from a selection list.

Note: For the sake of brevity and to facilitate searches, all function parameters and class definitions have been omitted from code blocks. Refer to the sample for full implementations of all code.

The Test Application

The test application is comprised of two components, the test application Form and the MainTest class. The Form provides the user with a list of all available tests and allows the user to select and run one or all of the tests with a press of the "Run Test" button. The results of the tests are displayed on the Form and can be cleared by pressing the "Clear Results" button.

The MainTest class provides the Form with the number and name of all available tests through Reflection. All classes defined in the Assembly are enumerated and searched for a static method named "TestProc." If this method is defined for a class then it is considered to be a P/Invoke test and is therefore added to the list. If the user runs a test then Reflection is again used to determine the MethodInfo for the TestProc and it is invoked.

Results from the tests are displayed via a delegate defined to take a string. This delegate is provided by the Form to the MainTest constructor and is, in turn, provided to each TestProc method as its only parameter.

Figure 1 shows a sample of the MemoryStatus test being run.

Figure 1. P/Invoke Library Test Application.

Input

The Input class provides the ability to override hardware hot keys and detect button presses regardless of which Control has input focus. Figure 2 shows sample output from this test.

Note: Some hardware keys may not be replicated on some emulators, causing this test to wait indefinitely for the proper key to be pressed.

Figure 2. Input Test Results.

The following functions are implemented in the Input class.

// C#
[DllImport("coredll.dll")]
protected static extern uint RegisterHotKey

[DllImport("coredll.dll")]
protected static extern uint UnregisterFunc1

[DllImport("coredll.dll")]
protected static extern short GetAsyncKeyState

'VB
<DllImport("coredll.dll")> 
Protected Shared Function RegisterHotKey

<DllImport("coredll.dll")> 
Protected Shared Function UnregisterFunc1

<DllImport("coredll.dll")> 
Protected Shared Function GetAsyncKeyState

Memory

The Memory class provides methods for allocating, reallocating, and freeing memory from the heap. Figure 3 shows output from a sample test.

Figure 3. Memory Test Results.

The following functions are implemented in the Memory class.

//c#
[DllImport("coredll.dll")]
extern public static IntPtr LocalAlloc

[DllImport("coredll.dll")]
extern public static IntPtr LocalFree

[DllImport("coredll.dll")]
extern public static IntPtr LocalReAlloc

'VB
<DllImport("coredll.dll")> 
Public Shared Function LocalAlloc 

<DllImport("coredll.dll")> 
Public Shared Function LocalFree 

<DllImport("coredll.dll")> 
Public Shared Function LocalReAlloc 

Memory Status

The MemoryStatus class provides methods for determining the status of the device's memory. Figure 4 shows sample output from this test.

Figure 4. Memory Status Test Results.

The MemoryStatus class implements the following classes and functions.

//C#
public class MEMORYSTATUS

[DllImport("CoreDll.dll")]
public static extern void GlobalMemoryStatus

[DllImport("CoreDll.dll")]
public static extern int GetSystemMemoryDivision

'VB
Public Class MEMORYSTATUS

<DllImport("CoreDll.dll")> 
Public Shared Sub GlobalMemoryStatus 

<DllImport("CoreDll.dll")> 
Public Shared Function GetSystemMemoryDivision 

Performance Counters

The PerfCounter class provides methods for accessing the device's performance counters. For more information on Performance Counters, see "HOWTO: Use a Performance Counter". Figure 5 shows sample output from the Performance Counter test.

Figure 5. Performance Counter Test Results.

The following functions are implemented by the PerfCounter class.

C#
[DllImport("CoreDll.dll")]
public static extern int QueryPerformanceFrequency

[DllImport("CoreDll.dll")]
public static extern int QueryPerformanceCounter

'VB
<DllImport("CoreDll.dll")> 
Public Shared Function QueryPerformanceFrequency 

<DllImport("CoreDll.dll")> 
Public Shared Function QueryPerformanceCounter 

Power Status

The PowerStatus class provides methods for determining the status of the device's power configuration, e.g., batter life, AC line status. For more information on Power Status, see "HOWTO: Get the Device Power Status". Figure 6 shows sample output from the Power Status test.

Figure 6. Power Status Test Results.

The PowerStatus class implements the following classes and functions.

C#
public class SYSTEM_POWER_STATUS_EX2

public class SYSTEM_POWER_STATUS_EX

[DllImport("coredll")]
public static extern uint GetSystemPowerStatusEx

[DllImport("coredll")]
public static extern uint GetSystemPowerStatusEx2

'VB
Public Class SYSTEM_POWER_STATUS_EX2

Public Class SYSTEM_POWER_STATUS_EX

<DllImport("coredll")>
Public Shared Function GetSystemPowerStatusEx

<DllImport("coredll")>
Public Shared Function GetSystemPowerStatusEx2

SIP

The SIP class provides methods for controlling the state of the Software Input Panel. During execution of the test, the SIP is temporarily displayed and then removed. Figure 7 shows sample output from the SIP test.

Figure 7. SIP Test Results.

The SIP class implements the following classes and functions.

C#
[DllImport("coredll.dll")]
public extern static void SipShowIM

[DllImport("coredll.dll")]
public extern static uint SipStatus();

public struct RECT

public class SIPINFO

[DllImport("coredll.dll")]
public extern static uint SipGetInfo

[DllImport("coredll.dll")]
public extern static uint SipSetInfo

'VB
<DllImport("coredll.dll")>
Public Shared Sub SipShowIM

<DllImport("coredll.dll")>
Public Shared Function SipStatus() As Integer

Public Structure RECT

Public Class SIPINFO

<DllImport("coredll.dll")>
Public Shared Function SipGetInfo

<DllImport("coredll.dll")>
Public Shared Function SipSetInfo

System Reset

The SystemReset class provides a mechanism for executing kernel IO controls and specifically demonstrates how to soft reset a device. The user is provided with a warning and the chance to back out, as shown in Figure 8.

Figure 8. System Reset Test Warning.

The SystemReset class implements the following function.

C#
[DllImport("Coredll.dll")]
public extern static uint KernelIoControl

'VB
<DllImport("Coredll.dll")>
Public Shared Function KernelIoControl

System Time

The SystemTime class provides methods for accessing and setting the system time of the device. The test accesses the time, increments it by one hour, then sets it back to the original. Figure 9 shows sample output from the System Time test.

Figure 9. System Time Test Results.

The SystemTime class implements the following structures and functions.

//C#
public struct SYSTEMTIME 

[DllImport("coredll.dll")]
public extern static void GetSystemTime

[DllImport("coredll.dll")]
public extern static uint SetSystemTime

'VB
Public Structure SYSTEMTIME

<DllImport("coredll.dll")>
Public Shared Sub GetSystemTime

<DllImport("coredll.dll")>
Public Shared Function SetSystemTime

Wave Out

The WaveOut class provides methods and classes for playing a .wav file. Due to the complexity of the Waveform Audio Interface, a WaveFile class is provided which encapsulates all of the functionality required to use the WaveOut P/Invoke functions. This class provides a mechanism for streaming audio via a specified buffer size. For more information on this sample, see the article "Recording and Playing Sound with the Waveform Audio Interface". Figure 10 shows sample output from the Wave Out test.

Figure 10. Wave Out Test Results.

Note: A helper class named Wave is provided as a common interface to the .wav audio format for both the WaveIn and WaveOut classes.

The following classes and functions are implemented in the WaveOut class.

//C#
[DllImport ("coredll.dll")]
protected static extern int waveOutGetNumDevs();

[DllImport ("coredll.dll")]
private static extern Wave.MMSYSERR waveOutOpen

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveOutGetVolume

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveOutSetVolume

[DllImport ("coredll.dll")]
private static extern Wave.MMSYSERR waveOutPrepareHeader

[DllImport ("coredll.dll")]
private static extern Wave.MMSYSERR waveOutWrite

[DllImport ("coredll.dll")]
private static extern Wave.MMSYSERR waveOutUnprepareHeader

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveOutClose

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveOutReset

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveOutPause

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveOutRestart

protected class MMTIME

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveOutGetPosition

protected class WAVEOUTCAPS

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveOutGetDevCaps

'VB
<DllImport("coredll.dll")>
Protected Shared Function waveOutGetNumDevs() As Integer

<DllImport("coredll.dll")>
Private Shared Function waveOutOpen

<DllImport("coredll.dll")>
Protected Shared Function waveOutGetVolume

<DllImport("coredll.dll")>
Protected Shared Function waveOutSetVolume

<DllImport("coredll.dll")>
Private Shared Function waveOutPrepareHeader

<DllImport("coredll.dll")>
Private Shared Function waveOutWrite

<DllImport("coredll.dll")>
Private Shared Function waveOutUnprepareHeader

<DllImport("coredll.dll")>
Protected Shared Function waveOutClose

<DllImport("coredll.dll")>
Protected Shared Function waveOutReset

<DllImport("coredll.dll")>
Protected Shared Function waveOutPause

<DllImport("coredll.dll")>
Protected Shared Function waveOutRestart

Protected Class MMTIME

<DllImport("coredll.dll")>
Protected Shared Function waveOutGetPosition

Protected Class WAVEOUTCAPS

<DllImport("coredll.dll")>
Protected Shared Function waveOutGetDevCaps

Wave In

The WaveIn class provides methods and classes for recording a .wav file. Due to the complexity of the Waveform Audio Interface, a WaveFile class is provided which encapsulates all of the functionality required to use the WaveIn P/Invoke functions. For more information on this sample, see the article "Recording and Playing Sound with the Waveform Audio Interface". Figure 11 shows sample output from the Wave In test.

Figure 11. Wave In Test Results.

Note: A helper class named Wave is provided as a common interface to the .wav audio format for both the WaveIn and WaveOut classes.

The following classes and functions are implemented in the WaveIn class.

C#
[DllImport ("coredll.dll")]
protected static extern int waveInGetNumDevs();

[DllImport ("coredll.dll")]
private static extern Wave.MMSYSERR waveInOpen

[DllImport ("coredll.dll")]
private static extern Wave.MMSYSERR waveInPrepareHeader

[DllImport ("coredll.dll")]
private static extern Wave.MMSYSERR waveInUnprepareHeader

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveInClose

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveInReset

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveInStart

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveInStop

[DllImport ("coredll.dll")]
private static extern Wave.MMSYSERR waveInAddBuffer

protected class WAVEINCAPS

[DllImport ("coredll.dll")]
protected static extern Wave.MMSYSERR waveInGetDevCaps

'VB
<DllImport("coredll.dll")>
Protected Shared Function waveInGetNumDevs() As Integer
End Function

<DllImport("coredll.dll")>
Private Shared Function waveInOpen

<DllImport("coredll.dll")>
Private Shared Function waveInPrepareHeader

<DllImport("coredll.dll")>
Private Shared Function waveInUnprepareHeader

<DllImport("coredll.dll")>
Protected Shared Function waveInClose

<DllImport("coredll.dll")>
Protected Shared Function waveInReset

<DllImport("coredll.dll")>
Protected Shared Function waveInStart

<DllImport("coredll.dll")>
Protected Shared Function waveInStop

<DllImport("coredll.dll")>
Private Shared Function waveInAddBuffer

Protected Class WAVEINCAPS

<DllImport("coredll.dll")>
Protected Shared Function waveInGetDevCaps

Windows

The Windows class provides methods for accessing the handle of a window, as well as controlling the state of the window. The test sample creates an invisible Form and then accesses its handle via the various methods. Figure 12 shows sample output from the Windows test.

Figure 12. Windows Test Results

The following functions are implemented by the Windows class.

//C#
[DllImport("coredll.dll")]
public static extern IntPtr GetCapture();

[DllImport("CoreDll")]
public static extern IntPtr FindWindow

[DllImport("CoreDll")]
public static extern bool ShowWindow

'VB
<DllImport("coredll.dll")>
Public Shared Function GetCapture() As IntPtr

<DllImport("CoreDll")>
Public Shared Function FindWindow

<DllImport("CoreDll")>
Public Shared Function ShowWindow

Registry

The Registry class provides methods for accessing the registry on the device. The test sample creates a key and two values, retrieves the values, deletes the values, and then deletes the key. Figure 13 shows sample output from the Registry test.

Figure 13. Registry test results.

The following functions are implemented by the Registry class

//C#
[DllImport("coredll.dll", SetLastError=true)]
public static extern int RegCreateKeyEx

[DllImport("coredll.dll", SetLastError=true)]
public static extern int RegDeleteKey

[DllImport("coredll.dll", SetLastError=true)]
public static extern int RegOpenKeyEx

[DllImport("coredll.dll", SetLastError=true)]
public static extern int RegQueryValueEx

[DllImport("coredll.dll", SetLastError=true)]
public static extern int RegSetValueEx

[DllImport("coredll.dll", SetLastError=true)]
public static extern int RegDeleteValue

[DllImport("coredll.dll", SetLastError=true)]
public static extern int RegCloseKey

'VB
<DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function RegCreateKeyEx

<DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function RegDeleteKey

<DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function RegOpenKeyEx

<DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function RegQueryValueEx

<DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function RegSetValueEx

<DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function RegDeleteValue

<DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function RegCloseKey

Phone

The Phone class provides methods for accessing the Phone API on Pocket PC Phone Edition devices. The test sample accesses the call log and attempts to call the number 555-5555. Figure 14 shows sample output from the Phone test.

Figure 14. Phone test results.

The following functions are implemented by the Phone class

//C#
[DllImport("Phone.dll")]
private static extern int PhoneMakeCall

[DllImport("Phone.dll")]
private static extern void PhoneOpenCallLog

[DllImport("Phone.dll")]
private static extern void PhoneCloseCallLog

[DllImport("Phone.dll")]
private static extern void PhoneGetCallLogEntry

[DllImport("Phone.dll")]
private static extern void PhoneSeekCallLog

'VB
<DllImport("Phone.dll")> _
Private Shared Function PhoneMakeCall

<DllImport("Phone.dll")> _
Private Shared Sub PhoneOpenCallLog

<DllImport("Phone.dll")> _
Private Shared Sub PhoneCloseCallLog

<DllImport("Phone.dll")> _
Private Shared Sub PhoneGetCallLogEntry

<DllImport("Phone.dll")> _
Private Shared Sub PhoneSeekCallLog

Folders

The Folders class provides methods for accessing folder information. The test sample enumerates all storage devices on the device, retrieves the path to the Programs folder, and determines the available space of the Programs folder. Figure 15 shows sample output from the Folders test.

Figure 15. Folders test results.

The following functions are implemented by the Folder class

//C#
[DllImport("Coredll.dll")]
static extern int SHGetSpecialFolderPath

[DllImport("coredll.dll")]
public static extern bool GetDiskFreeSpaceEx

'VB
<DllImport("Coredll.dll")> _
Shared Function SHGetSpecialFolderPath

<DllImport("coredll.dll")> _
Public Shared Function GetDiskFreeSpaceEx

Keyboard

The Keyboard class provides a method for determining hardware keyboard existence and functionality. The test sample detects the presence, or lack of, a keyboard on the device. Figure 16 shows sample output from the Keyboard test.

Figure 16. Keyboard test results.

The Keyboard class implements a registry key test, as well as the following function.

//C#
[DllImport("Coredll.dll")]
static extern uint GetKeyboardStatus

'VB
<DllImport("Coredll.dll")> _
Shared Function GetKeyboardStatus

The registry test is generally more reliable because the P/Invoke method is not guaranteed to be implemented by all OEMs and is only updated once when the OS is booted. The registry method, on the other hand, is "real-time", in that it is updated for hot-pluggable keyboards.

Show:
© 2014 Microsoft