Thursday, November 6, 2008

Services in Windows Mobile and Windows CE are DLL libraries loaded by service.exe and then run as ..... well as a services. Unfortunately these DLLs has to be written in native code. But why to use native code when man just needs little "invisible" application, that will survive Windows Mobile memory management?

ServiceApplication class

I wrote ServiceApplication class that is used in similar way as Application class in Windows Forms. In fact it is the console application with main loop that processes system messages. ServiceApplication can be controlled from outside world by interprocess messages. Simple WM_USER windows messages. The easiest service can look like this.

There is a service name set, which is actually name of MessageWindows that represents the service. All messages to control the service is send to this MessageWindow. All messages that should be processed by service has to be registered. Whenever the registered message arrived, event is fired. Event handler may look like this.

Example application

ServiceApplication class is bundled in little demo application. Whole solution consists of three projects. Fisrt project CallLoggerLib is library containing ServiceApplication class and Interprocess class for communication with service. Second project is service implementation itself. Very simple CallLoggerService thats logs information about last phone call into the file. Third project CallLogger is a simple UI application which is used to start and stop the service.

Threading is one of the most important thing in application development on Windows platform. Almost none of the serious applications can run in single thread. You will always need to perform some operations on background. The only problem with threads is, when they try to share some critical resources. One of the typical case are UI elements. Whenever you try to change some UI control from different thread than UI thread you will end up with the exception.

Changing UI from thread

Before we look at the events, lets have a look at possibilities for changing UI from thread. All UI controls has methods Invoke and/or BeginInvoke. These methods accepts delegates as parameters. Invoking means, that the delegate given as the parameter will be exceuted in thread that is owner of the UI control. This will not cause parallel access to the UI resource, so no exception will be thrown.

The first option for invoking uses BeginInvoke method and WaitCallback delegate.

This solution is suitable for most situations where simple status reporting is required. Disadvantage of this solution is the only one argument of WaitCallback delegate. In case of multiple informations to be given, you will need to pass structure or array as the argument. Anyway, I'am still using this solution a lot.

Second option offers more scalability and more arguments to be passed, because of custom delegate instead of the WaitCallback. Following code is also part of the previous Form1 class.

Firing thread safe events

Applications are usually splited into two or three layers, where UI and business logic are different layers. When event comes from business layer to UI layer we need to update some status or information. Problem is, if logic in business layer is running in thread. In that case, we need to catch the event and pass the status into thread safe Invokation described above. Such a design is really lousy, because UI logic must in fact rethrow the event to itself and layers are no more strictly separated.

It is necessary to fire event in business layer thread safe way, so that UI layer can immidiately show the status. Since delegates and events in Compact Framework has no Target property as it's in full .NET Framework, we need some workaround. Let's have a look at following class. It is simple worker class representing business layer. Class has UIControl property which represent the UI control that will be Invoked. So FireStatusUpdate method Invokes the control and fires the event. This means, the event will be fired in thread which owns the UIControl.

Thread safe events in full framework

Following snippet shows the modification of the FireStatusUpdate method, to be used in full .NET Framework. There is no need for UIControl property, because delegates contains automaticaly filled property Target.

Input mode in smart phone application

Friday, October 5, 2007 @ 14:03

If you ever used TextBox control in smart phone application, you may found a bit confusing that input mode is selected to numbers. Entering alphabetic strings is then quite uncomfortable. Solution for this behavior is already included in .NET Compact Framework, but not so many coders knows about it.

InputModeEditor

Microsoft.WindowsCE.Forms namespace contains class InputModeEditor with single static method SetInputMode that takes two arguments. First parametr is the object that takes the input (usually TextBox), second one is the enumeration InputMode which contains values like AlphaABC, AlphaT9, Numeric etc.. Usage is obvious:

Today I want to write about small class library I wrote some times ago. It is the compact web server written in C#. Class library implements functionality of the single threaded web server, which can run in Windows CE powered system as well as desktop version of Microsoft Windows. Currently only the GET method is supported, but it's possible to pass query strings and process 'em in custom code. Let's see some examples.

Configuring web server

Configuration for web server is stored in WebServerConfiguration class. Here it's possible to setup server root, listening port, IP address etc.. Important thing is the possibility to configure default files like default.html, index.html or other. Do not forget to register MIME types for files that will be handled by the web server. Setting right mime types is necessary for correct response header of the server.

Special files are those files, that need to be treat in custom method and not just send to the client. CompactWeb server supports virtual directories so you can request directory placed outside the server root.

Necessary step is to setup server root physically in the file system. Simply create the folder and put the website in.

Start me up

Starting the web server is the easiest thing in whole process. Registering OnLogEvent is fine to track client connections, response sending and exceptions. OnSpecialFileType is raised whenever the file registered as special is requested by client. Delegate for this event can handle output to the client.

webServer = new WebServer(webConf);webServer.OnLogEvent += new WebServer.LogEvent(webServer_OnLogEvent);webServer.OnSpecialFileType += new WebServer.SpecialFileType(webServer_OnSpecialFileType);webServer.Start();

From here, your server is running and ready to serve all files placed in the server root.

ASP, PHP, CGI whatever you want

If it's necessary to process some files in special way, you can use delegate to OnSpecialFileType and take the control over processing. Next piece of code handles file with .cgi extension. It takes the content of the file and replace pattern with parameter userName passed in the query string. In case that you will call following URL http://127.0.0.1/form.cgi?userNamer=Joshua the pattern will be replaced with Joshua.

Download and Conclusion

Complete CompactWeb class library with this sample code is possible to download here CompactWebServer.zip . Even if the code is written in compact framework it can be compiled and used with full version of .NET framework. Usage is NOT limited to windows mobile. Feel free to suggest any ideas and improvements, or change the code for your needs. I believe that you will find this library useful.

I must say that I'am always amazed how many useful things you can perform just by simulating the keystrokes in Windows Mobile. In Windows CE SDK is the function keybd_event which generates WM_KEYUP or WM_KEYDOWN message. In fact it means, that you can "broadcast" the key press through whole system. It's unbelievable how many functions is binded to the keys even if it's not physically present on the device.

On this page in MSDN you can find list of many keys supported in Windows CE systems. There are interesting keys like VK_OFF, VK_NONAME, VK_ESC, VK_KEYLOCK. To be honest much better list is in book Programming Microsoft WindowsCe .Net. So let's look on some of the keys and how to play with them.

Sending application into background

Dreaming of minimizing application in Smartphone? If you want to send your application into background, just like the the back-button do - why not press it from application. Just send the VK_ESC key (0x1B).

Showing the Today screen

How to show today screen? Simulate the "home" button which is represented by F4 key. This VK_F4 has value of 0x73.

Lock the device keys

If you want to lock the device, just like it happens after idle time - you can perform it also by key press. On the Smartphone you need VK_APP6 key (0xC6). On the Pocket PC you will use VK_F22 or VK_KEYLOCK key (0x85). Windows Mobile 6.0 has the API function SHDeviceLockAndPrompt which puts device into a lock state as well.

Preventing the device from locking or sleeping

If you are using for instance TomTom navigation and PIN lock on your device, than you are probably fed up by the screen locking after idle time. You can prevent this locking by simulating key press, so the device will think you are still working on your device. But what key to press? You may think about shift or caps-lock, BUT thEn yOyR uSeR INpuTs WiLL loOk liKE tHiS. It must be the key without affects on the input. The VK_NONAME key (0xFC). Key actually does nothing and is reserved for the future use. In my opinion, the time is here.

Turn off the device

I was really surprised that you can simulate press of the key like power button is. The VK_OFF key (0xDF) performs soft reset on Smartphone and screen off on the Pocket PC.

Activate the Speakerphone

If you will read this post from Peter Foot, you will find how VK_F16 key (0x7F) can be useful, when you want to toggle Speakerphone while talking.

Putting it into C# class

Following class encapsulates SendKey function which simulates press of specified key. Function do two P/Invoke calls to keyb_event with KEYUP and KEYDOWN parameters set. You can use this class in Compact Framework 1.0.

Creating shortcuts in Windows Mobile Smartphone

Tuesday, July 24, 2007 @ 10:44

Sometimes people ask me about differencies in Windows Mobile for Smartphone and PocketPC. Hmm, I should say Windows Mobile Standard and Professional. Well, the most significant differences are in UI, and now I know the next one. In Smartphone you are not able to create shortcuts to file on your file system. To be precise you have no option how to create it.

On pocket PC it's quite easy, just select the file in explorer, tap and click Copy. Then go to the folder where you want to place the shortcut, tap and click Paste Shortcut. Unfortunately Smartphones has no Paste Shortcut option. So, it was only matter of time when someone will ask me how to fix this glitch.

How the shortcut works?

In Windows CE (so Windows Mobile) the shortcut file is very simple plain text file. If you open some *.lnk file in notepad, you will see something like this:

42#"\Program Files\Total Commander\cecmd.exe"

The number 42 is of course Answer to Life, the Universe, and Everything. But in this case it is the length of the command placed in shortcut. So that Program Files\Total Commander\cecmd.exe without the quotes. The quotes are neccesary when the path contains spaces. Don't think that you can put qoutes everywhere. If the path has no spaces than put no quotes. Like in this example:

18#\Windows\notes.exe

The # sign is just the delimiter. In cases you want to pass some arguments to the exacutable, you can add it right after the path. Don't forget to add length of the parameters to begining number. Following examples shows executing with parameters. First one executes Total Commander and pass \Windows as the parametr. Second one executes autoprof and pass two parameters. Quotes are NOT count to the length.

51#"\Program Files\Total Commander\cecmd.exe" \Windows

27#\Windows\autoprof -s Silent

Do it from C#

The principles mentioned above is obviously very easy to rewrite into the C# code. So here is the method and example how to place short cut to Total Commander into the start menu.

Complete application

I wrote application called ShortcutMaker as the complete solution for creating shortcuts in smartphones. It is written in C# and uses Compact Framework 1.0, so that it will run without other requirements on WM 2003 and above. Since CF 1.0 has no support for standard file-open and folder-browsing dialogs, I utilize the one from Peter Foot. You can download it from here with examples. Those are now implementeted in OpenNETCF.

Tuesday, October 7, 2008

To get or set the system time of the device, use platform invoke to call the native GetSystemTime or SetSystemTime functions.

Note that the GetSystemTime function returns Coordinated Universal Time (UTC, also known as Greenwich Mean Time). To get your local time, you must add or subtract the number of hours between your time zone and UTC. For example, 24:00 (midnight) in UTC is 19:00 in New York--an offset of minus 5 hours (UTC–5).

To determine the UTC offset for your time zone, see the Time Zone tab of Date and Time Properties.

Some device emulators do not initially set daylight-saving time correctly, which could affect your result.

Visual Basic

PublicStructure SYSTEMTIMEPublic wYear As UInt16Public wMonth As UInt16Public wDayOfWeek As UInt16Public wDay As UInt16Public wHour As UInt16Public wMinute As UInt16Public wSecond As UInt16Public wMilliseconds As UInt16EndStructure

Thursday, September 25, 2008

So I have this problem, where I need to create a tool that creates a folder with a bunch of files on the PC and then copies all these files over to a CE device. The method of choice here was via ActiveSync over USB. One of the design goals was to be able to copy these files to a number of devices simultaneously. However, research revealed that this is not really possible since, activesync only supports one active connection at a time. So much for the great idea.

So now we are faced with this problem of copying files over to the device over ActiveSync. Since the app had a lot of GUI, I created that in C#. The .NET framework exposes excellent API for file manipulation based on paths. The problem with ActiveSync connections is when the device is cradled, there is no drive letter associated with the connection. So all device paths are then \My Documents\ or \Program Files\ etc.

This creates a problem as far as the File manipulation API in System.IO. Since these methods accept relative as well as fully qualified paths, any path like the above, would be treated as a relative path and not a fully qualified path, thereby causing a lot of grief.

The only way to get past this so far has been to use RAPI.

RAPI stands for Remote Application Programming Interface, and was created ages ago with the first wave of activesync and windows mobile products.

RAPI has some documentation on MSDN at: http://msdn.microsoft.com/en-us/library/aa458022.aspx

However since RAPI is a native API, almost all the documentation is geared towards native implementation.

After searching the intertubes for a suitable solution, I couldn’t find one that was recent, and that was guaranteed to work.

Wednesday, September 10, 2008

Introduction

This is a short and simple demonstration of .NET framework's capability of creating custom controls.

Here I'm going to make a custom control and then, test my control in a Windows application. I have implemented some custom properties for my control, so you can learn how it is done in C#.

Building the Control

Open the Visual Studio and start a new project. Your project must be based on the Windows Control Library template. Call your project ctlCuteButton and click OK.

Once you have your project open, delete the UserControl from the project. Just remove it because the 'User Control' is not exactly what we need here.

Now go to the 'Project' menu: Project->Add User Control... and select the Custom Control template there. 'Custom Control' is what we need in this case. You may call it cuteButton. Now click OK. A new Custom control has been added to your project.

The first thing we must do here is to change the base class of the cuteButton:

Override the following line:

publicclass cuteButton : System.Windows.Forms.Control

by this one:

publicclass cuteButton : System.Windows.Forms.Button

Now your control is based on the System.Windows.Forms.Button class.

Now let's create some custom properties for our control. This is done by inserting the following code inside the cuteButton class:

Testing the Control

Open a new instance of the VS .NET. Create a new project choosing the Windows Application template.

From a new Windows Forms project, we can add the compiled custom control to the toolbox. I do this by right-clicking the toolbox, selecting Customize Toolbox, and from the .NET Framework Components tab, clicking Browse and locating the Control Library DLL # (in our case, ctlCuteButton\bin\debug\cuteButton.dll). The component cuteButton will then appear in the Toolbox.

You can play a bit changing it’s properties (cuteColor1, cuteColor2, cuteTransparent1, cuteTransparent2).

That’s all so far about building and using custom controls.

Good Luck.

(Or, do not need to add control from toolbox, add the control project to your project, then the control will appear automatically.)

Monday, August 25, 2008

Correct Use of the SetFont() Function in MFC

SUMMARY

The SetFont() member function of the CWnd class changes the font in a specified control. For this function to work correctly in a Windows- based application, you must ensure that the CFont object specified in the SetFont() call is not destroyed until after the specified control has been destroyed.

MORE INFORMATION

The SetFont() accepts a CFont object as a parameter; the control uses the specified font to display its text. The SetFont() function is implemented to send a WM_SETFONT message to the control with the font handle that corresponds to the CFont object.

An application can delete the font specified in a WM_SETFONT message only under certain circumstances; these same restrictions apply to the CFont object specified in a SetFont() call.

Specifically, do not destroy the specified CFont object until after the CWnd control has been destroyed. Windows does not copy the font specified in a SetFont() call. If the font is destroyed before the control is destroyed, unpredictable results can occur.

For example, when an application uses SetFont() to change the font a dialog box uses, the application should not destroy the CFont object until after it has destroyed the dialog box. Make the CFont object a member variable of the derived dialog box class instead of making the font a local variable in one of the functions in the class. This is the best method to ensure that the CFont object exists for the lifetime of the dialog box. When the application destroys the dialog box, the dialog box class destructor automatically calls the CFont destructor to delete the font handle.

The best time to specify the font for any controls in the dialog box is in the OnInitDialog() member function.

The code below demonstrates deriving a dialog box class from CModalDialog and using the SetFont() member function:

You can check for Ctrl inside the KeyPress event by using the staticproperties Control.ModifierKeysIn theory you should be able to do

if(e.KeyChar == (char)13 && Control.ModifierKeys == Keys.Ctrl)

Except this doesn't work. Modifierkeys are translated to charactersinside the KeyPress event. When you hold ctrl while clicking Enter(char)10 is sent instead of (char)13 and the Control click is suppressed,so all you have to do to detect Ctrl+Enter is

Tuesday, August 19, 2008

BOOL CColdBootApp::InitInstance(){// Standard initialization// If you are not using these features and wish to reduce the size// of your final executable, you should remove from the following// the specific initialization routines you do not need.LPTSTR lCmd = ::GetCommandLine();

10、error C2039: 'OnHelpInfo' : is not a member of 'CView'error C2039: 'OnHelpInfo' : is not a member of 'CFrameWnd'error C2039: 'OnHelpInfo' : is not a member of 'CDialog'解决方法：用TRUE替换相应的类成员函数OnHelpInfo'return CView::OnHelpInfo(pHelpInfo); ——> return TRUE;

11、error C2039: 'm_bShowSharedNewButton' : is not a member of 'CCommandBar'D:Program FilesMicrosoft Visual Studio 8VCceatlmfcincludeafxext.h(557) : see declaration of 'CCommandBar'解决方法：直接注释掉 m_wndCommandBar.m_bShowSharedNewButton = FALSE;

3.遇到stdafx.cpp_CE_ACTIVEX was not defined because this Windows CE SDK does not have DCOM._CE_ACTIVEX could be caused to be defined by defining _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA, but it is recommended that this be done only for single-threaded apps._ATL_NO_HOSTING was defined because _CE_ACTIVEX was not defined.的错误:在stdafx.h文件里加上#define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA可解决.

Wednesday, July 23, 2008

Introduction

Im afraid to say that I am just one of those people that unless I am doing something, I am bored. So now that I finally feel I have learnt tha basics of WPF, it is time to turn my attention to other matters.

I have a long list of things that demand my attention such as (WCF/WF/CLR Via C# version 2 book), but I recently went for (and got, but turned it down in the end) which required me to know a lot about threading. Whilst I consider myself to be pretty good with threading, I thought yeah I'm ok at threading but I could always be better. So as a result of that I have decided to dedicate myself to writing a series of articles on threading in .NET. This series will undoubtely owe much to an excellent Visual Basic .NET Threading Handbook that I bought that is nicely filling the MSDN gaps for me and now you.

I suspect this topic will range from simple to medium to advanced, and it will cover a lot of stuff that will be in MSDN, but I hope to give it my own spin also.

I dont know the exact schedule, but it may end up being something like