Introduction

Password Safe is a .NET 2.0 Mobile application that allows you to keep your passwords in your mobile secured with the top secure AES encryption. It provides a nice touch surface with gestures, and can be completely used without a stylus, except when you're writing or editing new passwords.

First of all, when you download the exe, you just need to put the DLL and the exe file to any location of your choice. Then, you can start the exe after two security warnings. The password.pws file is optional, and can be placed in the “\My Documents” folder, and contains a demo database just to play around. This database has no password.

How to use Password Safe

The first time you start Password Safe, a welcome screen appears, and an empty default database is created. As the next step, you should create a password for it using the "Change Password" button. Then, you can select a category of passwords. After selecting a category, it appears empty, and you can use the "+" button on the header at the right to create a new one. Just type in a field. You'll notice that the Undo (blue button) and the Save button at the bottom get activated. Now, you can either undo your changes or save them. They are automatically saved when you log out or close Password Safe. If you want to delete a password, go to Details, press the "-" button on the header, and confirm the message dialog.

The Search button becomes active when you are are in a category list. You can minimize the contents of the list by opening the Search panel. In this panel, you can type like you type an SMS. Only those items that contain a part of the possible text you typed remain in the list.

If you want to minimize the choice of categories, click the "+" button on the header to add or remove categories. Don't worry if you remove a category. The passwords don't get lost and are still available in the "All Passwords" category, and you can add the category back to the list at any time.

In future releases I will add the possibility to create and edit our own categories. That's why the categories are all stored in the password.pws database.

Background

In December, I bought a new mobile phone, the Xperia x1. Shortly before Christmas, I decided to quickly write a simple password safe to maintain the various passwords I own, both at job and at home. But as always, I could not write just simple programs, and so I wasn’t satisfied with the features that were available with the .NET Compact Framework for Windows Mobile. It didn’t like good, and it was hard to use without a stylus. Therefore, I decided to create my own fancy controls.

Due to the lack of a better name, I currently call them Fluid Controls, but most probably, I will rename them to a name that sounds good and is not already copyright protected. I guess iControl would not be possible

The controls that I developed are not windows components which are actually “windows”, and so they don’t have their own graphics and message system. They are more like Silverlight controls, which are completely maintained different.

The heart of the controls is the FluidHost class.

It’s the connection between a Windows Form and the Fluid Controls. It listens to all events, like mouse or keyboard events, and translates them to send them to the controls. It also recognizes gestures.

As soon as a gesture is recognized, it sends an OnGesture event to the root level controls (which will redirect them to their child controls, and so on). In this event, a control can decide to do something with this event, or to cancel this event.

The following snippet is from the ScrollContainer class which is the base class for all controls that offer scrolling:

You can try the back gesture in Password Safe. Instead of pressing the Back button, you can wipe your finger from left to right and release it so it has the same effect.

Basically, when the host gets an input event, it redirects it to the root level controls, which will redirect them to their controls, and so on. The exception is the OnKeyPress event which is redirected to the top level control (maybe a textbox), and the top level control redirects the event down to the parent control (or not).

Painting

It’s almost the same as for the normal Windows controls, except that there is a FluidPaintEventArgs event. Remember that the Fluid Controls are not windows controls, and thus they don’t have their own canvas. Therefore, the controls get the Graphics of the host control and the FluidPaintEventArgs has a ControlBounds rectangle that specifies where the control has to paint itself. Due to performance issues, this area is not clipped, so it would be possible to paint outside this rectangle.

Another important property of FluidPaintEventArgs is Region. It contains the region that needs to be painted, and is the same as the region in Graphics.Clip. So, why would I add a separate property? Because, whenever you access the Graphics.Clip, it actually creates a copy of the Region. So, for example, the ListBox would create various regions whenever it checks if an Item is within the region. This is a huge performance penalty, so I added the Region property, which does not create a clone.

To check if a rectangle is dirty and needs to be painted, you can use the Region.IsVisible(rect) method:

The ListBox

The ListBox derives from the ScrollContainer class which is a base class for all controls that support touch screen scrolling.

It will allow different data sources like any IList or a DataTable, but currently, only IList and IBindingList are supported. The advantage of IBindingList is that the ListBox gets informed whenever something has happened to the List, like adding or removing an item, or even modifying an item (if the developer doesn’t forget to notify the binding list by calling ResetItem()).

The List itself can contain any kind of class, simple strings, integers, or complex classes.

To display an item in the ListBox, Templates are used. A Template is a simple panel with an additional Item and ItemIndex property. It is possible to use different Templates for different classes. Therefore, you can specify either a BindTemplate event or override the OnBindTemplate method. In the first case, you get a TemplateEventArgs with the item for which to obtain a template, and you can specify the template for it on the TemplateEventArgs template property. In the latter case, the OnBindTemplate expects to return the template that it can use, with the index and the item as well as the default Template as parameters.

If you don’t use different Templates, you just need to specify a default Template property for the ListBox. This is how I did it in Password Safe.

How does a template get the data?

It doesn’t work automatically, and you have to program this manually. There are two ways to implement this. The first way that I’m using is to override the OnBindValue and or OnItemUpdate methods of a derived Template:

This can become handy when you need to modify some properties of your template depending on the current state of the list box item itself, as the above snippet from the source code shows.

The other way to assign the data is to use the DataBound event handler of the ListBox:

///<summary>/// Occurs after the Template was data bound
/// an the EndInit state is completed for the template.
///</summary>///<example>/// You can use this events to perform some actions that require
/// to raise an event, for instance to set the focus to a control like tbFirstName.Focus().
///</example>publicevent EventHandler<TemplateEventArgs> DataBound;

or, you override the OnDataBound method of a derived listbox. In the source code, I do not use this possibility.

Finally, if you don’t want to use any template, you can directly paint each item, by adding a PaintItem or PaintGroupHeader event handler to the ListBox, or override the OnPaintItem method of a derived ListBox.

I am using this possibility to paint a custom background for a template:

A DataSource for a ListBox is usually a BindingList<object> list. Why not a more specific class like BindingList<MyData>? Because, then you would not be able to add a group header. But, of course, you could create a MyData class and a derived MyGroupHeaderData class, then you would be able to specify a BindingList<MyData> and add some group headers.

As soon as a IGroupHeader is attached as the first item, the ListBox adds a header that is permanently visible and shows the last available group header. It also performs an overlapping as soon as a new group header is close to be the new header. It’s hard to explain, the best is to just try it out.

The ListBox show a scrollbar on demand, as soon as the TopOffset changes and disappears automatically after a delay.

Alpha-blending

It’s possible to use a fade effect for the disappearance of the scrollbar, and you can make the header transparent. But, I don’t use this since alpha-blending slows down the system. I will improve this by using DirectX 2D for alpha-blending functionalities instead of using methods from the GDI+ DLL.

The Panel

The Panel is a host for different controls, of course. Each control has a Anchor property which specifies how to layout the control within a Panel. There is currently no Docking property available. It does this by directly overriding the OnSizeChanged event of a control, but maybe, I’ll add it in a later version. The layout of the controls is smart, so the need to paint areas that are hidden by later controls is reduced, unless they are transparent.

A Panel also has the possibility to act like a window. Therefore, it has the Show, ShowMaximized, and Close methods available. As soon as you call Show, it appears in front of the previous controls with the specified bounds. If you call ShowMaximized, it’ll be maximized to full screen. More interesting thing is to add a ShowTransition parameter to the Show or ShowMaximized call. This parameter specifies that the panel should not just appear, but appear animated into the screen. There are various transitions possible, but currently, only FromBottom or FromTop are supported. The fade effect is simply too slow without DirectX 2D. And, I did not need to use FromLeft or FromRight. I will also add some other effects, like page turning, zooming, etc., as soon as I have the time.

To speed up your panel, you should set EnableDoubleBuffer to true. This creates a separate bitmap and region to invalidate, and so the canvas is only repainted when its own region has become invalidated. EnableDoubleBuffer is smart, and does not always actually use a double buffer. It would make no sense to double buffer when it contains only one control that is already double buffered. On the contrary, it would cause a performance penalty to shift an image from one bitmap to another. The panel checks the situation, and only if it is adequate, will it create a double buffer.

Additionally, you can specify an Alpha value lower than 255, and the panel becomes transparent if you also use EnableDoubleBuffer. But note that alpha-blending is currently slow, and the bigger the panel is, the slower it will become.

The ButtonGroup

The ButtonGroup groups more buttons together. You can specify which corners of the ButtonGroup should be rounded.

The Header

The Header is, like the name says, a header control, which contains a text, a Backbutton on the left, and a ButtonGroup on the right.

The TransitionPanel

This Panel can contain multiple Controls, but only one control is displayed at once. You can use the ItemIndex and/or Item property to change the Control to be displayed. The interesting thing is that the TransitionPanel uses a transition to flip from one control to another.

The NavigationPanel

This is a combination of a Header and a TransitionPanel, which syncs the transition of the panel with the header. It also manages the BackButton automatically, and principally, it is being used to show hierarchical structures.

A NavigationPanel hosts Page panels.

The NavigationPanel has Back and Forward methods. Back navigates back to the previous Page, and Forward to the next level Page.

PageControl

This is a panel that is used for a navigation panel, and has additional properties to be maintained by the NavigationPanel:

BackButton specifies a different back button, if not to be maintained by the NavigationPanel.

Buttons contains the buttons to be displayed in the header as soon as the page becomes active.

Note that I intended to also add a fading animation between the old and new buttons as soon as a page flips, but there is the same performance problem with alpha-blending as mentioned before, so let’s look at what DirectX can do…

NumericPad

This is a compound panel that builds, like the name says, a numeric pad for different purposes.

MessageDialog

A predefined panel that has a text and two or less buttons at the bottom. Its purpose is to show simple dialogs with requests of two choices. You can use the MessageDialog.Show() method to quickly show the dialog. You can also open the dialog modal, so that a transparent empty panel is above the remaining screen and lets the other controls appear darker and not touchable. In that case, you must specify an event handler to decide what to do when one of these buttons is pressed. Here comes an example:

Notice, that I mostly reuse controls, even EventArgs. That’s because some delays appeared while I was playi… testing the scroll behavior. I figured out that the cause was the garbage collector. So for better performance, I created them either generally or first on demand.

Animator class

This is the class that provides neat animations and is similar to Silverlight, though not that flexible. You have three kinds of animations: Linear, Acceleration/Deceleration, or Log. Acceleration/Deceleration does what the name says. If you specify a positive Acceleration property, the animation accelerates; with a negative value, it decelerates. The Log (arithmic) animation is logarithmic, and is best for visual effects that look like you are releasing a rubber band. You can see that kind of animation when you move the top position of a listbox down and release your finger, and then it jumps back to the default position.

GDI+ in the .NET Compact Framework

Unfortunately, some rendering methods that I need to paint my controls are missing in the Compact Framework, though the GDI+ DLL is part of Windows Mobile. Therefore, I use a custom GraphicsPlus class, with Graphics as parameter, that builds a wrapper to the now available methods, like drawing shapes etc. Not everything that the Windows Mobile GDI+ offers is truly possible. Sometimes, you get a NotImplemented exception, for instance, when you try to use a Region with a GraphicsPath. This does not work, so I had to do a workaround to create the glossy buttons, by creating actually two parts of a path, one for the top and one for the bottom, both with different gradients.

Designer

As the fluid controls are not window controls, there is no visual designer available. But since the target is Windows Mobile, you wouldn't create too sophistic UIs, and so the code to define the controls is not that complicated.

Password Safe

Something to mention about Password Safe itself.

It is designed to run on systems with a resolution of 480x800 pixels, but also works on smaller resolutions with 240x320 pixels, though some text might not be readable as the font is too small. Only the search panel that filters out passwords will not show up.

At the Category list, there is an edit button and an add (+) button on the header. When you press the edit button, a round button appears animated on each item on the left to provide an option to delete the item. As soon as you press this button, another button appears on the right to confirm the deletion. This looks nice, but is actually not very performant. The (+) button does the same, both adding and removing items. The iPhone like behavior is just a proof of concept that it is not very difficult to implement, and will be removed in later versions.

The passwords are saved in XML format which is encrypted using the top secure AES encryption.

Encryption

The .NET Framework offers a lot of different symmetric and asymmetric encryption algorithms, do does the Compact Framework for Windows Mobile. But, one important class is missing in the Compact Framework:

Rfc2898DeriveBytes

This class provides functionality to create key data from an arbitrary password string, which is required for every encryption algorithm. You cannot simply convert the password string to a byte[] array using, e.g., Encoding.Default.ToArray(password), since the key must be of a specific size. The size can vary by different blocks, and it depends on the algorithm you are using. For instance, the preferred AES or Rijndael algorithm requires a key size of 128, 256, 384, etc., but nothing in between. Therefore, you need an algorithm that encodes any string to a byte array of at least 128 bytes and not less or more.

Fortunately, this is what hashing algorithms do! So, as a replacement for the missing Rfc2898DeriveBytes, we can use a hash algorithm that belongs to the Compact Framework, and that creates a size that matches the requirements for the encryption algorithm. In this case, since we are using AES, we need a hash with a size of 128 or 256, and the qualified match is the MD5 algorithm. It is not the strongest though, and SH256 would be the better choice, but unfortunately, the Compact Framework does not include this hash algorithm, so we need to use MD5.

Here comes an example of how to implement encryption/decryption for Windows Mobile.

Final words

So, after almost 7000 lines of code, I present you my Christmas vacation project. As soon as I make a final decision for the final name of the controls, I will push them to CodePlex to keep you up to date on newer versions.

I hope you like my application, and of course, I would like to participate in the Microsoft Mobile Developer Contest 2008

I am using Password Safe on a HTC Diamond 2, I included data from a card recently without problems. When I went to access this data, I get an error message and can not see any credit card. The other categories are operating normally.
The error message: InvalidOperationException and provides a bunch of errors.

While opening the file PasswordSafe.exe in windows 7 i get an error saying the application has stopped working.
cant it be installed to device through windows 7?
i have downloaded the source of this project and when i try to open the solution file in vs 2008, i get the following error:
The associated source control plug-in is not installed or could not be initialized.
could some1 plz provide me a solution.

Hi Thomas,
Thank you for support the application.
I found a error when press right button on a empty the category. I think you forget check the item count.

This is the exception information:

PasswordSafe.exe
ArgumentOutOfRangeException
Specified argument was out of the range of valid values.
Parameter name: index
at System.ThrowHelper.ThrowArgumentOutOfRangeException()
at System.Collections.Generic.List`1.get_Item()
at System.Collections.ObjectModel.Collection`1.get_Item()
at PasswordSafe.PasswordsListBox.NavigateForward()
at PasswordSafe.ListBoxBase.OnKeyDown()
at Fluid.Controls.FluidHost.tb_KeyDown()
at System.Windows.Forms.Control.OnKeyDown()
at System.Windows.Forms.Control.WnProc()
at System.Windows.Forms.ButtonBase.WnProc()
at System.Windows.Forms.Control._InternalWnProc()
at Microsoft.AGL.Forms.EVL.EnterMainLoop()
at System.Windows.Forms.Application.Run()
at PasswordSafe.Program.Main()

First of all, I really appreciate this excellent example, which is done by Thomas. Currently I am working on Windows Mobile 6.5.

What I'm asking is How I can add(actually, Controls.add in FluildPanel) standard Windows controls(e.g. TextBox) instead of the FluidTextBox. I know FluildTextBox is pretty good, but it's not working for my language, Korean. I think that FluidTextBox can NOT support other languages that one character is based on two bytes, such as Japanese and Chinese. That's why I want to use standard Windows controls.

Hi, my friend Works Greatly! And i really profit from this thread!
Thanks for what you've done!

I want to point some error, and wait for your reply!

Every time, when i input empty password and login for 24 times(exactly), it throw OutOfMemoryException!
And when i input non-empty incorrectly password and login for about 46 time(exactly), it also throw OutOfMemoryException!

at Microsoft.AGL.Common.MISC.HandleAr()
at System.Drawing.Bitmap._Init()
at System.Drawing.Bitmap..ctor()at Fluid.Controls.FluidPanel.EnsureDBuffer()
at Fluid.Controls.FluidPanel.OnPaint()
at Fluid.Controls.ControlContainer.PaintControlUnbuffered()
at Fluid.Controls.ControlContainer.PaintControl()
at Fluid.Controls.ControlContainer.PaintControls()
at Fluid.Controls.ControlContainer.OnPaint()
at Fluid.Controls.FluidPanel.OnPaint()
at Fluid.Controls.FluidHost.OnPaint()
at System.Windows.Forms.Control.WnProc()
at System.Windows.Forms.Control._InternalWnProc()
at Microsoft.AGL.Forms.WL.Update()
at System.Windows.Forms.Control.Update()at Fluid.Controls.FluidHost.Fluid.Controls.IHost.Update()
at Fluid.Controls.FluidControl.Update()
at Fluid.Controls.FluidPanel.topAnimation_Started()
at Fluid.Classes.Animation.OnStarted()
at Fluid.Classes.Animation.Start()
at Fluid.Controls.FluidPanel.AnimateTop()
at Fluid.Controls.FluidPanel.Show()
at Fluid.Controls.MessageDialog.Show()
at Fluid.Controls.FluidPanel.ShowModal()
at Fluid.Controls.MessageDialog.Show()
at Fluid.Controls.MessageDialog.Show()
at PasswordSafe.LoginPanel.ShowIncorrectPasswordDialog()
at PasswordSafe.LoginPanel.OnEnter()
at PasswordSafe.LoginPanel.PerformEnter()
at PasswordSafe.LoginPanel.numPad_Enter()
at Fluid.Controls.NumericPad.OnEnter()
at Fluid.Controls.NumericPad.btn_Click()
at Fluid.Controls.FluidControl.PerformClick()
at Fludi.Controls.FluidButton.PerformClick()
at Fluid.Controls.FluidControl.OnClick()
at Fluid.Controls.FluidButton.OnClick()
at Fluid.Controls.ControlContainer.OnClick()
at Fluid.Controls.ControlContainer.OnClick()
at Fluid.Controls.ControlContainer.OnClick()
at Fluid.Controls.ControlContainer.OnClick()
at Fluid.Controls.FluidHost.OnMouseUp()
at System.Windows.Forms.Control.WnProc()
at System.Windows.Forms.Control._InternalWnProc()
at Microsoft.AGL.Forms.EVL.EnterMainLoop()
at System.Windows.Forms.Application.Run()
at PasswordSafe.Program.Main()
_________________________________________________________________

It's working with me, I can add button to a customized Fluid Panel, but the problem that I'm getting a panel of size 200 X 200 even if I choose more than these dimensions (240 X 300) why this happened to me, Please Explain this to me...

What a great effort is this from your side Mr.Thomas? Thank you very much for this.

Second, I downloaded the project and I build it on a Samsung Omnia device, CF 3.5, windows mobile 6.1.

The problem that I found is that the NumericPad buttons don't appear because the dialog is painted on the upper half of the dialog, the password text button to the left of the dialog, and the numbad buttons on the right hand of the dialog.

Firstly, thanks a lot for the excellent framework. I just downloaded your source code (both from codeproject & codeplex) and tried to build it. but i get lot of compliation errors (see below). I have checked the code and infact there is no abstract keyword.

For example the error in the code

D:\Projects\WM\Samples\Fluid\Controls\Control.cs(112,30): error CS0501: 'Fluid.Controls.FluidControl.Name.get' must declare a body because it is not marked abstractorextern

Fluid controls are now available on http://fluid.codeplex.com[^]
as soon as the tfs server is back available, I will add the source code to tfs to keep you up to date with the latest release which I'm currently continue.

Hi, a tutorial is definitely a must for such a complex but very powerful library... After digging into the code for a few days, I can only display the header but not listbox on the panel... Do anyone have a simple working example for reference? Thanks a lot!

does not allow scrolling when the virtual height is smaller than the pysical height of the container. I did this on purpose since I see no reason to do scrolling when it is not necassary. However, if your virtual height is larger than the height of the control, then please tell me.

First of all, thank you for your great job. I'm having a problem when using a FluidListBox and a FluidButton within a FluidPanel that is within the control property of an object PageControl. The FluidListBox is too slow. What can I do?
Thanks in advanced

Can you add anymore detail as to what is going on. I am using these controls with no problems.
Maybe you can show how to recreate the issue to see what you are saying. The only slowness that I have seen is the button press gradiant is slow to render and usually does not on the first press. But after that it is fine.

I have been playing with the Fluid DLL in my own project and have made some FluidButtons on a screen. The problem that I am having is there is a box around the buttons, like a border. I have been going through the code but have not found anything that would suggest where this is getting created. I changed the transparent color to Color.DarkSlateGray as I need the a dark bord around my button images. So now I see this light colored box around my image buttons. How do I get rid of it, or change its color to a desired one?

Also since my project is already built using VB.Net, I just compiled the Fluid DLL to use as a reference in my project. The only thing is that the DLL is not CLS compliant. Seeing that I have never dealt with this before I do not know what to change to make it compliant. Maybe someone here could give a hand and we can get this to be compliant. Can't wait to see it get posted to codeplex and see this take off. It is a great tool!!!