Archive for the 'Mobile' Category

WURFL and SSDS, part I

June 28th, 2008

A friend of mine asked me for some help on mobile device detection.  He introduced me to WURFL, a giant database contains mobile devices information in xml format, in a single file.

First thought came to mind was:  how do I store this thing in a database?  I Googled around, found a couple of .NET libraries working against WURFL, but they all directly working against the xml.  Queries are done against memory objects.

To store this thing in SQL 2005, would need to define a schema, too much work.

I just got access to the SSDS beta, what a perfect match:

  • No need to define any schema.
  • WURFL would be an Authority.
  • Devices would be the container.
  • Each device would be an Entity in the Devices container.
    • device_Id will be the entityId
    • device.Properties will hold the user_agent, fallback_id, and all the capabilities.

Within 30 minutes, I whipped up a console application, parsed the 8MB xml, and stored all the 5755 devices into SSDS.

Next, I will write a web service to query the data.

Posted in .NET, Mobile, SOA, SSDS | No Comments »

MeasureString for wrapped multi-line text height in .NET Compact Framework

April 7th, 2008

In .NET Compact Framework, Graphics.MeasureString only measures the required width and height for a single line string.  What happens if the text is wrapped?

Several years ago, I used this piece of code to measure a wrapped string height.  Not pretty, but works.  A couple of days ago, I found this code, which utilizes the DrawText API, I think is better, but I did not like the idea of taking a control as input.  Combine these two, I have this code:

static public Size MeasureStringEx(Graphics gr, string text, Font font, Rectangle rect)
{
    RECT bounds = new RECT();
    bounds.left = rect.Left;
    bounds.right = rect.Right;
    bounds.bottom = rect.Bottom;
    bounds.right = rect.Right;

    IntPtr hFont = font.ToHfont();
    IntPtr hdc = gr.GetHdc();
    IntPtr originalObject = CoreDll.SelectObject(hdc, hFont);
    int flags = CoreDll.DT_CALCRECT | CoreDll.DT_WORDBREAK;
    CoreDll.DrawText(hdc, text, text.Length, ref bounds, flags);
    CoreDll.SelectObject(hdc, originalObject);
    gr.ReleaseHdc(hdc);
    return new Size(bounds.right - bounds.left, bounds.bottom - bounds.top);
}

and the CoreDll API imports:

Public struct RECT
{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

[DllImport("coredll")]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

[DllImport("coredll.dll")] public static extern int DrawText(IntPtr hdc, string lpStr, int nCount, ref RECT lpRect, int wFormat);
public static int DT_CALCRECT = 0x00000400;
public static int DT_WORDBREAK = 0x00000010;

Posted in .NETCF, Mobile | No Comments »

Windows Mobile 6.1

April 2nd, 2008

It has been announced here, and emulator images can be downloaded from here.

 

Posted in Mobile | No Comments »

Screen Capture in .NET Compact Framework

March 31st, 2008

Five years ago, if you wanted to do a screen capture on Windows Mobile devices with .NET Compact Framework, you would look at Screen Capture, I did not count the lines, but looked quiet long.  Five years later, I wanted to do the same thing, and my code looked like this:

public static Bitmap ScreenCapture(IntPtr hWnd, Rectangle rect)
{
    IntPtr hBitmap; 
    IntPtr hDC = CoreDll.GetDC(hWnd); 
    IntPtr hMemDC = CoreDll.CreateCompatibleDC(hDC);

    hBitmap = CoreDll.CreateCompatibleBitmap(hDC, rect.Width, rect.Height);

    if (hBitmap != IntPtr.Zero)
    {
        IntPtr hOld = (IntPtr)CoreDll.SelectObject(hMemDC, hBitmap);
        CoreDll.BitBlt(hMemDC, 0, 0, rect.Width, rect.Height, hDC, 0, 0, CoreDll.SRCCOPY);

        CoreDll.SelectObject(hMemDC, hOld);

        CoreDll.DeleteDC(hMemDC);
        CoreDll.ReleaseDC(hWnd, hDC);
        Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap);
        CoreDll.DeleteObject(hBitmap);


        return bmp;
    }

    return null;
}

 

The CoreDll imports:

[DllImport("Coredll.dll", EntryPoint = "GetDC")]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImportAttribute("coredll.dll", EntryPoint = "GetWindowDC")]
internal static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("Coredll.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("coredll.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
[DllImport("coredll.dll")]
public static extern IntPtr CreateDIBSection(IntPtr hdc, IntPtr hdr, uint colors, ref IntPtr pBits, IntPtr hFile, uint offset);
[DllImport("coredll")]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("coredll")]
public static extern int DeleteDC(IntPtr hdc);
[System.Runtime.InteropServices.DllImportAttribute("coredll.dll", EntryPoint = "ReleaseDC")]
internal static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("coredll")]
public static extern IntPtr DeleteObject(IntPtr hObject);

Posted in .NETCF, Mobile | No Comments »

How do you explain MSFT’s Mobile Platforms to end users

March 27th, 2008

Let’s say you developed a MSFT Windows mobile software, in the WM5 world, you probably named your product as "XYZ for Windows Mobile 5 Pocket PC edition" and "XYZ for Windows Mobile 5 Smart Phone edition".

These names are fine for people working with WM systems, but for end users, the word "Smart Phone" might create a lot of confusions.  The problem is more and more Pocket PC devices have phone functions, are they Pocket PCs or Smart Phones?  A lot of users might choose the wrong software for the wrong devices.

I use the following simple method to explain this to the end users, it seems working well:

Looking for the "Start" menu on your device, if it's in the top left corner, choose the Pocket PC software; if it's in the lower left corner, use the Smart Phone software.


Pocket PC

Smart Phone

Posted in Mobile | No Comments »

How to programmatically close a message box in .NET Compact Framework

March 24th, 2008

On Windows Mobile devices, there is a Time out setting for the Home or Today screen.  When this time out value is reached, WM will hide whatever program is running and display the Home/Today screen.

This causes a problem for one of my project.  In my project, if the MessageBox.Show(…) function is called and the home/today screen kicks in before the user closes the message box, my program is hidden, and the user has no way to get back in, except turn the device off then on again.

The reason is obvious, modal dialog boxes, like message boxes, block the UI thread until they are closed.  But how do you close a message box while it’s hidden?  After some googling plus try and error, I came up with the following solution:

 

const int WM_DESTROY = 0x02;

 

[DllImport("coredll.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

 

[DllImport("coredll.dll", EntryPoint="SendMessage")]
private static extern uint SendMessage(IntPtr hWnd, uint msg, uint wParam, uint lParam);

 

public static void KillWindow(string className, string title)
{
    IntPtr handle = FindWindow(className, title);
    SendMessage(handle, WM_DESTROY, 0, 0);
}

public static void CloseMessageBox(string title)
{
    IntPtr handle = FindWindow("Dialog", title);
    SendMessage(handle, WM_DESTROY, 0, 0);
}

Posted in .NET, Mobile | No Comments »

How to determine if a table exists in SQL Server Compact (SSC) Edition

March 10th, 2008

In one of my managed code project, I need to determine if a table exists in SSC.  This is pretty easy to do in regular SQL Server with T-SQL:

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[MyTable]') AND type in (N'U'))

SELECT 'Table exists.'

ELSE SELECT 'Table does not exist.'

However, this does not work in SQL Server Compact Edition.  First of all, SSC does not have sys.objects, second, SSC does not support conditional T-SQL.

After googling a bit, I found the first problem can be solved by using INFORMATION_SCHEMA.TABLES, how about the second problem?  I just could not find any conditional T-SQL reference in SSC.

I ended writing a c# function like this:

public static bool DoesTableExist(string tableName, SqlCeConnection ssceconn)
{
    string exsitTSql = @"SELECT COUNT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='" + tableName + "'";
    int cnt = (int) ExecuteScalar(exsitTSql, ssceconn);
    return (cnt == 1);
}

Posted in Mobile, SQL | No Comments »

Silverlight for Mobile Announced

March 5th, 2008

Microsoft announced silverlight for mobile today.

http://silverlight.net/learn/mobile.aspx

It will be a plugin for browsers, starts out with WM6, will go on Nokia phones as well.

Wondering if they are going to port WPF to mobile as well.

Posted in Mobile, Silverlight | No Comments »