Friday, August 26, 2016
Wednesday, April 28, 2010
New blog
I am moving all my blogging activity to a new roof, where I will discuss more than just native code on mobile devices. Please follow me on the Smiling Smith.
Wednesday, February 17, 2010
Windows Mobile 6.5.3 Developer Tool Kit
You can now download the Windows Mobile 6.5.3 Developer Tool Kit from this link.
Monday, February 15, 2010
Windows Mobile 7 is here
Actually, it's "Windows Phone 7 Series". Go have a look at the Windows Phone team blog!
Thursday, February 04, 2010
Gesture magic
The February edition of MSDN Magazine is now out with a very interesting and informative article on Windows Mobile 6.5 gestures: Gesture Magic. A must read, I would say...
Tuesday, January 26, 2010
Not yet...
The Windows Mobile 6.5 SDK I announced was removed due to some issues (apparently it was prematurely uploaded). Here's the story from the::unwired. Apparently we will have to wait a bit more before te final version is released.
Sunday, January 24, 2010
Thursday, January 14, 2010
New development certificates
Here I am, back from the December hibernation (not a vacation) with a renewed MVP award. Thank you for that, Microsoft!
It's time to get this blog rolling again, so here's a heads up for you:
New Windows Mobile development certificates
It's time to get this blog rolling again, so here's a heads up for you:
New Windows Mobile development certificates
Sunday, December 06, 2009
An alternative way to create the menu bar
I don't like resources. I really don't. I can understand their usefulness for features such as string tables or embedded icons, but when it comes to the Windows Mobile menu bar definition, I just hate the whole thing. Take a good look at how the CrypSafe sample app's menu bar is defined:
There is a better way, fortunately. A way that you can encapsulate and that makes the whole process a bit more transparent.
You create a Windows Mobile menu bar by calling the SHCreateMenuBar API typically from your main window's WM_CREATE handler. As you can see the function takes a single parameter, a pointer to a SHMENUBARINFO structure where you define the menu bar. There are two ways to create a menu bar: you either specify a menu bar resource ID or you provide your own HMENU by specifying the SHCMBF_HMENU flag. This is in fact a much more palatable alternative because you can declaratively create your menu bar in a single location of your application's code. Using my beloved WTL, here's how the code would look like on the main frame's OnCreate handler:
CodeProject
Intuitive, right? Incidentally, this resource is defined in the .rc2 file and the ATL_IDW_MENU_BAR identifier is used as a default parameter of the CreateSimpleCEMenuBar method of the CFrameWindowImplBase class template. So what do you have to do in order to change the menu bar? Gasp!
ATL_IDW_MENU_BAR SHMENUBAR DISCARDABLE
BEGIN
IDR_MAINFRAME,
2,
I_IMAGENONE, ID_ACTION, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE,
ID_ACTION, 0, NOMENU,
I_IMAGENONE, ID_MENU, TBSTATE_ENABLED, TBSTYLE_DROPDOWN TBSTYLE_AUTOSIZE,
ID_MENU, 0, 0,
END
There is a better way, fortunately. A way that you can encapsulate and that makes the whole process a bit more transparent.
You create a Windows Mobile menu bar by calling the SHCreateMenuBar API typically from your main window's WM_CREATE handler. As you can see the function takes a single parameter, a pointer to a SHMENUBARINFO structure where you define the menu bar. There are two ways to create a menu bar: you either specify a menu bar resource ID or you provide your own HMENU by specifying the SHCMBF_HMENU flag. This is in fact a much more palatable alternative because you can declaratively create your menu bar in a single location of your application's code. Using my beloved WTL, here's how the code would look like on the main frame's OnCreate handler:
The m_mainMenu variable is a CMenu, of course. The advantage of this approach is that you create the main menu bar in a very explicit way and if you later want to change it you know where to find the code, and stop guessing what that crappy SHMENUBAR resource declaration means...
if(m_mainMenu.CreateMenu())
{
m_mainMenu.AppendMenu(MF_BYCOMMAND MF_ENABLED MF_STRING,
ID_BACK, _T("Back"));
m_mainMenu.AppendMenu(MF_BYCOMMAND MF_ENABLED MF_STRING,
ID_MENU, _T("Menu"));
SHMENUBARINFO mbi = { 0 };
mbi.cbSize = sizeof(mbi);
mbi.hwndParent = m_hWnd;
mbi.dwFlags = SHCMBF_HMENU;
mbi.nToolBarId = (UINT)(HMENU)m_mainMenu;
mbi.hInstRes = ModuleHelper::GetResourceInstance();
mbi.nBmpId = 0;
mbi.cBmpImages = 0;
mbi.hwndMB = NULL;
BOOL bRet = ::SHCreateMenuBar(&mbi);
if(bRet != FALSE)
{
m_hWndCECommandBar = mbi.hwndMB;
SizeToMenuBar();
}
}
CodeProject
Tuesday, December 01, 2009
A simple header button
Now that we have a header for the application, what about adding some useful stuff to it, like buttons? The picture on the left shows the second version of the touch header in action with a "back" button that implements the same functionality as the menu bar's "Back" menu. This button should only be visible when there is somewhere to go back to, so we should be able to add it and remove it as we please.For now, the header button is a very simple object containing up to 3 CImage objects (for the normal, depressed and disabled states). This is not a regular Windows button but instead a "sensitive area" of the header that just behaves like a button (just like what happens with regular toolbars).
The button itself is implemented in the CTouchToolbarItem class (see sample code below). It derives from CRefCount so you can use the CRefPtr smart pointer class template to manage it and forget about deleting... The class contains three CImage instances, one for each possible state (these will later be changed to smart pointers as well in order to allow for better reuse).
Buttons are set through the virtual SetupTouchHeader method in each of the child views. Instead of just setting the header text, you can now set up to two buttons (left with index zero and right with index one). The button activation messaging is very similar to a regular menu: the WM_COMMAND message is sent to the parent window (the main frame) with the command ID as the wParam parameter.
A final thought: the header belongs to the frame window and is set up by the child view when they are shown. Is this a good design? I'm wondering if these should "belong" to the child view instead and be replaced along with it, possibly with some fancy animation. What do you think?
Sample code: CrypSafe08.zip (406 KB)
Sunday, November 15, 2009
A basic header
In this post I'm adding a very simple header to the CrypSafe sample, as you can see from the picture. Graphically it is a simple gray gradient with some text printed with an embossed look. Despite of the sleek look, the implementation is quite simple, as you can see from reading the CTouchHeader class source code (see sample source below).The header is implemented as a simple WTL header window. The WTL protocol for headers and footers is quite simple: the frame window sends an empty WM_SIZE message (both width and height are set to zero) to the header and footer signaling these to position themselves in the main frame client rectangle. The remaining space will be occupied by the child view window.
Implementing this protocol is quite simple: handle the WM_SIZE message and reposition the header at the top of the main frame:
void CTouchHeader::OnSize(UINT nType, CSize size)
{
if(size.cx == 0 && size.cy == 0)
{
CWindow wndParent(GetParent());
CRect rc;
wndParent.GetClientRect(&rc);
rc.bottom = rc.top + m_cyHeader;
MoveWindow(&rc);
}
}
The m_cyHeader variable contains the height in pixels of the header. Now, you just need to paint the header with your favorite gradient. Painting the text with the embossed look is also a simple task: you just need to paint it twice in different colors, offsetting the second painting by one or two pixels down. You get the best effect by painting first with a darker color.
As of this implementation, you don't get a very smart header control: it just paints the text it is given. However, we can make this text change according to some application context just like when you switch views. In the sample code below, the header is always present between view switches and the CChildViewManager merely asks each CChildView that is brought into view to update the header text through the virtual SetupTouchHeader function.
Now that this is in place, we can add more features to the header and make it more useful for the whole UI...
Sample code: CrypSafe07.zip (345 Kb)
Friday, November 06, 2009
HOWTO: Close Application on Minimize
This is a popular question lately: how do I close my application when the user clicks the "smart minimize button"? This button does exactly that - it minimizes your application and does not close it. Your main application window is minimized when it receives a WM_SIZE message with the SIZE_MINIMIZED constant in the wParam parameter. All you have to do is call PostMessage(WM_CLOSE) and you are done. Here's a sample WTL handler:
LRESULT CCloseOnMinFrame::OnSize(UINT /*uMsg*/,
WPARAM wParam,
LPARAM /*lParam*/,
BOOL& bHandled)
{
if(wParam == SIZE_MINIMIZED)
{
PostMessage(WM_CLOSE);
bHandled = TRUE;
return 0;
}
// Not handled here
bHandled = FALSE;
return 1;
}
Sunday, November 01, 2009
Article about Windows Mobile 6.5 Gestures
There is a new article on CodeProject about Windows Mobile 6.5 Gestures, and it's fully written in native code. Go there and have a look!
Monday, October 26, 2009
HOWTO: Implement a text ticker

Here's the answer to yet another question asked on the Windows Mobile Developer Center Forums: How to implement a text ticker. The request implied for a flicker-free implementation, so a memory bitmap is required. This bitmap is generated whenever the screen changes size (CTextTickerView::OnSize) or when the text itself changes (CTextTickerView::SetTickerText). To calculate the text size when printed with the given font, a call is made to CDC::GetTextExtent which returns both the height and the width of the text in pixels. The off-screen is then created using the screen width and the text height plus a few padding pixels (CTextTickerView::ResizeBitmap).
Scrolling of the ticker is achieved through a timer that shifts the ticker printing position every 100 ms. The ticker is painted by invalidating its own rectangle and the whole painting process is performed on CTextTickerView::OnPaint. Note how the ticker text gets painted a second time tailing the first instance in order to give a continuous feel. Also note how the x offset is incremented by the timer handler. Go and have a look at the code!
Sample code: TextTicker.zip (114 KB)
HOWTO: Show the Today or Home screen
I recently answered this question on an MSDN forum: how can I show the Today screen from my application? The answer is actually quite simple:
The first line of code retrieves the "desktop" window handle (the Today screen) and in the second you set it to the foreground. Easy.
HWND hWndDesktop = GetDesktopWindow();
SetForegroundWindow((HWND)(((ULONG) hWndDesktop) | 0x01) );
The first line of code retrieves the "desktop" window handle (the Today screen) and in the second you set it to the foreground. Easy.
Monday, October 19, 2009
The Hold Gesture

After writing my last post, I started wondering if I could implement other useful gestures to control the touch list. So I started to wonder what kind of gestures would be needed for a real list-based application, like the CrypSafe prototype I have been working on. One of the issues that you will be confronted with is the requirement of, somehow, single out a single list item and then apply some sort of command to it. Think about deleting a list item: wouldn't it be nice that by clicking the item in a special way you would be able to do just so? There are a lot of other actions you might want to perform in a list item this way (edit, move up or down, you name it). Microsoft actually solved this issue some time ago with the "tap-and-hold" gesture, but gave it a very specific implementation with those circles rolling around the screen to denote it. Alas, I don't like it so I decided to reinvent the wheel and tweak the CTouchGesture in order to implement this gesture. It's actually quite simple: if you press an area of the screen and you don't move or release the finger for some time, a hold gesture is returned by the timer event.
To illustrate the use of this gesture, I implemented a very simple demo based on AppStart (yes, I was lazy) a so that it shows a "context toolbar" when you hold a given list item (see picture). In this case I added an "edit" and a "delete" button that you could use to change the list item. To make the whole thing a bit more fun, I added a small animation to the hold gesture where you can see the item expanding to reveal the "toolbar". Getting information about the pressed toolbar button would be a simple matter of overriding the HitTest function. Note that when the toolbar is displayed you can still flick and click because the item merely changed its size.
Here is the sample app: AppStart05.zip (268 KB)
Labels:
GDI,
User Interface,
Windows Mobile,
WTL
Sunday, October 18, 2009
Ooops!
Please discard the AppStart03.zip file as the project contains a bug. The corrected version is here: AppStart04.zip (169 KB).
Minor touch improvements
In this blog post I'm returning to the touch window code to show you a couple of improvements that were needed.
First, there was the issue of stopping the list halfway through a scroll. If you start dragging the list and then stop, wait a little and then release the finger or stylus, the list would still scroll. This is not an intended (nor intuitive) behavior: the user scrolls the list up to a position and he / she wants it to stay put by stopping the finger / stylus for a fraction of a second and then releasing it.
The second issue happened when the list was "bouncing back" if you forced it to scroll down from the top (or scrolling up from the bottom). Under some occasions you could actually stop the list from scrolling back to its "rest" position leaving it in an awkward state.
To solve the first issue I changed the bulk of the code in the CTouchGesture class and turned it into a state machine with four inputs:
By implementing the gesture recognition as a state machine we get a much better chance of determining and handling the harder to detect situations, such as:
To illustrate all of this, I turned back to the AppStart sample simply because it has a bigger list. Here it is for your viewing pleasure (or not...):
Sample code: AppStart03.zip (166 KB)
First, there was the issue of stopping the list halfway through a scroll. If you start dragging the list and then stop, wait a little and then release the finger or stylus, the list would still scroll. This is not an intended (nor intuitive) behavior: the user scrolls the list up to a position and he / she wants it to stay put by stopping the finger / stylus for a fraction of a second and then releasing it.
The second issue happened when the list was "bouncing back" if you forced it to scroll down from the top (or scrolling up from the bottom). Under some occasions you could actually stop the list from scrolling back to its "rest" position leaving it in an awkward state.
To solve the first issue I changed the bulk of the code in the CTouchGesture class and turned it into a state machine with four inputs:
- Press - The user pressed the finger / stylus
- Move - The user is dragging the finger / stylus
- Release - The user released the finger / stylus
- Timer - Called every 200 ms in order to check transient conditions
By implementing the gesture recognition as a state machine we get a much better chance of determining and handling the harder to detect situations, such as:
- Input noise such as when the user flicks and accidentally releases the screen for a very short period. This is now handled by the code and the state machine assumes that the previous flick is still happening.
- Intermediate motion stop, such as when the user is flicking and stops halfway. This situation is detected by the timer event that essentially resets all displacement and time accumulators and assumes that the user wants to do nothing (this is not interpreted as a click, of course).
To illustrate all of this, I turned back to the AppStart sample simply because it has a bigger list. Here it is for your viewing pleasure (or not...):
Sample code: AppStart03.zip (166 KB)
Sunday, October 11, 2009
It's not a bug...
... it's a feature! Really! I'm talking about my last post where I jumped to the conclusion that I had a bug in a particular line of code. In fact, that line of code is correct - the bug lies elsewhere. Let me explain.
As I stated before, there is no way (at least I never found a way to) use storage object with SQL Compact command parameters. To overcome this limitation the code must allocate the full size of the BLOB data on the binding buffer (which is not very efficient, but it's a viable solution). The problem with this is that the code has to know the size of the BLOB and adjust the binding buffer accordingly. If you use ADO .NET then you know how this issue is solved: the developer must create SqlCeParameters with the given maximum size of the parameter data. The whole purpose of this code is to avoid this situation and let the OLE DB library handle that chore for you.
Command parameter information is requested when you prepare a command and this is the reason why you see the dreaded 1024 constant in the code (the value is pretty arbitrary, by the way). This was the value I chose to represent the default value of the BLOB just to assume a value for it's length. The code then expects that you call SetParam for each parameter and explicitly set its size then. When the command is executed, the whole set of command parameters is looped through in order to get the size of the new binding buffer. If the new binding buffer is larger than the previous one it gets reallocated. And this is exactly where the bug was: the existing buffers were not being deleted and an obvious memory leaked was being created (the complaint reason from the reader who sent me the email message thet prompted me to look at this issue again).
To prove that the memory leak issue is gone in the new code, I set up a very simple demo project where three JPG images are inserted into a sample database table. The images are inserted using a SQL INSERT command and the code is arranged so that the images are processed in an increasing size order. This way you can actually see how the binding buffer increases.
Incidentally, the real bug was on the CCommand::BindParameters method where the m_pBuffer and m_pBindStatus arrays are allocated. These must be freed if non null before allocation.
Sample code: BigParams.zip (789 KB)
Note that the sample application expects both the sdf and jpg files on the \Storage Card\Temp directory. You can change this by editing the BigParamsFrame.cpp file.
As I stated before, there is no way (at least I never found a way to) use storage object with SQL Compact command parameters. To overcome this limitation the code must allocate the full size of the BLOB data on the binding buffer (which is not very efficient, but it's a viable solution). The problem with this is that the code has to know the size of the BLOB and adjust the binding buffer accordingly. If you use ADO .NET then you know how this issue is solved: the developer must create SqlCeParameters with the given maximum size of the parameter data. The whole purpose of this code is to avoid this situation and let the OLE DB library handle that chore for you.
Command parameter information is requested when you prepare a command and this is the reason why you see the dreaded 1024 constant in the code (the value is pretty arbitrary, by the way). This was the value I chose to represent the default value of the BLOB just to assume a value for it's length. The code then expects that you call SetParam for each parameter and explicitly set its size then. When the command is executed, the whole set of command parameters is looped through in order to get the size of the new binding buffer. If the new binding buffer is larger than the previous one it gets reallocated. And this is exactly where the bug was: the existing buffers were not being deleted and an obvious memory leaked was being created (the complaint reason from the reader who sent me the email message thet prompted me to look at this issue again).
To prove that the memory leak issue is gone in the new code, I set up a very simple demo project where three JPG images are inserted into a sample database table. The images are inserted using a SQL INSERT command and the code is arranged so that the images are processed in an increasing size order. This way you can actually see how the binding buffer increases.
Incidentally, the real bug was on the CCommand::BindParameters method where the m_pBuffer and m_pBindStatus arrays are allocated. These must be freed if non null before allocation.
Sample code: BigParams.zip (789 KB)
Note that the sample application expects both the sdf and jpg files on the \Storage Card\Temp directory. You can change this by editing the BigParamsFrame.cpp file.
Thursday, October 08, 2009
Command Parameter Handling
I recently got an email from an interested reader pointing out an error in the SQL command parameter handling OLE DB Client code. If you remember my previous ramblings on this issue, the OLE DB provider for SQL Compact is unable to handle BLOB SQL command parameter through storage objects. This means that you must provide some information about the BLOB before using the command, just like you have to do if you use the ADO .NET stack. Now, if you look at the CCommand::CreateParameter method you will see the error:
ULONG nParamSize = bIsLong ? 1024 : pParamInfo->ulParamSize;
Let me assure you that I was not taking any medication (or smoking funny stuff) when I wrote this line. This is a piece of code that I just did not return to so the error crept in and started to create lots of memory leaks. Solving this issue is not a simple matter of correcting this line to:
ULONG nParamSize = pParamInfo->ulParamSize;
Like I said, we must specify all the BLOB parameter sizes before we prepare the command and this means that CCommand::Prepare must also change. Instead of getting parameter information in the call to Prepare, the user will have the option of calling another method to get this information. In any case, there must be an option to provide custom command parameters. This is the topic of my next post.
ULONG nParamSize = bIsLong ? 1024 : pParamInfo->ulParamSize;
Let me assure you that I was not taking any medication (or smoking funny stuff) when I wrote this line. This is a piece of code that I just did not return to so the error crept in and started to create lots of memory leaks. Solving this issue is not a simple matter of correcting this line to:
ULONG nParamSize = pParamInfo->ulParamSize;
Like I said, we must specify all the BLOB parameter sizes before we prepare the command and this means that CCommand::Prepare must also change. Instead of getting parameter information in the call to Prepare, the user will have the option of calling another method to get this information. In any case, there must be an option to provide custom command parameters. This is the topic of my next post.
Subscribe to:
Posts (Atom)
