Wednesday, July 13, 2011

GC.WaitForPendingFinalizers();

This blog has been discontinued. All information posted will be kept here for future references.

Wednesday, September 3, 2008

Get Name of Executing *.EXE

The Compact Framework doesn't support Assembly.GetEntryAssembly to determine the launching .exe. You can instead P/Invoke the native GetModuleFileName function like so:-

byte[] buffer = new byte[MAX_PATH * 2];

int chars = GetModuleFileName(IntPtr.Zero, buffer, MAX_PATH);

if (chars > 0)

{

string assemblyPath = System.Text.Encoding.Unicode.GetString(buffer, 0, chars * 2);

}

Where MAX_PATH is defined in the Windows CE headers as 260. The P/Invoke declaration for GetModuleFileName looks like this:-

[DllImport("coredll.dll", SetLastError = true)]

private static extern int GetModuleFileName(IntPtr hModule, byte[] lpFilename, int nSize);

The function expects a HMODULE - a handle to a native module. However passing IntPtr.Zero here indicates we want the module which created the process which is our .exe. This code will always return the path of the calling .exe regardless of if it is in a utility dll, or even a GAC assembly located in the \Windows folder.

Source: Peter Foot

Friday, August 22, 2008

Creation Of NK.NB0 File

The nk.bin file is the Windows CE binary image that is usually transfered from Platform Builder to the Windows CE device, but for platforms you need to provide the nk.nb0 files. The nb0 files is a raw version of an bin file, that means that this file can be directly loaded in the SDRAM and executed from there.

Manual generation of an nb0 :
Platform builder environment provide two tools for the generation of the nb0 files. The first one Viewbin used to see the properties of the bin file, the second one Cvrtbin used to convert the bin file into an nb0 file using the information provided by viewbin.
So open your OSDesign and go to Build -> Open Release Directory in Build Window, it will show up a command line window setup for your project.
Use : viewbin nk.bin
ViewBin... nk.bin
Image Start = 0x00220000, length = 0x00AC136C
Start address = 0x0023D618
Checking record #72 for potential TOC (ROMOFFSET = 0x80000000)
Found pTOC = 0x80ce02c0
ROMOFFSET = 0x80000000
Done.

Using this output, the following code example shows the syntax used to create an nk.nb0 file, using the values found in the Image Start and length lines:
cvrtbin -r -a 00220000 -l 00ac136c -w 32 nk.bin

Values may vary for your nk.bin as those information are related to the settings of your BSP and OSDesign.

Source: Nicolas Besson

Tuesday, April 22, 2008

Microsoft Visual Studio & Microsoft Windows CE Development

Developers building Windows CE based devices fall into one of two groups, you are either an operating system developer, or an application developer (and yes, you could be both).

1. Operating System Developer.

For the operating system developer, the CE 6.0 development tools are a plug in to Visual Studio 2005 - the Full CE 6.0 product ships with a full version of Visual Studio 2005 - The CE 6.0 development tool (Platform Builder) gives you the ability to configure, build, download, and debug your custom operating system image. Platform Builder also gives you the ability to write Win32 (C/C++) applications, or DLLs (where the DLL can export functions shared between applications, resource only DLLs, or the DLL could be a device driver in the operating system image).

Operating system developers need Visual Studio 2005, and the CE 6.0 development tools.

2. Application Developer.

Application developers typically don't need access to the underlying operating system development tools, the application developer codes against a "platform". For native code developers (Win32, MFC, *TL), this means that you code against a Windows CE Platform SDK - since you are a native code developer this means that you are calling the Win32 APIs on the operating system directly (MFC is a thin wrapper over Win32) - Since Windows CE is a componentized operating system the exact APIs exposed from a customized "platform" are determined by the embedded operating system developer.

Once a Windows CE configuration is complete, the embedded o/s developer builds a custom SDK (Software Development Kit) that defines the exposed APIs for that specific platform (through header files and libraries). This SDK can then be shared with application developers who install the SDK into Visual Studio 2005 and/or Visual Studio 2008.

The native code developer codes against the custom platform SDK.

Managed code developers have a slightly easier time - the .NET Compact Framework *defines* the underlying platform APIs, when you add the compact framework to a platform configuration a set of operating system dependencies automatically gets added to the platform - as a managed application developer you know that the .NET class libraries are there - if you want to escape the box (platform invoke) then you need to know which native code APIs exist for your specific platform.

Application developers can choose to develop using Visual Studio 2005 OR Visual Studio 2008.

Source: Mike Hall

Detect Windows Mobile Version – Adaptation Kit Update (A.K.U.)


If you want to know which version of known Adaptation Kit Update (AKU) releases you have in your device, check out this link.

To see the AKU of your device, you can :
type : Start / Settings / System Tab / About
Using a C# application, the OSVersion.Version method returns build information.
Using the Registry : HKLM\SYSTEM\Versions\Aku

Source: Fabien Decret

Create Custom Animated Cursor

Most .NET Compact Framework developers will be familiar with the Cursor.Current property and how to display the standard Wait Cursor, but did you know that you could easily display your own custom cursor? This blog entry discusses how you can replace the standard wait cursor with your own application specific cursor. This is an ideal way to brand kiosk style applications for example.

Creating a custom cursor

Recent versions of the Windows CE operating system (and hence Windows Mobile) support an OS API called LoadAnimatedCursor. This API enables you to specify a sequence of individual bitmap frames and will convert them into an animated cursor. For example an animated cursor of a rotating monkey could be made up of the following 4 bitmaps, for example, bitmap value 101, 102, 103 and 104.

The more frames the cursor consists of the smoother the animation will be. Individual frames within the animation should be 48×48 pixel bitmap resources within a *.dll or *.exe file. The bitmap resources are identified by a numeric ID and must be in sequential order (such as the values 101, 102, 103 and 104 used in the example above).
The id of the first bitmap, the total number of frames and the period of time to delay between frames is then passed into the LoadAnimatedCursor API which will return a handle to the newly created cursor (an HCURSOR). Passing this handle to the SetCursor API will then make the cursor visible on the screen.

Unfortunately the LoadAnimatedCursor function is not as easy to use from managed code as it should be. The API expects the bitmap images to be native bitmap resources meaning you can not store them within a *.resx resource file within your .NET Compact Framework application. The easiest way to store the bitmaps in the correct format is to create a native C++ DLL project. You can then remove all the C++ source files, leaving a sole Win32 *.rc resource file to which you can add the bitmaps to (as will be demonstrated later).

Sample Application

[Download animatedcursortest.zip - 37KB]

The sample application available for download consists of two projects. The first (called AnimatedCursors) demonstrates how to create a resource only DLL that contains the bitmap images required for the two custom cursors shown above.
The second project is a C# example demonstrating how to use Platform Invoke to access theLoadAnimatedCursor and SetCursor APIs to display the custom cursors. This second project loads the custom cursors from the AnimatedCursors.dll file built by the first project.

The C# sample wraps up the required Platform Invoke code within a class called AnimatedWaitCursor. This class implements the IDisposable interface so that the following syntax can be used to display a custom cursor. This code structure should be familiar to anyone who has used MFC's CWaitCursor class.

// Use the animated cursor that has 4 frames starting with
// bitmap id 101, delaying 125 milliseconds between each frame.
string dll = @"\path\to\some.dll";
using (AnimatedWaitCursor cursor = new AnimatedWaitCursor(dll, 101, 4, 125))
{
// do some long running task
}
Source: Christopher Fairbairn

Using Delegates (i.e. Function Pointers)

Ever since learning how to use function pointers in C, I've always been a fan of using them to help make code a bit more usable, especially when you've got a state machine. Today, as I'm working on a Wizard UI for a desktop application I came across a typical scenario for using a function pointer. Depending on the stage of the Wizard you're in, a button will have to do separate things.

That got me to thinking that most managed developers simply don't understand the power and utility of delegates, but instead simply consider them a necessity when using Control.Invoke or creating custom events. Sure, in my case I could have a switch statement in the click handler and do logic there, or I could unhook the click handler from one method and hook it to another, but those all seem ugly and a pain in the ass to me. A simple function pointer change is all you need. So I decided I'd throw together a really simple example of how you would use a delegate to change the behavior of a Button click.

Let's assume that we have a button that we want to click, and when it's clicked it will do one of 4 things, depending on the state of our application. We'll just use a messagebox here to give you the idea - what it does is up to you- it's a function after all.

public
void FunctionA()
{
MessageBox.Show(
"FunctionA");
}

public
void FunctionB()
{
MessageBox.Show(
"FunctionB");
}

public
void FunctionC()
{
MessageBox.Show(
"FunctionC");
}

public
void FunctionD()
{
MessageBox.Show(
"FunctionD");
}

To simulate the different "states" I simply added a ListBox (called functionList) to the Form and manually added the function names to it in the Form's constructor. Sure, I could have used Reflection to be clever and populate the list, but I'm tryiong to keep it simple and show delegates.

functionList.Items.Add("FunctionA");
functionList.Items.Add(
"FunctionB");
functionList.Items.Add(
"FunctionC");
functionList.Items.Add(
"FunctionD");

Alright, so now we know that depending on which item is selected, we want to call one of our four functions. Since they all have the same interface (and they have to to use a delegate) we simply define a delegate that matches them. This delegate can be privately scoped inside your class.

delegate
void FunctionDelegate();

And then we create an instance variable to hold the current function pointer we want to use:

private FunctionDelegate m_functionPointer =
null;

We add an event handler for the SelectedIndexChanged event of the ListBox (in the Form constructor)

functionList.SelectedIndexChanged += new EventHandler(functionList_SelectedIndexChanged);

And implement the event handler. It simply looks at the newly selected index in the list and changes the value stored in m_functionPointer appropriately.

void functionList_SelectedIndexChanged(object sender, EventArgs e)
{
// determine which function pointer to store based on selection
switch (functionList.SelectedIndex)
{
case 0:
m_functionPointer
= FunctionA;
break;
case 1:
m_functionPointer
= FunctionB;
break;
case 2:
m_functionPointer
= FunctionC;
break;
case 3:
m_functionPointer
= FunctionD;
break;
default:
m_functionPointer
=
null;
break;
}
}

Next we wire up an event handler for our button (again the the Form constructor):

callButton.Click += new EventHandler(callButton_Click);

And finally the magic and simplicity of the state-dependent call

void callButton_Click(object sender, EventArgs e)
{
// call our function (as long as it's not null)
if (m_functionPointer !=
null)
{
m_functionPointer();
}
}

That's all there is to it. Run the application, select a function and click the button.


Get the full source here.

Source: Chris Tacke