<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-11847577</id><updated>2011-10-19T05:10:21.390+01:00</updated><category term='Menu'/><category term='Tech Ed'/><category term='Shell'/><category term='Windows Mobile'/><category term='Visual Studio'/><category term='User Interface'/><category term='WTL'/><category term='ATL'/><category term='MAPI'/><category term='Accelerometer'/><category term='Off topic'/><category term='Article'/><category term='OLE DB'/><category term='GPS'/><category term='Gestures'/><category term='Bluetooth'/><category term='XML'/><category term='GDI+'/><category term='GDI'/><category term='Products'/><category term='MSDN Magazine'/><category term='SQL Compact'/><category term='HOWTO'/><title type='text'>Native Mobile</title><subtitle type='html'>Thoughts on native mobile development on Microsoft platforms</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default?start-index=101&amp;max-results=100'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>341</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-11847577.post-4759028230601276450</id><published>2010-04-28T13:57:00.004+01:00</published><updated>2010-04-28T15:07:21.958+01:00</updated><title type='text'>New blog</title><content type='html'>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 &lt;a href="http://smilingsmith.blogspot.com/"&gt;Smiling Smith&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4759028230601276450?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4759028230601276450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4759028230601276450' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4759028230601276450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4759028230601276450'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2010/04/new-blog.html' title='New blog'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-3827757788069315123</id><published>2010-02-17T09:32:00.002Z</published><updated>2010-02-17T09:35:51.664Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Windows Mobile 6.5.3 Developer Tool Kit</title><content type='html'>You can now download the Windows Mobile 6.5.3 Developer Tool Kit from this &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c0213f68-2e01-4e5c-a8b2-35e081dcf1ca&amp;amp;displaylang=en"&gt;link&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-3827757788069315123?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/3827757788069315123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=3827757788069315123' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3827757788069315123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3827757788069315123'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2010/02/windows-mobile-653-developer-tool-kit.html' title='Windows Mobile 6.5.3 Developer Tool Kit'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6774428860323923020</id><published>2010-02-15T15:29:00.001Z</published><updated>2010-02-15T15:31:30.085Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Windows Mobile 7 is here</title><content type='html'>Actually, it's "Windows Phone 7 Series". Go have a look at the &lt;a href="http://windowsteamblog.com/blogs/windowsphone/archive/2010/02/15/windows-phone-7-series-show-and-tell.aspx"&gt;Windows Phone team blog&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6774428860323923020?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6774428860323923020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6774428860323923020' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6774428860323923020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6774428860323923020'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2010/02/windows-mobile-7-is-here.html' title='Windows Mobile 7 is here'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-8091772362426234361</id><published>2010-02-04T10:40:00.001Z</published><updated>2010-02-04T10:42:04.454Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Gesture magic</title><content type='html'>The February edition of MSDN Magazine is now out with a very interesting and informative article on Windows Mobile 6.5 gestures: &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee309880.aspx"&gt;Gesture Magic&lt;/a&gt;. A must read, I would say...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-8091772362426234361?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/8091772362426234361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=8091772362426234361' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8091772362426234361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8091772362426234361'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2010/02/gesture-magic.html' title='Gesture magic'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-7297555158630275590</id><published>2010-01-26T09:17:00.003Z</published><updated>2010-01-26T09:20:03.939Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Not yet...</title><content type='html'>The Windows Mobile 6.5 SDK I announced was removed due to some issues (apparently it was prematurely uploaded). Here's the story from &lt;a href="http://www.theunwired.net/?item=developing-microsoft-releases-windows-mobile-6-5-professional-and-standard-sdks"&gt;the::unwired&lt;/a&gt;. Apparently we will have to wait a bit more before te final version is released.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-7297555158630275590?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/7297555158630275590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=7297555158630275590' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7297555158630275590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7297555158630275590'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2010/01/not-yet.html' title='Not yet...'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-3344116739303027105</id><published>2010-01-24T13:28:00.002Z</published><updated>2010-01-24T13:29:12.567Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Windows Mobile 6.5.3 SDK</title><content type='html'>The new Windows Mobile 6.5.3 SDK is now available for download &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c5241738-0fe6-4396-a4e5-5a516deb1bc5&amp;amp;displayLang=en"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-3344116739303027105?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/3344116739303027105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=3344116739303027105' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3344116739303027105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3344116739303027105'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2010/01/windows-mobile-653-sdk.html' title='Windows Mobile 6.5.3 SDK'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-1436684288134439544</id><published>2010-01-14T09:22:00.003Z</published><updated>2010-01-14T09:25:02.437Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>New development certificates</title><content type='html'>Here I am, back from the December hibernation (not a vacation) with a renewed MVP award. Thank you for that, Microsoft!&lt;br /&gt;&lt;br /&gt;It's time to get this blog rolling again, so here's a heads up for you:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://windowsteamblog.com/blogs/wmdev/archive/2010/01/12/new-windows-mobile-developer-certificates.aspx"&gt;New Windows Mobile development certificates&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-1436684288134439544?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/1436684288134439544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=1436684288134439544' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1436684288134439544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1436684288134439544'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2010/01/new-development-certificates.html' title='New development certificates'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-1224889243496921765</id><published>2009-12-06T23:12:00.005Z</published><updated>2009-12-11T11:50:44.085Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>An alternative way to create the menu bar</title><content type='html'>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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ATL_IDW_MENU_BAR SHMENUBAR DISCARDABLE&lt;br /&gt;BEGIN&lt;br /&gt;IDR_MAINFRAME,&lt;br /&gt;2,&lt;br /&gt;I_IMAGENONE, ID_ACTION, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE,&lt;br /&gt;ID_ACTION, 0, NOMENU,&lt;br /&gt;I_IMAGENONE, ID_MENU, TBSTATE_ENABLED, TBSTYLE_DROPDOWN  TBSTYLE_AUTOSIZE,&lt;br /&gt;ID_MENU, 0, 0,&lt;br /&gt;END&lt;br /&gt;&lt;/pre&gt;Intuitive, right? Incidentally, this resource is defined in the .rc2 file and the &lt;span style="font-family:courier new;"&gt;ATL_IDW_MENU_BAR&lt;/span&gt; identifier is used as a default parameter of the &lt;span style="font-family:courier new;"&gt;CreateSimpleCEMenuBar&lt;/span&gt; method of the &lt;span style="font-family:courier new;"&gt;CFrameWindowImplBase&lt;/span&gt; class template. So what do you have to do in order to change the menu bar? Gasp!&lt;br /&gt;&lt;br /&gt;There is a better way, fortunately. A way that you can encapsulate and that makes the whole process a bit more transparent.&lt;br /&gt;&lt;br /&gt;You create a Windows Mobile menu bar by calling the &lt;a style="FONT-FAMILY: courier new" href="http://msdn.microsoft.com/en-us/library/aa453678.aspx"&gt;SHCreateMenuBar&lt;/a&gt; API typically from your main window's &lt;span style="font-family:courier new;"&gt;WM_CREATE&lt;/span&gt; handler. As you can see the function takes a single parameter, a pointer to a &lt;a href="http://msdn.microsoft.com/en-us/library/aa453721.aspx"&gt;&lt;span style="font-family:courier new;"&gt;SHMENUBARINFO&lt;/span&gt;&lt;/a&gt; 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 &lt;span style="font-family:courier new;"&gt;HMENU&lt;/span&gt; by specifying the &lt;span style="font-family:courier new;"&gt;SHCMBF_HMENU&lt;/span&gt; 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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if(m_mainMenu.CreateMenu())&lt;br /&gt;{&lt;br /&gt;  m_mainMenu.AppendMenu(MF_BYCOMMAND  MF_ENABLED  MF_STRING,&lt;br /&gt;                        ID_BACK, _T("Back"));&lt;br /&gt;  m_mainMenu.AppendMenu(MF_BYCOMMAND  MF_ENABLED  MF_STRING,&lt;br /&gt;                        ID_MENU, _T("Menu"));&lt;br /&gt;&lt;br /&gt;  SHMENUBARINFO mbi = { 0 };&lt;br /&gt;  mbi.cbSize        = sizeof(mbi);&lt;br /&gt;  mbi.hwndParent    = m_hWnd;&lt;br /&gt;  mbi.dwFlags       = SHCMBF_HMENU;&lt;br /&gt;  mbi.nToolBarId    = (UINT)(HMENU)m_mainMenu;&lt;br /&gt;  mbi.hInstRes      = ModuleHelper::GetResourceInstance();&lt;br /&gt;  mbi.nBmpId        = 0;&lt;br /&gt;  mbi.cBmpImages    = 0;&lt;br /&gt;  mbi.hwndMB        = NULL;&lt;br /&gt;&lt;br /&gt;  BOOL bRet = ::SHCreateMenuBar(&amp;amp;mbi);&lt;br /&gt;  if(bRet != FALSE)&lt;br /&gt;  {&lt;br /&gt;      m_hWndCECommandBar = mbi.hwndMB;&lt;br /&gt;      SizeToMenuBar();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The &lt;span style="font-family:courier new;"&gt;m_mainMenu&lt;/span&gt; variable is a &lt;span style="font-family:courier new;"&gt;CMenu&lt;/span&gt;, 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 &lt;span style="font-family:courier new;"&gt;SHMENUBAR&lt;/span&gt; resource declaration means...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:smaller"&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=47486" rel="tag"&gt;CodeProject&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-1224889243496921765?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/1224889243496921765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=1224889243496921765' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1224889243496921765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1224889243496921765'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/12/alternative-way-to-create-menu-bar.html' title='An alternative way to create the menu bar'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-1326753523251420919</id><published>2009-12-01T19:33:00.003Z</published><updated>2009-12-01T21:45:46.256Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>A simple header button</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_AksH5-lumMs/SxVvpcBQnSI/AAAAAAAAAdw/LAhbTSu0FfQ/s1600/HeaderButton.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 240px; height: 320px;" src="http://1.bp.blogspot.com/_AksH5-lumMs/SxVvpcBQnSI/AAAAAAAAAdw/LAhbTSu0FfQ/s320/HeaderButton.png" alt="" id="BLOGGER_PHOTO_ID_5410353285042314530" border="0" /&gt;&lt;/a&gt;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.&lt;br /&gt;&lt;br /&gt;For now, the header button is a very simple object containing up to 3 &lt;span style="font-family: courier new;"&gt;CImage&lt;/span&gt; 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).&lt;br /&gt;&lt;br /&gt;The button itself is implemented in the &lt;span style="font-family: courier new;"&gt;CTouchToolbarItem&lt;/span&gt; class (see sample code below). It derives from &lt;span style="font-family: courier new;"&gt;CRefCount&lt;/span&gt; so you can use the &lt;span style="font-family: courier new;"&gt;CRefPtr&lt;/span&gt; smart pointer class template to manage it and forget about deleting... The class contains three &lt;span style="font-family: courier new;"&gt;CImage&lt;/span&gt; instances, one for each possible state (these will later be changed to smart pointers as well in order to allow for better reuse).&lt;br /&gt;&lt;br /&gt;Buttons are set through the virtual &lt;span style="font-family: courier new;"&gt;SetupTouchHeader&lt;/span&gt; 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 &lt;span style="font-family: courier new;"&gt;WM_COMMAND&lt;/span&gt; message is sent to the parent window (the main frame) with the command ID as the &lt;span style="font-family: courier new;"&gt;wParam&lt;/span&gt; parameter.&lt;br /&gt;&lt;br /&gt;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?&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/CrypSafe08.zip"&gt;CrypSafe08.zip&lt;/a&gt; (406 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-1326753523251420919?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/1326753523251420919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=1326753523251420919' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1326753523251420919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1326753523251420919'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/12/simple-header-button.html' title='A simple header button'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_AksH5-lumMs/SxVvpcBQnSI/AAAAAAAAAdw/LAhbTSu0FfQ/s72-c/HeaderButton.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-8063748251467871362</id><published>2009-11-15T12:07:00.004Z</published><updated>2009-11-15T12:31:16.708Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>A basic header</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_AksH5-lumMs/Sv_vDmumNKI/AAAAAAAAAdo/1RI8WFzdj6U/s1600-h/TouchHeader.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 240px; height: 320px;" src="http://2.bp.blogspot.com/_AksH5-lumMs/Sv_vDmumNKI/AAAAAAAAAdo/1RI8WFzdj6U/s320/TouchHeader.png" alt="" id="BLOGGER_PHOTO_ID_5404300923082519714" border="0" /&gt;&lt;/a&gt;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 &lt;span style="font-family:courier new;"&gt;CTouchHeader&lt;/span&gt; class source code (see sample source below).&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-family:courier new;"&gt;WM_SIZE&lt;/span&gt; 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.&lt;br /&gt;&lt;br /&gt;Implementing this protocol is quite simple: handle the WM_SIZE message and reposition the header at the top of the main frame:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void CTouchHeader::OnSize(UINT nType, CSize size)&lt;br /&gt;{&lt;br /&gt;   if(size.cx == 0 &amp;amp;&amp;amp; size.cy == 0)&lt;br /&gt;   {&lt;br /&gt;       CWindow wndParent(GetParent());&lt;br /&gt;       CRect   rc;&lt;br /&gt;&lt;br /&gt;       wndParent.GetClientRect(&amp;amp;rc);&lt;br /&gt;       rc.bottom = rc.top + m_cyHeader;&lt;br /&gt;       MoveWindow(&amp;amp;rc);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style="font-family: courier new;"&gt;m_cyHeader&lt;/span&gt; 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.&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-family: courier new;"&gt;CChildViewManager&lt;/span&gt; merely asks each &lt;span style="font-family: courier new;"&gt;CChildView&lt;/span&gt; that is brought into view to update the header text through the virtual &lt;span style="font-family: courier new;"&gt;SetupTouchHeader&lt;/span&gt; function.&lt;br /&gt;&lt;br /&gt;Now that this is in place, we can add more features to the header and make it more useful for the whole UI...&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/CrypSafe07.zip"&gt;CrypSafe07.zip&lt;/a&gt; (345 Kb)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-8063748251467871362?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/8063748251467871362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=8063748251467871362' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8063748251467871362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8063748251467871362'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/11/basic-header.html' title='A basic header'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_AksH5-lumMs/Sv_vDmumNKI/AAAAAAAAAdo/1RI8WFzdj6U/s72-c/TouchHeader.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5034872100370029288</id><published>2009-11-06T08:56:00.003Z</published><updated>2009-11-06T09:03:08.723Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='HOWTO'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>HOWTO: Close Application on Minimize</title><content type='html'>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 &lt;span style="font-family: courier new;"&gt;WM_SIZE&lt;/span&gt; message with the &lt;span style="font-family: courier new;"&gt;SIZE_MINIMIZED&lt;/span&gt; constant in the &lt;span style="font-family: courier new;"&gt;wParam&lt;/span&gt; parameter. All you have to do is call &lt;span style="font-family: courier new;"&gt;PostMessage(WM_CLOSE)&lt;/span&gt; and you are done. Here's a sample WTL handler:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;LRESULT CCloseOnMinFrame::OnSize(UINT /*uMsg*/, &lt;br /&gt;                                 WPARAM wParam, &lt;br /&gt;                                 LPARAM /*lParam*/, &lt;br /&gt;                                 BOOL&amp;amp; bHandled)&lt;br /&gt;{&lt;br /&gt;    if(wParam == SIZE_MINIMIZED)&lt;br /&gt;    {&lt;br /&gt;        PostMessage(WM_CLOSE);&lt;br /&gt;        bHandled = TRUE;&lt;br /&gt;        return 0;&lt;br /&gt;    }&lt;br /&gt;    // Not handled here&lt;br /&gt;    bHandled = FALSE;&lt;br /&gt;    return 1;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5034872100370029288?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5034872100370029288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5034872100370029288' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5034872100370029288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5034872100370029288'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/11/howto-close-application-on-minimize.html' title='HOWTO: Close Application on Minimize'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-3139679164873249027</id><published>2009-11-01T11:37:00.001Z</published><updated>2009-11-01T11:39:39.956Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gestures'/><category scheme='http://www.blogger.com/atom/ns#' term='Article'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Article about Windows Mobile 6.5 Gestures</title><content type='html'>There is a new article on &lt;a href="http://www.codeproject.com/KB/mobile/IntroToGesturesAPI.aspx"&gt;CodeProject&lt;/a&gt; about Windows Mobile 6.5 Gestures, and it's fully written in native code. Go there and have a look!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-3139679164873249027?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/3139679164873249027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=3139679164873249027' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3139679164873249027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3139679164873249027'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/11/article-about-windows-mobile-65.html' title='Article about Windows Mobile 6.5 Gestures'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-1957893120259535068</id><published>2009-10-26T22:41:00.003Z</published><updated>2009-10-26T22:57:36.007Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='GDI'/><category scheme='http://www.blogger.com/atom/ns#' term='HOWTO'/><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>HOWTO: Implement a text ticker</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_AksH5-lumMs/SuYpSG5LWxI/AAAAAAAAAdg/NfBMJ3vGaOg/s1600-h/TextTicker.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 150px; height: 200px;" src="http://4.bp.blogspot.com/_AksH5-lumMs/SuYpSG5LWxI/AAAAAAAAAdg/NfBMJ3vGaOg/s200/TextTicker.png" alt="" id="BLOGGER_PHOTO_ID_5397046594514934546" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Here's the answer to yet another question asked on the &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/vssmartdevicesnative/thread/61794db0-700d-48b5-939d-633e7832f2f4"&gt;Windows Mobile Developer Center Forums&lt;/a&gt;: 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 (&lt;span style="font-family:courier new;"&gt;CTextTickerView::OnSize&lt;/span&gt;) or when the text itself changes (&lt;span style="font-family:courier new;"&gt;CTextTickerView::SetTickerText&lt;/span&gt;). To calculate the text size when printed with the given font, a call is made to &lt;span style="font-family:courier new;"&gt;CDC::GetTextExtent&lt;/span&gt; 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 (&lt;span style="font-family:courier new;"&gt;CTextTickerView::ResizeBitmap&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-family:courier new;"&gt;CTextTickerView::OnPaint&lt;/span&gt;. 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 &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; offset is incremented by the timer handler. Go and have a look at the code!&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/TextTicker.zip"&gt;TextTicker.zip&lt;/a&gt; (114 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-1957893120259535068?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/1957893120259535068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=1957893120259535068' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1957893120259535068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1957893120259535068'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/10/howto-implement-text-ticker.html' title='HOWTO: Implement a text ticker'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_AksH5-lumMs/SuYpSG5LWxI/AAAAAAAAAdg/NfBMJ3vGaOg/s72-c/TextTicker.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6240019152442037878</id><published>2009-10-26T13:42:00.003Z</published><updated>2009-10-26T13:47:14.922Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='HOWTO'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>HOWTO: Show the Today or Home screen</title><content type='html'>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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;HWND hWndDesktop = GetDesktopWindow();&lt;br /&gt;SetForegroundWindow((HWND)(((ULONG) hWndDesktop) | 0x01) );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The first line of code retrieves the "desktop" window handle (the Today screen) and in the second you set it to the foreground. Easy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6240019152442037878?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6240019152442037878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6240019152442037878' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6240019152442037878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6240019152442037878'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/10/howto-show-today-or-home-screen.html' title='HOWTO: Show the Today or Home screen'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5551951370759061548</id><published>2009-10-19T19:42:00.003+01:00</published><updated>2009-10-19T22:07:57.934+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GDI'/><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>The Hold Gesture</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_AksH5-lumMs/StzSyLNW5YI/AAAAAAAAAdQ/uukr2p-hLXU/s1600-h/HoldSample.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 240px; height: 320px;" src="http://1.bp.blogspot.com/_AksH5-lumMs/StzSyLNW5YI/AAAAAAAAAdQ/uukr2p-hLXU/s320/HoldSample.png" alt="" id="BLOGGER_PHOTO_ID_5394418213127120258" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;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 &lt;span style="font-family:courier new;"&gt;CTouchGesture&lt;/span&gt; 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.&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-family: courier new;"&gt;HitTest&lt;/span&gt; function. Note that when the toolbar is displayed you can still flick and click because the item merely changed its size.&lt;br /&gt;&lt;br /&gt;Here is the sample app: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/AppStart05.zip"&gt;AppStart05.zip&lt;/a&gt; (268 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5551951370759061548?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5551951370759061548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5551951370759061548' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5551951370759061548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5551951370759061548'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/10/hold-gesture.html' title='The Hold Gesture'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_AksH5-lumMs/StzSyLNW5YI/AAAAAAAAAdQ/uukr2p-hLXU/s72-c/HoldSample.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5067795664940223172</id><published>2009-10-18T16:48:00.001+01:00</published><updated>2009-10-18T16:49:57.428+01:00</updated><title type='text'>Ooops!</title><content type='html'>Please discard the AppStart03.zip file as the project contains a bug. The corrected version is here: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/AppStart04.zip"&gt;AppStart04.zip&lt;/a&gt; (169 KB).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5067795664940223172?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5067795664940223172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5067795664940223172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5067795664940223172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5067795664940223172'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/10/ooops.html' title='Ooops!'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2874526891946575983</id><published>2009-10-18T11:37:00.002+01:00</published><updated>2009-10-18T12:02:37.906+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Minor touch improvements</title><content type='html'>In this blog post I'm returning to the touch window code to show you a couple of improvements that were needed.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;To solve the first issue I changed the bulk of the code in the &lt;span style="font-family: courier new;"&gt;CTouchGesture&lt;/span&gt; class and turned it into a state machine with four inputs:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Press - The user pressed the finger / stylus&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Move - The user is dragging the finger / stylus&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Release - The user released the finger / stylus&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Timer - Called every 200 ms in order to check transient conditions&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Each input is implemented by a method with the same name and the novelty here is that each of the first three returns a value of &lt;span style="font-family: courier new;"&gt;GestureType&lt;/span&gt; (&lt;span style="font-family: courier new;"&gt;NoGesture&lt;/span&gt;, &lt;span style="font-family: courier new;"&gt;ClickGesture&lt;/span&gt;, &lt;span style="font-family: courier new;"&gt;FlickGesture&lt;/span&gt;). The return type is used by the &lt;span style="font-family: courier new;"&gt;CTouchWindow&lt;/span&gt; mouse event handlers to determine what to do (nothing, a click or a flick). When flicking through the list, the &lt;span style="font-family: courier new;"&gt;CTouchGesture&lt;/span&gt; returns the delta movement through the new &lt;span style="font-family: courier new;"&gt;GetDelta&lt;/span&gt; function.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;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.&lt;/li&gt;&lt;li&gt;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).&lt;/li&gt;&lt;/ul&gt;Finally, I changed the code a little bit so that it does not allow the list to be in an "unnatural" position. Whenever the list stops it is checked for such a situation (showing the canvas to the top or bottom when the list is larger than the window). When such a situation is detected, the list is automatically scrolled back into position.&lt;br /&gt;&lt;br /&gt;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...):&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/AppStart03.zip"&gt;AppStart03.zip&lt;/a&gt; (166 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2874526891946575983?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2874526891946575983/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2874526891946575983' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2874526891946575983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2874526891946575983'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/10/minor-touch-improvements.html' title='Minor touch improvements'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-1949707316962089600</id><published>2009-10-11T18:56:00.003+01:00</published><updated>2009-10-11T20:40:42.346+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>It's not a bug...</title><content type='html'>... it's a feature! Really! I'm talking about my &lt;a href="http://nativemobile.blogspot.com/2009/10/command-parameter-handling.html"&gt;last post&lt;/a&gt; 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-family:courier new;"&gt;SetParam&lt;/span&gt; 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).&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Incidentally, the &lt;span style="font-style: italic;"&gt;real&lt;/span&gt; bug was on the &lt;span style="font-family:courier new;"&gt;CCommand::BindParameters&lt;/span&gt; method where the &lt;span style="font-family:courier new;"&gt;m_pBuffer&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;m_pBindStatus&lt;/span&gt; arrays are allocated. These must be freed if non null before allocation.&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/BigParams.zip"&gt;BigParams.zip&lt;/a&gt; (789 KB)&lt;br /&gt;&lt;br /&gt;Note that the sample application expects both the sdf and jpg files on the &lt;span style="font-weight: bold;"&gt;\Storage Card\Temp&lt;/span&gt; directory. You can change this by editing the &lt;span style="font-family:courier new;"&gt;BigParamsFrame.cpp&lt;/span&gt; file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-1949707316962089600?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/1949707316962089600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=1949707316962089600' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1949707316962089600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1949707316962089600'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/10/its-not-bug.html' title='It&apos;s not a bug...'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6325454010197936523</id><published>2009-10-08T10:36:00.002+01:00</published><updated>2009-10-08T22:38:44.464+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Command Parameter Handling</title><content type='html'>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 &lt;span style="font-family: courier new;"&gt;CCommand::CreateParameter&lt;/span&gt; method you will see the error:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ULONG nParamSize = bIsLong ? 1024 : pParamInfo-&gt;ulParamSize;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ULONG nParamSize = pParamInfo-&gt;ulParamSize;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Like I said, we must specify all the BLOB parameter sizes before we prepare the command and this means that &lt;span style="font-family: courier new;"&gt;CCommand::Prepare&lt;/span&gt; must also change. Instead of getting parameter information in the call to &lt;span style="font-family: courier new;"&gt;Prepare&lt;/span&gt;, 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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6325454010197936523?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6325454010197936523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6325454010197936523' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6325454010197936523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6325454010197936523'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/10/command-parameter-handling.html' title='Command Parameter Handling'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6822861309472838002</id><published>2009-09-28T09:07:00.002+01:00</published><updated>2009-09-28T09:28:07.197+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Improvements</title><content type='html'>After reading Vincent's comment on my last post, I took a second look at the scrolling code and scuttled the &lt;span style="font-family: courier new;"&gt;InvalidateRect&lt;/span&gt; scrolling mechanism. The fact is that while on some older devices this did work in an acceptable fashion, it did not work that well on more recent models and you can actually see some "bumps" in the scrolling speed. The code now uses a timer (again) but instead of indirectly painting the window through the &lt;span style="font-family: courier new;"&gt;InvalidateRect&lt;/span&gt; / &lt;span style="font-family: courier new;"&gt;UpdateWindow&lt;/span&gt; calls, it now directly invokes the painting function. The result is a very smooth scroll on all devices I have tested the code with.&lt;br /&gt;&lt;br /&gt;I also changed the way the &lt;span style="font-family: courier new;"&gt;ScrollLeft&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;ScrollRight&lt;/span&gt; view transitions work. Instead of painting the bitmap at full speed, I added a very small sleep period to each iteration so that each transition is performed in approximately 250 milliseconds. The first paint operation is timed and a per-iteration sleep period is calculated so that the whole process takes the quarter-second period to unfold. With this improvement, you will be able to see the view transition on all devices (especially the ones with a faster CPU and QVGA screen).&lt;br /&gt;&lt;br /&gt;Finally, I decided to add a couple of new view transitions: Fade and Explode / Implode. The first transition uses the &lt;span style="font-family: courier new;"&gt;AlphaBlend&lt;/span&gt; API function to fade from the existing view to the new view (like in a Power Point presentation). I have to say that this is not a very compelling transition, but inspired me to write the second. The Explode / Implode view transition also tries to mimic one of the most famous iPhone view transitions (when you launch an application). The existing view is zoomed in while the new view fades in while also zooming in from half its original size. The Implode effect does the reverse. The result was a bit disappointing because &lt;span style="font-family: courier new;"&gt;AlphaBlend&lt;/span&gt; operation seems to be very greedy (you can replace it by a simple &lt;span style="font-family: courier new;"&gt;StretchBlt&lt;/span&gt; and compare the results). The GDI is not very good at this stuff, unfortunately...&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/CrypSafe06.zip"&gt;CrypSafe06.zip&lt;/a&gt; (323KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6822861309472838002?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6822861309472838002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6822861309472838002' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6822861309472838002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6822861309472838002'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/09/improvements.html' title='Improvements'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-1510112541254455049</id><published>2009-09-20T19:03:00.003+01:00</published><updated>2009-09-20T21:37:13.071+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>View transitions</title><content type='html'>Now that I managed to get some decent finger feedback from the list, it's time to get back to the CrypSafe prototype and add some view transitions. The code I'm using is based on an article I published last year on CodeProject: &lt;a href="http://www.codeproject.com/KB/mobile/SlideView.aspx"&gt;Animating View Transitions on Windows Mobile&lt;/a&gt;. Please read it before continuing as what you will see here is an extension of what I wrote there.&lt;br /&gt;&lt;br /&gt;Essentially this article explored the ability to do some fashionable (read iPhone-like) view transitions using child views implemented as regular Win32 controls (such as a tree view, a list view or even a dialog). The view transitions were implemented using a very simple mechanism:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Capture the existing view as a bitmap;&lt;/li&gt;&lt;li&gt;Remove the from the frame container;&lt;/li&gt;&lt;li&gt;Paint the view bitmap on the frame client area;&lt;/li&gt;&lt;li&gt;Create the new child view window off screen;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Enter a loop where the bitmap is scrolled to the requested direction a few pixels;&lt;/li&gt;&lt;li&gt;Every time the bitmap is scrolled, move the new child window to the contiguous position thus creating the illusion that both windows are moving in lockstep.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;That was a bit crude but worked. One of the lessons I learned from writing this article is that, generally, you cannot force an arbitrary window to paint itself to a memory DC. This would be very useful for some advanced visual effects. By reading the docs you might even be tempted (as I was) to send a &lt;span style="font-family:courier new;"&gt;WM_PAINT&lt;/span&gt; message to the hidden window with your memory DC in the &lt;span style="font-family:courier new;"&gt;WPARAM&lt;/span&gt; and expect it to paint there, but that just doesn't work for all windows. That's why I had to use &lt;span style="font-family:courier new;"&gt;MoveWindow&lt;/span&gt; for the animation.&lt;br /&gt;&lt;br /&gt;Now that we are rendering the touch windows and lists directly on a memory DC, there is a better chance to improve on the original algorithm and implement a smoother view transition algorithm. This is what you will find in the sample code (see below).&lt;br /&gt;&lt;br /&gt;The major change I made to the code was to &lt;span style="font-family:courier new;"&gt;CChildViewBase&lt;/span&gt; where you can now see a &lt;span style="font-family:courier new;"&gt;GetBitmap&lt;/span&gt; virtual method. If this method returns &lt;span style="font-family:courier new;"&gt;NULL&lt;/span&gt;, then the child view is not able to render itself on a bitmap and the old brute-force method will be used. If, on the other hand, the child view is able to render itself to a bitmap it must do so here. Note how this is implemented in the &lt;span style="font-family:courier new;"&gt;CCrypSafeView&lt;/span&gt; class: the painting engine is called directly and a new &lt;span style="font-family:courier new;"&gt;HBITMAP&lt;/span&gt; is returned for the child view manager to paint.&lt;br /&gt;&lt;br /&gt;The results are here for you to see: acceptable on some devices, way too fast on others and slower on older devices. What we need to do here is quite simple: use the same kinematics equations to control the view transition motion and leave nothing to chance.&lt;br /&gt;&lt;br /&gt;Comments and suggestions are welcome!&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/CrypSafe05.zip"&gt;CrypSafe05.zip&lt;/a&gt; (349 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-1510112541254455049?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/1510112541254455049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=1510112541254455049' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1510112541254455049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1510112541254455049'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/09/view-transitions.html' title='View transitions'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4982487089632574575</id><published>2009-09-15T22:17:00.004+01:00</published><updated>2009-09-15T22:28:55.496+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Feedback</title><content type='html'>I just received a very nice email from one of you (you know who you are) reporting a bug in the OLE DB Client library, more specifically on the &lt;span style="font-family: courier new;"&gt;CDbValueRef&lt;/span&gt; class (file&lt;span style="font-family: courier new;"&gt; DbValue.cpp&lt;/span&gt;, line 758). The line must read:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;*m_pLength = nStrLen * sizeof(wchar_t);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The original code did not multiply the string size with the Unicode character size, so you got a wrong byte count and a bug.&lt;br /&gt;&lt;br /&gt;It's always very rewarding to receive emails with correction and suggestions from you (it means someone is reading this... - hehe). Thank you for all the feedback!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4982487089632574575?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4982487089632574575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4982487089632574575' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4982487089632574575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4982487089632574575'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/09/feedback.html' title='Feedback'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-261985284543170608</id><published>2009-09-13T19:56:00.002+01:00</published><updated>2009-09-13T22:11:55.622+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Better touch</title><content type='html'>My professional life changed quite a bit recently and that's why I have not been posting as frequently as usual. I finally seem to have reached some balance and now's the time to resume my blog work.&lt;br /&gt;&lt;br /&gt;One of the faults I found in the last version of the published code concerned finger sensitivity. This is a real issue in touch screens based on resistive technology (see a discussion about this topic on &lt;a href="http://blogs.msdn.com/marcpe/archive/2009/06/29/let-s-talk-about-touch-part1.aspx"&gt;Marcus Perryman's blog&lt;/a&gt;). The bottom line is simple: resistive screens were made for a stylus, not for your finger. They are much more precise than capacitive screens (like the one found on the iPod Touch and iPhone), but require pressure. Capacitive screens are less precise but require only a very soft finger contact in order to operate. Resistive screens expect a very small pressure area (the tip of a stylus). An adult index finger uses up a very large area on the touch screen and the net result is noise and erratic motion messages.&lt;br /&gt;&lt;br /&gt;You can see this in the last sample code I published: flick the list and then click it. It should stop the list but it doesn't (that's how it works on my HTC Touch Pro). What happens is that a single finger press is interpreted by the highly sensitive resistive screen as a sequence of one &lt;span style="font-family: courier new;"&gt;WM_LBUTTONDOWN&lt;/span&gt; message, a couple of &lt;span style="font-family: courier new;"&gt;WM_MOUSEMOVE&lt;/span&gt; messages and the final &lt;span style="font-family: courier new;"&gt;WM_LBUTTONUP&lt;/span&gt;. Inspecting the &lt;span style="font-family: courier new;"&gt;LPARAM&lt;/span&gt; parameter you will see that the &lt;span style="font-family: courier new;"&gt;POINT&lt;/span&gt; structure shows some fluctuations on the &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;y&lt;/span&gt; coordinates. This means that a single finger press is actually equivalent to a small doodle drawn with your stylus. You will be lucky if the first and last &lt;span style="font-family: courier new;"&gt;POINT&lt;/span&gt; values are the same (they almost never are).&lt;br /&gt;&lt;br /&gt;To mitigate this issue and provide better (more reliable) finger action feedback I made some adjustments to the code. The first thing I realized is that one of the sources of "position noise" was the first &lt;span style="font-family: courier new;"&gt;WM_MOUSEMOVE&lt;/span&gt; message. The offset between the &lt;span style="font-family: courier new;"&gt;WM_LBUTTONDOWN&lt;/span&gt; position and the first &lt;span style="font-family: courier new;"&gt;WM_MOUSEMOVE&lt;/span&gt; message seems to provide more variance than the offset to the second &lt;span style="font-family: courier new;"&gt;WM_MOUSEMOVE&lt;/span&gt;. To even things out a little bit I now discard the first offset and start calculating the gesture from the first &lt;span style="font-family: courier new;"&gt;WM_MOUSEMOVE&lt;/span&gt; message. Also, I brought back the concept of sensitivity to filter out smaller movements. Finally take a look at the code in &lt;span style="font-family: courier new;"&gt;CTouchGesture::Move&lt;/span&gt; method. Instead of calculating the move offset in a single &lt;span style="font-family: courier new;"&gt;if&lt;/span&gt; clause, I split the code into two, one for the vertical motion and the other for the horizontal motion.&lt;br /&gt;&lt;br /&gt;The final result feels a bit better and more reliable on all the machines I have tested the code with, but the final word is yours.&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/AppStart02.zip"&gt;AppStart02.zip&lt;/a&gt; (164 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-261985284543170608?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/261985284543170608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=261985284543170608' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/261985284543170608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/261985284543170608'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/09/better-touch.html' title='Better touch'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-427477199583065266</id><published>2009-09-10T11:20:00.005+01:00</published><updated>2009-09-10T11:22:26.389+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Accelerometer'/><title type='text'>Shaken, not stirred...</title><content type='html'>The September 2009 issue of MSDN Magazine presents us with a &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee413721.aspx"&gt;very nice article&lt;/a&gt; on how to detect shaking with the HTC accelerometer. Note that the article is for managed developers, but that should be no problem for you...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-427477199583065266?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/427477199583065266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=427477199583065266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/427477199583065266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/427477199583065266'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/09/shaken-not-stirred.html' title='Shaken, not stirred...'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4352773616309578833</id><published>2009-08-25T10:02:00.003+01:00</published><updated>2009-08-25T10:43:21.210+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Touch Improvements</title><content type='html'>The last version of the touch window and touch lists still needed improvements, notably on scrolling smoothness and clicking accuracy. In this post I'm presenting new versions of both classes where I tried to address these issues. The bottom line is that clicking feels much better but scrolling is still a bit jagged. I have to say that in order to get a game-like smooth screen scrolling one would have to choose something like DirectDraw because GDI was not made for this. Anyway, you will be the judge.&lt;br /&gt;&lt;br /&gt;First I changed how the window scrolls by removing the timer. How do you force the window to scroll without a timer? Well, it's kind of easy: set up a scrolling mechanism that determines the next position based on the current time (I showed how to do that with the kinematic equations), set up a cutoff point (time and / or position) and just invalidate the whole window after painting. If you just invalidate the window, you allow all other messages to be processed and when the message queue is empty, the OS will send you a &lt;span style="font-family:courier new;"&gt;WM_PAINT&lt;/span&gt; message. If the window is still scrolling, you calculate the new position (based on the current time), paint the window and if the motion has not stopped, you invalidate the window again. This way you get a more natural way of scrolling the window and you know that you will get the best screen update frequency that GDI can muster. Note that in order to implement this in a generic way, I had to implement the &lt;span style="font-family:courier new;"&gt;OnPaint&lt;/span&gt; handler in &lt;span style="font-family:courier new;"&gt;CTouchWindow&lt;/span&gt;. This class delegates to its children through the "static virtual" &lt;span style="font-family:courier new;"&gt;Paint&lt;/span&gt; method.&lt;br /&gt;&lt;br /&gt;In this process I had to update the way the kinematic equations are calculated due to some rounding errors I found on QVGA devices. To solve the issue, I changed the main equation back to the more classical form but reduced the timer precision from millisecond to hundredths of a second (divided by 10 in order to get smaller number from multiplication). The rounding error seems to be gone. I have also added a double criteria to test if the motion did end: now the code tests for both time limit and end point.&lt;br /&gt;&lt;br /&gt;To help with both scrolling and clicking, I added a new class named &lt;span style="font-family:courier new;"&gt;CTouchGesture&lt;/span&gt; that essentially handles all the data coming from the stylus (mouse) messages and helps &lt;span style="font-family:courier new;"&gt;CTouchWindow&lt;/span&gt; determine if the last gesture was a click or a "flick". Note that for flicking, the class adds up all the partial moves (compensating for changes in direction) and reports an "average" flick speed (total displacement and time) instead of the last move.&lt;br /&gt;&lt;br /&gt;Clicking the items is now a bit more reliable because the code tests for clicking eligibility. If the window is moving and you click it, there will not be an &lt;span style="font-family:courier new;"&gt;OnClick&lt;/span&gt; call: you will only get one if the window is still to begin with.&lt;br /&gt;&lt;br /&gt;I hope that these modifications did improve the code and the user experience, but with my limited assortment of devices I cannot have a good judgment on  that. So please tell me what you think!&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/AppStart01.zip"&gt;AppStart01.zip&lt;/a&gt; (161 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4352773616309578833?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4352773616309578833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4352773616309578833' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4352773616309578833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4352773616309578833'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/08/touch-improvements.html' title='Touch Improvements'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5713688092915798107</id><published>2009-08-19T16:03:00.004+01:00</published><updated>2009-08-19T16:22:06.289+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='Shell'/><title type='text'>A simple application launcher</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_AksH5-lumMs/SowVAlmDq7I/AAAAAAAAAdI/2Q0oETRp4uU/s1600-h/AppLaunch00.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 240px; height: 320px;" src="http://4.bp.blogspot.com/_AksH5-lumMs/SowVAlmDq7I/AAAAAAAAAdI/2Q0oETRp4uU/s320/AppLaunch00.png" alt="" id="BLOGGER_PHOTO_ID_5371691555382078386" border="0" /&gt;&lt;/a&gt;As I promised on my last post, here is the code for a very simple application launcher. It essentially lists all the applications registered in the "Programs" folder of your Windows Mobile device and launches them when the user clicks the corresponding list item.&lt;br /&gt;&lt;br /&gt;I have to confess that I went into a bit of an ordeal in order to implement this very simple application. Quite simply because I tried to outsmart the Windows Mobile shell and to collect all the required information from the .lnk files. If you are on this same path, please read these words carefully: all has been done for you already, so don't try to reinvent the wheel.&lt;br /&gt;&lt;br /&gt;My first pain was to get the icons from the shortcuts. You can almost do this by using &lt;span style="font-family:courier new;"&gt;ExtractIconEx&lt;/span&gt;, but this function will not work for some of the system DLLs, such as &lt;span style="font-family:courier new;"&gt;ceshell.dll&lt;/span&gt;. Why? I really don't know why, but the "Search" application icon (the magnifying glass) is impossible to get to by using this function. After asking around a bit, I was steered to the right direction by &lt;a href="http://www.christec.co.nz/"&gt;Christopher Fairbairn&lt;/a&gt;: use &lt;a href="http://msdn.microsoft.com/en-us/library/aa453700.aspx"&gt;&lt;span style="font-family:courier new;"&gt;SHGetFileInfo&lt;/span&gt;&lt;/a&gt;. The only caveat is that you must use this function against the .lnk file itself, not against the target. If you do so, your icons will show up just right as you can see from the image.&lt;br /&gt;&lt;br /&gt;The item name is taken from the shortcut file name - just remove the extension and the path. To make this easier I creted a very simple class named &lt;span style="font-family:courier new;"&gt;CFilePath&lt;/span&gt; that, for the time being, contains only one function: &lt;span style="font-family:courier new;"&gt;GetFileNameWithoutExtension&lt;/span&gt; (now where have I seen a similar function name?).&lt;br /&gt;&lt;br /&gt;Finally, in order to execute the application, you just send the full .lnk file name to the &lt;a href="http://msdn.microsoft.com/en-us/library/aa453684.aspx"&gt;&lt;span style="font-family:courier new;"&gt;ShellExecuteEx&lt;/span&gt;&lt;/a&gt; function and you are done with it. No need to mess around with the .lnk file format and all of its quirks.&lt;br /&gt;&lt;br /&gt;For your viewing pleasure, here is the sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/AppStart00.zip"&gt;AppStart00.zip&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5713688092915798107?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5713688092915798107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5713688092915798107' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5713688092915798107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5713688092915798107'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/08/simple-application-launcher.html' title='A simple application launcher'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_AksH5-lumMs/SowVAlmDq7I/AAAAAAAAAdI/2Q0oETRp4uU/s72-c/AppLaunch00.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-8959599560180107114</id><published>2009-08-17T12:06:00.003+01:00</published><updated>2009-08-17T12:27:09.326+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='Shell'/><title type='text'>Shell Shortcuts</title><content type='html'>Windows Mobile shell shortcuts have a very simple file format, something like (taken from my HTC Touch Pro):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;22#:MSPIMG?pimgres.dll,-101&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The number &lt;span style="font-family:courier new;"&gt;22&lt;/span&gt; is supposed to tell us how many characters there are in the string, but this example seems to be wrong. Incidentally, I have seen examples where this value is zero so apparently you can forget about it.&lt;br /&gt;&lt;br /&gt;After the &lt;span style="font-family:courier new;"&gt;#&lt;/span&gt; character, you can read the associated command. In this case, you get a "shell macro" that needs to be expanded using a technique that I explained on my &lt;a href="http://nativemobile.blogspot.com/2009/08/default-windows-mobile-applications.html"&gt;previous post&lt;/a&gt;. After the &lt;span style="font-family:courier new;"&gt;?&lt;/span&gt; character there is a module name where the display icon can be found. This section is optional as well as the final section after the comma: the display icon identifier. The negative value means that this is an icon ID and you should be able to feed it directly to the &lt;a href="http://msdn.microsoft.com/en-us/library/aa922154.aspx"&gt;&lt;span style="font-family:courier new;"&gt;ExtractIconEx&lt;/span&gt;&lt;/a&gt; API to get the icon handle.&lt;br /&gt;&lt;br /&gt;One of the interesting things I've found while doing some research on these files is that you can add a comment section to the beginning of the file, something like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;;Pictures &amp;amp; Videos&lt;br /&gt;22#:MSPIMG?pimgres.dll,-101&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Interesting, huh?&lt;br /&gt;&lt;br /&gt;I'm putting together a very simple application launcher that uses this knowledge to read from the Program Files directory all the existing shell shortcuts and displays them on a touch list with the right icon and name. This will be published on my next post, so stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-8959599560180107114?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/8959599560180107114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=8959599560180107114' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8959599560180107114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8959599560180107114'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/08/shell-shortcuts.html' title='Shell Shortcuts'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5979828026713184315</id><published>2009-08-12T16:09:00.003+01:00</published><updated>2009-08-12T16:33:22.399+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Default Windows Mobile Applications</title><content type='html'>How do you start the default Windows Mobile applications like Calendar, Contacts or Messaging from your application? I recently came across this question in the &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/vssmartdevicesnative/threads"&gt;Visual Studio Smart Device Development - Native C++ Project&lt;/a&gt; (quite a long name, huh?) MSDN forum. The answer is quite simple and relies on a registry entry that has been around at least since Windows Mobile 2003:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Rai&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here you find a list of varying size containing all the default applications in your machine (both a human-readable name and the required command line). For instance, on my HTC Touch Pro the calendar is stored in the following entry:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Rai\:MSCALENDAR&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The application's human-readable name is stored in the "&lt;span style="font-family: courier new;"&gt;0&lt;/span&gt;" (zero) key while the command line is stored in the "&lt;span style="font-family: courier new;"&gt;1&lt;/span&gt;" key. If you look up this in your device's registry you will probably find something like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;:MSPOUTLOOK calendar&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note that this requires further expansion by looking up the following entry:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Rai\:MSPOUTLOOK&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The value of the "&lt;span style="font-family: courier new;"&gt;1&lt;/span&gt;" key contains &lt;span style="font-family: courier new;"&gt;"poutlook.exe&lt;/span&gt;" so the final command line to start the Calendar application must be "&lt;span style="font-family: courier new;"&gt;poutlook.exe calendar&lt;/span&gt;".  Easy huh?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5979828026713184315?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5979828026713184315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5979828026713184315' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5979828026713184315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5979828026713184315'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/08/default-windows-mobile-applications.html' title='Default Windows Mobile Applications'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5591995386223002010</id><published>2009-08-10T16:57:00.003+01:00</published><updated>2009-08-10T17:22:45.328+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Item Activation</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_AksH5-lumMs/SoBFWF1rubI/AAAAAAAAAdA/iL4jcrmVFRA/s1600-h/CrypSafe02.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 240px; height: 320px;" src="http://2.bp.blogspot.com/_AksH5-lumMs/SoBFWF1rubI/AAAAAAAAAdA/iL4jcrmVFRA/s320/CrypSafe02.png" alt="" id="BLOGGER_PHOTO_ID_5368367001652410802" border="0" /&gt;&lt;/a&gt;I'm still not sure how this is going to end, but right now items can be focused, selected and activated. An item gets the focus when you use the arrow keys to navigate the list and that is meant to mean the "current" item in the list. When you select an item it gets added to a selection list (in case you need to use multiple-selection lists). Note that focus does not mean selection nor selection means focus. Finally, an activated item is the one you just "pressed" or clicked.&lt;br /&gt;&lt;br /&gt;The code I'm publishing today shows how to set the focus on a particular item (just added a highlighter to the &lt;span style="font-family: courier new;"&gt;DrawItem&lt;/span&gt; method) by navigating the list with the arrow keys and how it can be activated by directly clicking it or by pressing the enter key on the focused item.&lt;br /&gt;&lt;br /&gt;I had to make some changes to the &lt;span style="font-family: courier new;"&gt;CTouchWindow&lt;/span&gt; class template in order to make sure that scrolling (or flicking through) the list does not get confused with a click. If you hook the application with &lt;span style="font-weight: bold;"&gt;Remote Spy&lt;/span&gt; you will see an interesting pattern of messages when clicking an item: &lt;span style="font-family: courier new;"&gt;WM_LBUTTONDOWN&lt;/span&gt;, &lt;span style="font-family: courier new;"&gt;WM_MOUSEMOVE&lt;/span&gt; (may occur more than once) and &lt;span style="font-family: courier new;"&gt;WM_LBUTTONUP&lt;/span&gt;. What's interesting is that the "mouse move" message always shows up even if it reports the same screen position as the "button down" message. Is this a bug, Microsoft? Anyway, the code already handles null movements so...&lt;br /&gt;&lt;br /&gt;When an item is selected, the &lt;span style="font-family: courier new;"&gt;CCrypSafeView::OnItemChangedState&lt;/span&gt; method is called by the base class and to handle the item activation you must handle the &lt;span style="font-family: courier new;"&gt;TLN_ITEMACTIVATED&lt;/span&gt; code. Just take a look at the sample code to see how it is done. Note that you test &lt;span style="font-family: courier new;"&gt;nmtl.dwState&lt;/span&gt; for nonzero meaning activation - it is zero when the item is "deactivated".&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/CrypSafe04.zip"&gt;CrypSafe04.zip&lt;/a&gt; (325 KB - now includes the OleDbClient lib)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5591995386223002010?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5591995386223002010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5591995386223002010' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5591995386223002010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5591995386223002010'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/08/item-activation.html' title='Item Activation'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_AksH5-lumMs/SoBFWF1rubI/AAAAAAAAAdA/iL4jcrmVFRA/s72-c/CrypSafe02.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2847386222773221970</id><published>2009-08-03T09:41:00.002+01:00</published><updated>2009-08-03T10:44:20.065+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><title type='text'>Compiling CrypSafe</title><content type='html'>Back from the sunny Algarve and ready for more work. I have to confess that during these last two weeks I barely touched my laptop, but I surely needed the rest.&lt;br /&gt;&lt;br /&gt;Compiling the CrypSafe prototype has proven to be a bit of a challenge for some of the readers and I have received some complaints about this very subject. Here is a list of what you need to do, both with VS 2005 and VS 2008 to get the sample to compile. Please note that I'm distributing the VS 2008 solution files only but you should be able to recreate the project for VS 2005 without major issues.&lt;br /&gt;&lt;br /&gt;Here's what you must do to compile the sample:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download WTL 8.0 or 8.1. You can get the latest version of WTL from its &lt;a href="http://sourceforge.net/projects/wtl/files/"&gt;sourceforge page&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Unzip the WTL distribution file to a directory of your choice.&lt;/li&gt;&lt;li&gt;Under the installation directory, you will find some directories named AppWiz, AppWizCE and AppWizMobile. Navigate to each of these in turn and run the &lt;span style="font-family: courier new;"&gt;setup90.js&lt;/span&gt; (for Visual Studio 2008) and/or &lt;span style="font-family: courier new;"&gt;setup80.js&lt;/span&gt; (for Visual Studio 2005) scripts in order to install the Visual Studio application wizards. Please note that under Vista (and probably also under Windows 7) you must open a command prompt with elevated privileges because these scripts write files to the Visual Studio install directories.&lt;/li&gt;&lt;li&gt;Now you have to open Visual Studio and let it know where to find the WTL include files. To do this, open Visual Studio and go to the Tools / Options menu and select "Projects and Solutions" item in the tree. Select the "VC++ Directories" under that item and then select the "Include files" option of the "Show directories for:" combo box. Now, for each platform listed on the left combo box, you must enter your WTL include directory in the list below.&lt;/li&gt;&lt;li&gt;Now you can open the CrypSafe solution in Visual Studio and try to compile it. If it still fails, please make sure you correct each project's "Additional Include Directories" property under the project's Configuration Properties / C++ / General option.&lt;/li&gt;&lt;/ol&gt;If you still find errors while compiling, please let me know through a comment to this post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2847386222773221970?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2847386222773221970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2847386222773221970' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2847386222773221970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2847386222773221970'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/08/compiling-crypsafe.html' title='Compiling CrypSafe'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2532874600686288772</id><published>2009-07-21T16:50:00.002+01:00</published><updated>2009-07-21T16:56:18.712+01:00</updated><title type='text'>And now for something completely different...</title><content type='html'>I just spotted a native code pearl on &lt;a href="http://foro.todopocketpc.com/showthread.php?p=1452603#post1452603"&gt;Todo PocketPC&lt;/a&gt;: &lt;a href="http://code.google.com/p/microfi-nitrogen/"&gt;Nitrogen 1.1&lt;/a&gt; a &lt;span style="font-style: italic;"&gt;native code&lt;/span&gt; media player for Windows Mobile 5. The interesting thing about this application is that it comes with full source code (licensed under the GNU GPL v3). The media player looks very good and I will be giving it a spin (I really don't like any of the media players bundled with my HTC Touch Pro).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2532874600686288772?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2532874600686288772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2532874600686288772' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2532874600686288772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2532874600686288772'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/07/and-now-for-something-completely.html' title='And now for something completely different...'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2599210848777172490</id><published>2009-07-11T18:33:00.003+01:00</published><updated>2009-07-11T19:36:52.938+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Kinematics</title><content type='html'>How do you make the touch list behave like a real physical object? What's the secret behind making the list bounce smoothly back to its original position? How do you decelerate it when you quickly flick through it like if it had some sort of "friction"? In short: how do you make it work like an iPhone list? The answer is simple: &lt;a href="http://www.physicsclassroom.com/class/1DKin/u1l6b.cfm"&gt;kinematics&lt;/a&gt;, the study of motion.&lt;br /&gt;&lt;br /&gt;In this post I'm adding some kinematic effects to the list to make it work like if it had both weight and some "springs" to attach it to the extremes of the window. These "springs" will make the list bounce back when the list is either showing its first or last element and you force it to scroll down or up (respectively). Also, when scrolling through very large lists, you want them to slow down in a realistic fashion, like a real object would.&lt;br /&gt;&lt;br /&gt;There are a lot of changes to the base &lt;span style="font-family: courier new;"&gt;CTouchWindow&lt;/span&gt; class in order to include these kinematic additions. Interestingly, some parts of the code actually became simpler. This base class is used to implement the touch list that only performs vertical scrolling, but it must also accommodate for a possible horizontal scrolling. To make the kinematics implementation easier, I created a helper class named &lt;span style="font-family: courier new;"&gt;CTouchMotion&lt;/span&gt; that is used to calculate the list position as a function of time. You initialize each instance (vertical and horizontal) with the desired acceleration (in pixels per squared second), initial speed (in pixels per second), the initial and final positions of the motion (the final position is redundant, me thinks) and the total motion time. The &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;y&lt;/span&gt; positions of the motion (just &lt;span style="font-style: italic;"&gt;y&lt;/span&gt; for the touch list) are calculated by the &lt;span style="font-family: courier new;"&gt;GetPosition&lt;/span&gt; function that takes the time offset (since the beginning of the motion) as milliseconds. The function just computes the classical &lt;span style="font-style: italic;"&gt;x = 0.5 * a * t * t + vi * t + xi&lt;/span&gt; equation, where &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; is the position for time &lt;span style="font-style: italic;"&gt;t,&lt;/span&gt; &lt;span style="font-style: italic;"&gt;a&lt;/span&gt; is the acceleration, &lt;span style="font-style: italic;"&gt;vi&lt;/span&gt; is the initial speed and &lt;span style="font-style: italic;"&gt;xi&lt;/span&gt; is the initial position. Notice that the function must transform the input in milliseconds to seconds in order to get the appropriate result.  This is a concern because I must perform all calculations using integers to get the best performance possible. If you look at the implementation of the &lt;span style="font-family: courier new;"&gt;GetPosition&lt;/span&gt; function you will see that I calculate the &lt;span style="font-style: italic;"&gt;0.5 * a * t&lt;/span&gt; term first and convert it to a pixels per second speed. Next I add the initial speed, multiply the result by &lt;span style="font-style: italic;"&gt;t&lt;/span&gt; and then convert the result to pixels by dividing by 1000. Finally, &lt;span style="font-style: italic;"&gt;xi&lt;/span&gt; is added and we get the proper result. Also notice how each step is accurately rounded to make sure nothing is lost during conversions.&lt;br /&gt;&lt;br /&gt;While I was debugging this code I found a very interesting bug. Originally, the function was using the time offset as a &lt;span style="font-family: courier new;"&gt;DWORD&lt;/span&gt; (an unsigned value). Occasionally the list would simply disappear while scrolling. The bug was due to the conversions performed between signed and unsigned integers and sometimes they behaved differently from what I expected, and would throw the list origin to very large negative numbers. The problem was solved by casting the time offset to a signed integer.&lt;br /&gt;&lt;br /&gt;You can also see that the function uses a time limit that works as a "break" if you accidentally call it with a time offset larger than the one you specified. Why is this? Simple: the equation is a simple parabola that computes a trajectory until the speed (the first derivative) is zero. This is when the list stops. If you don't limit the motion, you would actually see the list bouncing back with a positive acceleration like when you throw a ball up, and it comes back down. You only want the upward movement - the one where the speed decreases until zero.&lt;br /&gt;&lt;br /&gt;Another big change happened in the way the motion timer is calculated. The previous version used the speed of the last &lt;span style="font-family: courier new;"&gt;WM_MOUSEMOVE&lt;/span&gt; (displacement and time). This concept was discarded and I assumed that the movements would have a set of fixed behaviors:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Bounce-back movements would last 500 milliseconds.&lt;/li&gt;&lt;li&gt;List deceleration would take 2 seconds.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;You can see these calculations in the &lt;span style="font-family: courier new;"&gt;CTouchWindow::SetupMotion&lt;/span&gt; function. This is called when the list is about to move (on the &lt;span style="font-family: courier new;"&gt;WM_LBUTTONUP&lt;/span&gt; handler) and during the timer (&lt;span style="font-family: courier new;"&gt;OnTimer&lt;/span&gt;) function in order to test for boundary conditions. There is something that's still amiss here: when you transition from a scroll to a bounce-back, the initial speed is not being considered so you see a bit of a harsh transition. I will correct this later.&lt;br /&gt;&lt;br /&gt;Finally, and because you can now have an empty space drawn before the list (and also after, but this was already in the previous implementation), I added a fourth color to the list: the canvas color. This is what lies "beneath" the list and helps to convey the notion that the list exists above another surface (thanks for the suggestion, Anatoly).&lt;br /&gt;&lt;br /&gt;The code is not fully cleaned up yet and you will see some more changes to this kinematic code. Meanwhile, here is the project for your perusal:&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/CrypSafe03.zip"&gt;CrypSafe03.zip&lt;/a&gt; (99 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2599210848777172490?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2599210848777172490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2599210848777172490' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2599210848777172490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2599210848777172490'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/07/kinematics.html' title='Kinematics'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-8006624804538380042</id><published>2009-07-09T21:03:00.001+01:00</published><updated>2009-07-09T21:05:00.408+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Windows Mobile 6.5 Gestures documented</title><content type='html'>The documentation for Windows Mobile 6.5 Gestures is now online &lt;a href="http://msdn.microsoft.com/en-us/library/ee220920.aspx"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-8006624804538380042?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/8006624804538380042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=8006624804538380042' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8006624804538380042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8006624804538380042'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/07/windows-mobile-65-gestures-documented.html' title='Windows Mobile 6.5 Gestures documented'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4097104577816719135</id><published>2009-07-09T10:03:00.002+01:00</published><updated>2009-07-09T10:11:13.612+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Bouncing the list</title><content type='html'>While I was preparing the code for the next post, I realized that something really important is missing from the touch list: it does not "bounce". Use the sample I published in the last post and try to move the list. It will not budge. Similar implementations allow you to move the list out of it's stable position (minimal energy position?) and it will move back to where it was. It gives you a nice sense that you are dealing with a physical inertial entity.&lt;br /&gt;&lt;br /&gt;The sample code I'm publishing today just allows for this and simply resets the list to it's stable position without any animation or kinematic feedback. Right now I'm going through some high-school kinematic equations in order to implement some properly accelerated animations to the list. Meanwhile, check the source code here: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/CrypSafe02.zip"&gt;CrypSafe02.zip&lt;/a&gt;. As you can see, the list painting now allows for empty space both &lt;span style="font-style: italic;"&gt;before&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;after&lt;/span&gt; the list so that when you force it down it will not leave garbage at the top.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4097104577816719135?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4097104577816719135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4097104577816719135' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4097104577816719135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4097104577816719135'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/07/bouncing-list.html' title='Bouncing the list'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-8522479627136184095</id><published>2009-06-29T11:33:00.004+01:00</published><updated>2009-06-29T12:35:24.228+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>A better look</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_AksH5-lumMs/SkigHmgEr3I/AAAAAAAAAc4/ZV_d_pCnINs/s1600-h/CrypSafe01.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 240px; height: 320px;" src="http://1.bp.blogspot.com/_AksH5-lumMs/SkigHmgEr3I/AAAAAAAAAc4/ZV_d_pCnINs/s320/CrypSafe01.png" alt="" id="BLOGGER_PHOTO_ID_5352704209584435058" border="0" /&gt;&lt;/a&gt;Here's a better look for the CrypSafe main view. As you can see I'm using  a new font for the item text, added a separation line between the items and painted the background with a different brush for odd-numbered items. The changes to the code are not very dramatic, so let's take a look at them.&lt;br /&gt;&lt;br /&gt;The first change is the new font. To use a new font I generally declare a &lt;span style="font-family: courier new;"&gt;CFont&lt;/span&gt; object on the view class like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;private:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;CFont m_largeFont;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This way I know that the font will exist throughout the life cycle of the containing view. Creating the font itself is always a bit of a pain, but i prefer to use the following method because it does give me full control over what is going on. The following code snippet was taken from the view constructor in &lt;span style="font-family: courier new;"&gt;CCrypSafeView.cpp&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;LOGFONT lf;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;int nLogPixelsY = DRA::LogPixelsY();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfHeight = DRA::HIDPIMulDiv(-12, nLogPixelsY, 72);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfWidth = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfEscapement = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfOrientation = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfWeight = FW_NORMAL;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfItalic = FALSE;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfUnderline = FALSE;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfStrikeOut = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfCharSet = ANSI_CHARSET;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfOutPrecision = OUT_DEFAULT_PRECIS;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfQuality = CLEARTYPE_QUALITY;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;lf.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;_tcscpy(lf.lfFaceName, TEXT("Tahoma"));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;m_largeFont.CreateFontIndirect(&amp;amp;lf);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The code at the top is the most important one because it makes sure that we create the font with the right size in points, independently of the resolution of your device's screen.&lt;br /&gt;&lt;br /&gt;Now that the new font is ready to use, let's see how to use it on the &lt;span style="font-family: courier new;"&gt;DrawItem&lt;/span&gt; method. First, you need to declare an &lt;span style="font-family: courier new;"&gt;HFONT&lt;/span&gt; variable:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;HFONT hFont;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is used to store the DC's currently selected font while we use our custom font. Setting the new font is easy:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;hFont = dc.SelectFont(m_largeFont);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When we are done with the new font, we must set the old DC font back:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;dc.SelectFont(hFont);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To paint the text with a left border, I copied the item &lt;span style="font-family: courier new;"&gt;CRect&lt;/span&gt; to a new instance:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;CRect rcText(rcItem);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Before painting, the left value is adjusted:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;rcText.left += DRA::SCALEX(4);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note that this will correctly scale in higher DPI screens. As you can see from the included image, the even-numbered items have a white background while the odd-numbered ones have a very light gray background. As I explained in the previous post, the client code in &lt;span style="font-family: courier new;"&gt;DrawItem&lt;/span&gt; is supposed to paint the background, and doing it is extremely easy:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;COLORREF rgb(m_rgbBack);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;if(iItem % 2) rgb = RGB(0xf0, 0xf0, 0xf0);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;brush.CreateSolidBrush(rgb);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;dc.FillRect(&amp;amp;rcItem, brush);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family: courier new;"&gt;m_rgbBack&lt;/span&gt; variable is declared by &lt;span style="font-family: courier new;"&gt;CTouchListBase&lt;/span&gt; and contains the default background color (this color is used to fill in the unpainted space at the bottom of the list). If the item has an odd number, I replace the default white with a light gray and use this RGB value to create a brush. Painting the item's background is a simple issue of calling &lt;span style="font-family: courier new;"&gt;FillRect&lt;/span&gt; with the supplied item &lt;span style="font-family: courier new;"&gt;CRect&lt;/span&gt; (&lt;span style="font-family: courier new;"&gt;rcItem&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Now we can paint the item's text making sure that it is painted with a transparent background mode:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;int nBkMode = dc.SetBkMode(TRANSPARENT);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;dc.DrawText(pItem-&gt;GetText(), -1, &amp;amp;rcText, DT_LEFT | DT_VCENTER);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;dc.SetBkMode(nBkMode);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note that the text is painted using the &lt;span style="font-family: courier new;"&gt;rcText&lt;/span&gt; rectangle, not the item's. This way we get the left margin effect. Finally we can print the bottom separation line:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;CPen pen;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;HPEN hPen;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;pen.CreatePen(PS_SOLID, 1, m_rgbLine);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;hPen = dc.SelectPen(pen);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;dc.MoveTo(0, rcItem.bottom - 1);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;dc.LineTo(rcItem.right, rcItem.bottom - 1);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;dc.SelectPen(hPen);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family: courier new;"&gt;m_rgbLine&lt;/span&gt; contains the default color for the separation line (gray). As you can see, this is not rocket sience. Next, I will explore how to add a navigation cursor and key handling.&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/CrypSafe01.zip"&gt;CrypSafe01.zip&lt;/a&gt; (96 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-8522479627136184095?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/8522479627136184095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=8522479627136184095' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8522479627136184095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8522479627136184095'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/06/better-look.html' title='A better look'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_AksH5-lumMs/SkigHmgEr3I/AAAAAAAAAc4/ZV_d_pCnINs/s72-c/CrypSafe01.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-268824423471794977</id><published>2009-06-26T11:51:00.006+01:00</published><updated>2009-06-26T12:44:45.063+01:00</updated><title type='text'>The CrypSafe prototype</title><content type='html'>Today I present the very first iteration of the mobile password safe application. First I decided to name it "CrypSafe". Second, I also decided to post the code in very small increments so that the whole process of using the WM framework becomes clearer (and also to allow me to add changes as I see fit). Third, I'm starting off with a prototype.&lt;br /&gt;&lt;br /&gt;The application architecture is actually very simple (as usual, I'm using WTL 8.0):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A main frame window that contains the content views and any decorations&lt;/li&gt;&lt;li&gt;A category view that shows the information categories in the safe&lt;/li&gt;&lt;li&gt;A detail view showing the individual items in each category&lt;/li&gt;&lt;li&gt;An item editing dialog&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;More items will be added if need arises, but for now I would say that this is enough. When you create a new project using the WTL Mobile Application Wizard, you get a lot of code created for you. In fact, after creating the project you can compile and run (and it will run - just make sure that the WTL include files are reachable for both the C++ and resource compilers). I usually create an SDI application with a child view because it's the most flexible arrangement. You can skip the child view and pain directly on the frame's client area, but this will make it harder for you to use multiple views. Incidentally, the code that flips views does paint on the frame's client area, but that's another story.&lt;br /&gt;&lt;br /&gt;After creating your initial project, our first stop is to change the view window (see the source code):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;class CCrypSafeView : public CTouchList&amp;lt;CCrypSafeView&amp;gt;, public CChildView&amp;lt;CCrypSafeView&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This means that our view will implement both a "touch list" and will also behave like a switchable child view. Next we need to remove the standard painting protocol and replace it with the touch list's:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;virtual void DrawItem(HDC hDC, int iItem, CRect &amp;amp;rcItem);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Yes, we only need this because the list is painted item by item. Remove the &lt;span style="font-family:courier new;"&gt;OnPaint&lt;/span&gt; handler because it is not needed (it's implemented by the base class). I also added a default constructor where I placed the initial list of categories for the prototype:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;CCrypSafeView::CCrypSafeView()&lt;br /&gt;{&lt;br /&gt; AddItem(new CTouchListItem(L"Credit Cards"));&lt;br /&gt; AddItem(new CTouchListItem(L"Debit Cards"));&lt;br /&gt; AddItem(new CTouchListItem(L"Mail Accounts"));&lt;br /&gt; AddItem(new CTouchListItem(L"SIM Cards"));&lt;br /&gt; AddItem(new CTouchListItem(L"User Accounts"));&lt;br /&gt; AddItem(new CTouchListItem(L"Web Sites"));&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Note that these items are not explicitly delete anywhere in the code because their pointers are reference counted (internally). Finally, let's see how to paint the items:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;void CCrypSafeView::DrawItem(HDC hDC, int iItem, CRect &amp;amp;rcItem)&lt;br /&gt;{&lt;br /&gt; CDCHandle  dc(hDC);&lt;br /&gt; PTouchListItem pItem = GetItem(iItem);&lt;br /&gt;&lt;br /&gt; dc.DrawText(pItem-&amp;amp;gtGetText(), -1, &amp;amp;rcItem, DT_LEFT);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Note that the &lt;span style="font-family:courier new;"&gt;PTouchListItem&lt;/span&gt; type is a &lt;span style="font-family:courier new;"&gt;typedef&lt;/span&gt; that denotes the reference-counted version of a pointer to a &lt;span style="font-family:courier new;"&gt;CTouchListItem&lt;/span&gt; object.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_AksH5-lumMs/SkSyNo9iCYI/AAAAAAAAAcw/HW3h131KFX0/s1600-h/CrypSafe00.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 240px; height: 320px;" src="http://3.bp.blogspot.com/_AksH5-lumMs/SkSyNo9iCYI/AAAAAAAAAcw/HW3h131KFX0/s320/CrypSafe00.png" alt="" id="BLOGGER_PHOTO_ID_5351598204626536834" border="0" /&gt;&lt;/a&gt;As you can see from the image, the result is less than satisfactory. The whole list is painted on an off-screen bitmap that is initialized to solid black (hence the black areas of the screen). The bottom of the list is automatically filled with the background color, but not the individual items - you must fill in the background for yourself. We also need to make the item font larger (possibly bold and with ClearType rendering for a better reading experience). As you can see each row has a height of 40 pixels (80 on high DPI machines) in order to accommodate a 32x32 (64x64 on high DPI machines) image. The text will have to be correctly formatted in order to better fill each row.&lt;br /&gt;&lt;br /&gt;For the time being, you can take a peek at the first version of the code &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/CrypSafe00.zip"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;P.S.: Anatoly, I have not included all of your changes yet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-268824423471794977?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/268824423471794977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=268824423471794977' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/268824423471794977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/268824423471794977'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/06/crypsafe-prototype.html' title='The CrypSafe prototype'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_AksH5-lumMs/SkSyNo9iCYI/AAAAAAAAAcw/HW3h131KFX0/s72-c/CrypSafe00.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5500311875467452331</id><published>2009-06-24T12:41:00.002+01:00</published><updated>2009-06-24T12:53:14.089+01:00</updated><title type='text'>Back to native</title><content type='html'>After a few days struggling with the BlackBerry JDK, JDE and Eclipse, it's time to get back to predictability and safe ground. Boy, have I missed Visual Studio!&lt;br /&gt;&lt;br /&gt;Now that I have some readers actively using, criticizing and suggesting improvements to the Windows Mobile native framework (thank you so much, Anatoly!), I think now is the time to start exercising the code with a real application. Contrary to my early plans, I will start with something that I really need on a day-to-day basis: a mobile password safe. Nowadays I struggle to remember all the mobile phone PINs and PUKs, debit and credit card PINs, online service passwords, just to name a few. I know there are some excellent applications out there ready to be purchased, but what's the fun in that? My idea is very simple: use an encrypted SQL Compact database to store all the sensitive data. The user will be able to add, modify and delete both data and structure (each information category will be stored in a different table). The user interface must be very simple:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A main list containing the user's information categories (credit cards, phone PINs...);&lt;/li&gt;&lt;li&gt;A secondary list containing the category details;&lt;/li&gt;&lt;li&gt;A dialog for editing the details&lt;/li&gt;&lt;/ul&gt;So, after committing to this, let me roll my sleeves and head back to VS. On the next post I will start publishing the first version of the code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5500311875467452331?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5500311875467452331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5500311875467452331' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5500311875467452331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5500311875467452331'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/06/back-to-native.html' title='Back to native'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6851302545552506044</id><published>2009-06-15T11:19:00.004+01:00</published><updated>2009-06-15T14:45:48.124+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GPS'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>A simple GPS viewer</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_AksH5-lumMs/SjYgTHbWdBI/AAAAAAAAAco/7xhICIMQcc4/s1600-h/GpsView.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 150px; height: 200px;" src="http://3.bp.blogspot.com/_AksH5-lumMs/SjYgTHbWdBI/AAAAAAAAAco/7xhICIMQcc4/s200/GpsView.png" alt="" id="BLOGGER_PHOTO_ID_5347497120332411922" border="0" /&gt;&lt;/a&gt;Here's a simple GPS viewer application. I wrote it to help me in testing the transition to reference counted pointers in my budding Windows Mobile native (WTL-based) framework. In the process I have learned a few things about reference counted pointers, especially when NOT to use  them.&lt;br /&gt;&lt;br /&gt;One of the changes I made to the way the &lt;span style="font-family:courier new;"&gt;CPropertyListView&lt;/span&gt; class is used is that it contains pointers to items created on the heap and not on the stack. This means that you now have to create items like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;m_pGpsFix = new CPropertyString(L"Fix", L"Unknown");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note that the &lt;span style="font-family:courier new;"&gt;m_pGpsFix&lt;/span&gt; variable is actually a "smart pointer" and you don't have to worry about deleting it in the destructor. Nor does the list, in fact... When each item's reference count reaches zero, the last smart pointer that references the object will delete it (and that's why you &lt;span style="font-style: italic;"&gt;cannot&lt;/span&gt; have stack allocated items). This is when you should use smart pointers, so when should you use simple C++ pointers? I found out the hard way when adding these items to the list. My original (and right) prototype was:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;void CTouchListBase::AddItem(CTouchListItem* pItem)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When I replaced the C++ pointer with a smart one, I immediately lost one of the best features these things have: the ability of a base class pointer to refer to a derived class object. Understanding that I don't know enough about C++ class templates to make this work (not even sure if that's possible - will have to look at Jossutti's book), I decided to fall back to straight C++ pointers. This poses no problem because the method internally will use the smart pointer class constructor to build a new instance using the raw pointer and add it to the underlying array, so the reference counting is respected.&lt;br /&gt;&lt;br /&gt;The sample application just starts the GPSID and displays some data from the GPS on a dialog. As you can see from the ZIP file, there are two additional library projects that make up the framework. Note that these are subject to change and &lt;span style="font-style: italic;"&gt;do have bugs&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/GpsView.zip"&gt;GpsView.zip&lt;/a&gt; (93 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6851302545552506044?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6851302545552506044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6851302545552506044' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6851302545552506044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6851302545552506044'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/06/simple-gps-viewer.html' title='A simple GPS viewer'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_AksH5-lumMs/SjYgTHbWdBI/AAAAAAAAAco/7xhICIMQcc4/s72-c/GpsView.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6346344723067192978</id><published>2009-06-11T14:44:00.005+01:00</published><updated>2009-06-11T14:58:40.732+01:00</updated><title type='text'>unresolved external symbol CLSID_ImagingFactory</title><content type='html'>Just started out a new sample project that illustrates how to use the WM libraries I'm writing, and got the following link errors:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;1&gt;wmfw.lib(Image.obj) : error LNK2001: unresolved external symbol CLSID_ImagingFactory&lt;br /&gt;1&gt;wmfw.lib(Image.obj) : error LNK2001: unresolved external symbol IID_IImagingFactory&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This means that the linker cannot find the symbols &lt;span style="font-family:courier new;"&gt;CLSID_ImagingFactory&lt;/span&gt; and&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;IID_IImagingFactory&lt;/span&gt;, required to use the imaging library on Windows Mobile. If you look at the documentation, you will see that a link to the &lt;span style="font-family:courier new;"&gt;imaging.lib&lt;/span&gt; file is required but it will not work (at least it does not work for me).&lt;br /&gt;&lt;br /&gt;The solution I found is to force the inclusion of these symbols using a dummy file that I usually name &lt;span style="font-family:courier new;"&gt;guids.cpp&lt;/span&gt;. Here's the content:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;#include "stdafx.h"&lt;br /&gt;#include &amp;lt;initguid.h&amp;gt;&lt;initguid.h&gt;&lt;br /&gt;#include &amp;lt;imgguids.h&amp;gt;&lt;imgguids.h&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family:courier new;"&gt;initguid.h&lt;/span&gt; include redefines the &lt;span style="font-family:courier new;"&gt;DEFINE_GUID&lt;/span&gt; macro that is used by &lt;span style="font-family:courier new;"&gt;imgguids.h&lt;/span&gt; so that it declares a &lt;span style="font-family:courier new;"&gt;GUID&lt;/span&gt; along with its value instead of making an external reference to the same symbol.&lt;br /&gt;&lt;br /&gt;Compile and link and the error goes away.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6346344723067192978?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6346344723067192978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6346344723067192978' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6346344723067192978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6346344723067192978'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/06/unresolved-external-symbol.html' title='unresolved external symbol CLSID_ImagingFactory'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4329862772755271583</id><published>2009-06-11T12:00:00.002+01:00</published><updated>2009-06-11T12:02:43.691+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>More native memory in WM 6.x</title><content type='html'>Here's a very interesting blog post from The Windows Mobile RSS: &lt;a href="http://blogs.msdn.com/hegenderfer/archive/2009/06/10/more-memory-for-all-in-wm-6-x.aspx"&gt;More Memory For ALL in WM 6.x&lt;/a&gt;. As you can see, folks at Microsoft still care about us, native mobile developers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4329862772755271583?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4329862772755271583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4329862772755271583' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4329862772755271583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4329862772755271583'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/06/more-native-memory-in-wm-6x.html' title='More native memory in WM 6.x'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5718333903560782743</id><published>2009-06-03T18:13:00.002+01:00</published><updated>2009-06-03T18:16:49.568+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>VS 2010 and Smart Device Development</title><content type='html'>This updated &lt;a href="http://msdn.microsoft.com/en-us/library/sa69he4t(VS.100).aspx"&gt;link&lt;/a&gt; explains it all: Smart Device development is not supported by Visual Studio 2010 Beta 1, but will (somehow) be supported by the final release. Quoting:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"&lt;i&gt;Microsoft is committed to making Visual Studio a great development tool for the mobile device developer, and will deliver mobile device tools for Visual Studio 2010, but cannot share details now. For existing Visual Studio 2008 mobile developers, Microsoft will release a new Windows Mobile 6.5 emulator in the upcoming months that works with the Windows Mobile 6 SDK.&lt;/i&gt;"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, back to work.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5718333903560782743?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5718333903560782743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5718333903560782743' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5718333903560782743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5718333903560782743'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/06/vs-2010-and-smart-device-development.html' title='VS 2010 and Smart Device Development'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-3269206937600176794</id><published>2009-05-30T15:49:00.005+01:00</published><updated>2009-05-30T16:47:27.540+01:00</updated><title type='text'>Is Native Code Hard?</title><content type='html'>If you read this blog then probably your answer is, like mine, no. So what's the difference between native and managed that makes people avoid native code like the plague? What makes people not want to come back? In my opinion there are a few reasons, especially for Windows Mobile native code:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Lack of tools - just try to write a C# application using notepad and the command line compiler and you will see how much tools make a managed developer life easy. There is no comparable level of tool support for native code developers, and this may be linked to the next point.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Lack of comprehensive and cohesive libraries and frameworks - the Win32 API is way too low-level for most uses. It's very nice to be able to use it directly without paying the P/Invoke price, but this comes at a cost of having to write dozens of lines of code to achieve a very simple outcome. The OLE DB and MAPI COM interfaces are a perfect example of this - way too complex to use as they are offered. Just compare the "stock" OLE DB samples with the OLE DB Client library I published here...&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Memory management - this is a minor issue for small applications but when the scale starts to grow it becomes a headache. When are you supposed to delete that object? Is it safe to do it now? Are there other objects referring to it?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I have recently been confronted with the memory management issue in a relatively complex application when I found myself wanting to have the memory management of a particular set of objects to be done automatically. These objects are referred to by an arbitrary number of other objects and determining when their life cycle ended was becoming more and more difficult, especially because they were being referred to by different threads.&lt;br /&gt;&lt;br /&gt;There are two basic approaches to automatic memory management that have been used for quite a long time:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Reference counting - The iPhone uses a reference counting mechanism to determine when a given object can be removed from memory. The price you pay for this type of memory management is that you have to remember to increment and decrement the memory reference counts. Failing to do this will result in memory leaks. The iPhone uses an optional "autorelease pool" object that kind of protects you from this.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Garbage collection - The Java and .NET platforms both use garbage collection to reclaim the memory of objects that are no longer active. The price you pay for this is that the GC has a mind of its own and stops your code in order to clean up the mess. On mobile devices, if you don't manage your memory by reusing objects and by avoiding excessive allocations, the GC will kill your application performance.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;One of the interesting advantages of C++ is that it implements deteministic object destruction: when your statically allocated object goes out of scope, the destructor is called. This behavior allows us to implement classes like &lt;span style="font-family:courier new;"&gt;CWaitCursor&lt;/span&gt; that displays the wait cursor on the constructor and hide it or replace it on the destructor. You just have to create a variable of that type and the wait cursor will be shown while the object is alive.&lt;br /&gt;&lt;br /&gt;If we couple this with a simple reference counting mechanism, we can actually get all the benefits of a reference-counted memory management scheme without the pain that is imposed on us by the iPhone: we don't have to remember when to increment and decrement the references. How? The dead-old solution is to use reference counted smart pointers to manage our objects' life cycles.&lt;br /&gt;&lt;br /&gt;After performing a search for reference-counted smart pointers, and realizing that my needs were quite simple, I decided to roll my own. The first thing we need is a place where to store the reference counts. Some implementations use a proxy object to do this but, for simplicity sake, I decided to put the reference count right on the object through inheritance. This has the disadvantage of having to make all the reference-counted objects inherit from one class, but it's a simple class that will only add four bytes to the object size:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class CRefCount&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt;LONG m_nRefCount;&lt;br /&gt;&lt;br /&gt;public:&lt;br /&gt;CRefCount(void) : m_nRefCount(0) { };&lt;br /&gt;&lt;br /&gt;void RefIncrement()&lt;br /&gt;{&lt;br /&gt;InterlockedIncrement(&amp;amp;m_nRefCount);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;bool RefDecrement()&lt;br /&gt;{&lt;br /&gt;return InterlockedDecrement(&amp;amp;m_nRefCount) &lt;= 0;  }   };  &lt;/pre&gt;&lt;br /&gt;Note that I'm using the InterlockedIncrement and InterlockedDecrement to manage the reference count because these methods can be used from different threads. Also, note that the reference count starts at zero (and not at one like on the iPhone) because I want to count how many smart pointers are referring to this object. Let's see how the smart pointer class is defined:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;template &amp;lt;class T&amp;gt;&lt;br /&gt;class CRefPtr&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt;T *p;&lt;br /&gt;&lt;br /&gt;public:&lt;br /&gt;CRefPtr() : p(NULL) { }&lt;br /&gt;CRefPtr(T *pT) : p(pT)&lt;br /&gt;{&lt;br /&gt;   if(p)&lt;br /&gt;       p-&gt;RefIncrement();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;CRefPtr(const CRefPtr&amp;amp; ptr) : p(ptr.p)&lt;br /&gt;{&lt;br /&gt;   if(p)&lt;br /&gt;       p-&gt;RefIncrement();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;~CRefPtr() throw()&lt;br /&gt;{&lt;br /&gt;   Release();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Release()&lt;br /&gt;{&lt;br /&gt;   T* pTemp = p;&lt;br /&gt;&lt;br /&gt;   if(pTemp)&lt;br /&gt;   {&lt;br /&gt;       p = NULL;&lt;br /&gt;       if(pTemp-&gt;RefDecrement())&lt;br /&gt;           delete pTemp;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Attach(T* p1)&lt;br /&gt;{&lt;br /&gt;   Release();&lt;br /&gt;   p = p1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;operator T*() const throw()&lt;br /&gt;{&lt;br /&gt;   return p;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;T&amp;amp; operator*() const&lt;br /&gt;{&lt;br /&gt;   ATLENSURE(p!=NULL);&lt;br /&gt;   return *p;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;bool operator!() const throw()&lt;br /&gt;{&lt;br /&gt;   return (p == NULL);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;T* operator=(const CRefPtr&amp;amp; rhs)&lt;br /&gt;{&lt;br /&gt;   if(this != &amp;amp;rhs)&lt;br /&gt;   {&lt;br /&gt;       Release();&lt;br /&gt;       p = rhs.p;&lt;br /&gt;       if(p)&lt;br /&gt;           p-&gt;RefIncrement();&lt;br /&gt;   }&lt;br /&gt;   return *this;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;T* operator=(T* pT)&lt;br /&gt;{&lt;br /&gt;   if(p != pT)&lt;br /&gt;   {&lt;br /&gt;       Release();&lt;br /&gt;       p = pT;&lt;br /&gt;       if(p)&lt;br /&gt;           p-&gt;RefIncrement();&lt;br /&gt;   }&lt;br /&gt;   return *this;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;T* operator-&gt;() const&lt;br /&gt;{&lt;br /&gt;   ATLASSERT(p != NULL);&lt;br /&gt;   return p;&lt;br /&gt;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;As you can see each smart pointer takes up the same amount of memory as a regular pointer, so you can safely pass and return it by value from your own methods and functions. This is a very bare-bones implementation and may lack some more sophisticated features, but so far has worked quite well for me. You use it like a &lt;span style="font-family:courier new;"&gt;CComPtr&lt;/span&gt; (I confess that I did look it up when writing this code).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-3269206937600176794?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/3269206937600176794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=3269206937600176794' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3269206937600176794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3269206937600176794'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/05/is-native-code-hard.html' title='Is Native Code Hard?'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5513222851148388171</id><published>2009-05-29T16:32:00.002+01:00</published><updated>2009-05-29T16:36:32.977+01:00</updated><title type='text'>Gynoid</title><content type='html'>There is a &lt;a href="http://www.codeproject.com/KB/mobile/gynoid.aspx"&gt;new article on Code Project&lt;/a&gt; by Vincent Richomme where he presents the Gynoid framework for cross-platform mobile development. In the included sample, Vincent was so kind as to use the "touch list" WTL control that I have published in this blog. Thank you Vincent!&lt;br /&gt;&lt;br /&gt;P.S.: I'm not a guru, I just love this stuff and write about it... ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5513222851148388171?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5513222851148388171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5513222851148388171' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5513222851148388171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5513222851148388171'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/05/gynoid.html' title='Gynoid'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-7523907730089653504</id><published>2009-05-23T15:37:00.009+01:00</published><updated>2009-05-23T19:10:41.731+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GDI'/><title type='text'>Integer Trigonometry</title><content type='html'>Adding a live GPS feed to a map means, besides near-second updates, the requirement to display a location marker with the current heading. The Window Mobile GPSID provides the current heading in the &lt;a href="http://msdn.microsoft.com/en-us/library/ms893674.aspx"&gt;&lt;span style="font-family:courier new;"&gt;GPS_POSITION&lt;/span&gt;&lt;/a&gt; structure as the &lt;span style="font-family:courier new;"&gt;fHeading&lt;/span&gt; value, representing the angle in degrees between the current heading and true North (zero degrees). So how do you go about drawing a compass like the one in the picture?&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_AksH5-lumMs/ShgpMjanJ9I/AAAAAAAAAcg/2eLFP5fGorM/s1600-h/Compass1.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 74px; height: 60px;" src="http://4.bp.blogspot.com/_AksH5-lumMs/ShgpMjanJ9I/AAAAAAAAAcg/2eLFP5fGorM/s400/Compass1.png" alt="" id="BLOGGER_PHOTO_ID_5339062653889750994" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The drawing is composed of two simple triangles: red for North and blue for South. The drawing is performed by using the &lt;a href="http://msdn.microsoft.com/en-us/library/aa931055.aspx"&gt;&lt;span style="font-family:courier new;"&gt;Polygon&lt;/span&gt;&lt;/a&gt; GDI function that takes a list of points describing a closed shape and draws it using the selected pen and brush. Nothing new here. The interesting challenge is how to draw the image in the different angles without a big performance hit (translated: how to implement fast trigonometry functions).&lt;br /&gt;&lt;br /&gt;Current Windows Mobile devices are not guaranteed to have an FPU unit that will do all the floating point math for you. If you use the Compact Framework, you are sure that all floating point calculations are performed in a &lt;a href="http://blogs.msdn.com/abhinaba/archive/2009/03/27/net-compact-framework-and-arm-fpu.aspx"&gt;software emulated FPU&lt;/a&gt;, so they are much slower than what they could be when performed with a real FPU. When using native code, you have the advantage of using the FPU if one is available, but the code will fall back to the emulator if the FPU is missing.&lt;br /&gt;&lt;br /&gt;My approach here was to skip any floating point processing at all. There are two reasons for this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Drawing a map on a Windos Mobile device is a resource-intensive operation, especially if you are updating it frequently and you want to spend the least amount of time drawing any decorations on top of it. So a fast implementation is required.&lt;/li&gt;&lt;li&gt;This object requires very simple transformations (rotation plus offset) and the required accuracy of the final result is not very high. In fact, it is somewhat low considering the relatively small resolution of WM device screens. The bottom line is that you can live with a bit of error when drawing your compass (this is not rocket science).&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;So how do you calculate a rotation transformation? Please refer to a good book on the subject (I'm using this lovely book as a reference: &lt;a href="http://www.amazon.com/Essential-Mathematics-Games-Interactive-Applications/dp/155860863X/ref=sr_1_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1243099094&amp;amp;sr=8-2"&gt;Essential Mathematics for Games and Interactive Applications&lt;/a&gt;) and you will see that it all boils down to these two simple equations (transforms a point through a counter-clockwise rotation around the origin):&lt;br /&gt;&lt;ul&gt;&lt;li style="font-style: italic;"&gt;x' = x cos(a) - y sin(a)&lt;/li&gt;&lt;li style="font-style: italic;"&gt;y' = x sin(a) + y cos(a)&lt;/li&gt;&lt;/ul&gt;Where (&lt;span style="font-style: italic;"&gt;x&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;y&lt;/span&gt;) are the original point coordinates, (&lt;span style="font-style: italic;"&gt;x'&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;y'&lt;/span&gt;) are the transformed point coordinates and &lt;span style="font-style: italic;"&gt;a&lt;/span&gt; is the rotation angle. The first thing you need to do is to "draw" your compass by defining the vertexes assuming that the center of your coordinate system is in the center of the image. In this case, I used the following points:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;(0, 32) - North&lt;/li&gt;&lt;li&gt;(-7, 0) - West&lt;/li&gt;&lt;li&gt;(0, -32) - South&lt;/li&gt;&lt;li&gt;(8, 0) - East&lt;/li&gt;&lt;/ul&gt;The reason why I'm not using (7, 0) for East is simple: the final image looks much better on a discrete screen if it has an odd width. If you look at the sample project you will see that I split the compass into two distinct triangles in order to draw them with different pens and brushes.&lt;br /&gt;&lt;br /&gt;Now the interesting bit is how I implemented the &lt;span style="font-style: italic;"&gt;sin&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;cos&lt;/span&gt; functions: through a table lookup.  Assuming that you can live with an error of one degree when specifying the angle, all you need is a precomputed list of the &lt;span style="font-style: italic;"&gt;sin&lt;/span&gt; values between 0 and 90 degrees. Using basic trigonometry you can derive all &lt;span style="font-style: italic;"&gt;sin&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;cos&lt;/span&gt; values from the first quadrant &lt;span style="font-style: italic;"&gt;sin&lt;/span&gt; values. If you look at the code, you will see that the precomputed &lt;span style="font-style: italic;"&gt;sin&lt;/span&gt; values are scaled by 10,000. When calculating &lt;span style="font-style: italic;"&gt;x sin(a)&lt;/span&gt; the code uses the precomputed value and divides the result by 10,000 to get the approximate result (you can use a higher scale for a higher resolution calculation, but that might not be required for this purpose). You can see the implementation of these functions in the &lt;span style="font-family:courier new;"&gt;FastTrig.h&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;FastTrig.cpp&lt;/span&gt; files in the sample.&lt;br /&gt;&lt;br /&gt;Before we can draw our compass on the screen, we must take care of two important issues:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The original compass coordinates are centered around the origin, so we must transform them further to make it fully visible on the screen;&lt;/li&gt;&lt;li&gt;The screen coordinates of a Windows Mobile device are a bit different: while &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; grows to the right as we expect, &lt;span style="font-style: italic;"&gt;y&lt;/span&gt; grows down and not up.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;This means that beside the rotation we must apply a translation and a "mirror" transformation. In the sample code, I translate by adding the &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;y&lt;/span&gt; offsets corresponding to the middle of the screen and then the &lt;span style="font-style: italic;"&gt;y&lt;/span&gt; coordinate is flipped by subtracting it from the window height. Enough of this talk, here's the sample project: &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/GpsCompass.zip"&gt;GpsCompass.zip&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;On a future post I will update this code so that it uses a double buffer painting method to eliminate flickering and connect the compass direction to the GPS heading.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-7523907730089653504?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/7523907730089653504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=7523907730089653504' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7523907730089653504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7523907730089653504'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/05/integer-trigonometry.html' title='Integer Trigonometry'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_AksH5-lumMs/ShgpMjanJ9I/AAAAAAAAAcg/2eLFP5fGorM/s72-c/Compass1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-1459674810913864774</id><published>2009-05-20T08:56:00.003+01:00</published><updated>2009-05-20T09:37:08.340+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GPS'/><title type='text'>One GPS, multiple windows</title><content type='html'>After publishing the simple GPS class on my last post, I found myself in a situation where I needed the same &lt;span style="font-family: courier new;"&gt;CGps&lt;/span&gt; object to notify more than one window whenever a new GPS event arrived. My scenario is quite simple: while feeding a window with a map, I also need the same &lt;span style="font-family: courier new;"&gt;CGps&lt;/span&gt; object to notify another window where I display some GPS information like the current latitude and longitude coordinates.&lt;br /&gt;&lt;br /&gt;The original code supports notifications for one window only so, to solve this issue I could create another instance of the &lt;span style="font-family: courier new;"&gt;CGps&lt;/span&gt; class and have it notify the new window. Although this would work, it would also create an extra thread in the appliction (if you look at the &lt;span style="font-family: courier new;"&gt;CGps&lt;/span&gt; implementation, you will see that it uses a thread to wait on the GPSID events) which is unneeded and consumes more system resources.&lt;br /&gt;&lt;br /&gt;I ended up by devising a simpler solution: add multiple window handle - message pairs to the notification mechanism. To implement this I created a new class - &lt;span style="font-family: courier new;"&gt;CWindowNotifier&lt;/span&gt; - that is nothing more than a simple array of &lt;span style="font-family: courier new;"&gt;HWND&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;UINT&lt;/span&gt; pairs. When the consuming object wants to send a notification to a set of windows, it just calls the appropriate method (&lt;span style="font-family: courier new;"&gt;Post&lt;/span&gt; or &lt;span style="font-family: courier new;"&gt;Send&lt;/span&gt;). If one of the notification windows was closed, the code automatically removes it from the notification list. Using this class is very simple: just call the AddWindow method with the &lt;span style="font-family: courier new;"&gt;HWND&lt;/span&gt; you want to notify and a &lt;span style="font-family: courier new;"&gt;UINT&lt;/span&gt; value containing the message code for the notification. When you want to send a notification use either the &lt;span style="font-family: courier new;"&gt;Post&lt;/span&gt; or &lt;span style="font-family: courier new;"&gt;Send&lt;/span&gt; methods. The &lt;span style="font-family: courier new;"&gt;Post&lt;/span&gt; method uses the &lt;span style="font-family: courier new;"&gt;PostMessage&lt;/span&gt; API so it returns immediately and is the one I recommend for most uses. The &lt;span style="font-family: courier new;"&gt;Send&lt;/span&gt; method uses the &lt;span style="font-family: courier new;"&gt;SendMessage&lt;/span&gt; API, so it works synchronously and waits before all notification windows have responded. You can get the class source code &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/WindowNotifier.zip"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The updated &lt;span style="font-family: courier new;"&gt;CGps&lt;/span&gt; source code is &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/Gps_2.zip"&gt;here&lt;/a&gt;. Note that this new version uses a new wrapper for the &lt;span style="font-family: courier new;"&gt;CRITICAL_SECTION&lt;/span&gt; objects which you can find &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/CriticalSection.h"&gt;here&lt;/a&gt;. Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-1459674810913864774?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/1459674810913864774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=1459674810913864774' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1459674810913864774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1459674810913864774'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/05/one-gps-multiple-windows.html' title='One GPS, multiple windows'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-226171685664890915</id><published>2009-05-15T09:05:00.005+01:00</published><updated>2009-05-15T09:42:20.471+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GPS'/><title type='text'>A simple GPS reader class</title><content type='html'>I've been recently involved in a number of projects that require information from the Window Mobile GPS Intermediate Driver. The usage pattern is quite similar in all cases as the application needs to update a window based on the GPS information stream. There are two possible approaches for this: you can use a window timer and poll the GPSID or you can create a worker thread that waits on the GPS stream to wake up and notify the window through a &lt;span style="font-family:courier new;"&gt;PostMessage&lt;/span&gt; call.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family:courier new;"&gt;CGps&lt;/span&gt; class (download &lt;a href="http://www.primeworks-mobile.com/Downloads/Blog/Gps.zip"&gt;here&lt;/a&gt;) is very simple to use. On your window class just declare a member variable of type &lt;span style="font-family:courier new;"&gt;CGps&lt;/span&gt;, like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CGps m_gps;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To start receiving GPS data, just call&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;m_gps.Start(m_hWnd, WM_GPS);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;where &lt;span style="font-family:courier new;"&gt;WM_GPS&lt;/span&gt; is a user-defined window message. You can use something like:&lt;br /&gt;&lt;br /&gt;#define WM_GPS (WM_USER + 0x654)&lt;br /&gt;&lt;br /&gt;Now you need to handle the &lt;span style="font-family:courier new;"&gt;WM_GPS&lt;/span&gt; message in your code (this will be somewhat different if you are using straight API, MFC or WTL). Note that when handling the message, both &lt;span style="font-family:courier new;"&gt;wParam&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;lParam&lt;/span&gt; are zero - the message works as a simple notification mechanism to let the window class or procedure know that the GPS updated its data. You read the GPS information quite simply:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;GPS_POSITION gpsPos;&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;m_gps.GetPosition(&amp;amp;gpsPos);&lt;/span&gt;&lt;br&gt;&lt;br /&gt;To stop the GPS events you can either call &lt;span style="font-family:courier new;"&gt;Stop()&lt;/span&gt; or let the destructor do that for you when the object goes out of scope and is destroyed.&lt;br /&gt;&lt;br /&gt;When implementing this class, I had to work around the now-known GPSID API bug. On some devices, the &lt;span style="font-family:courier new;"&gt;GPSGetPosition&lt;/span&gt; API uses a different size for the &lt;span style="font-family:courier new;"&gt;GPS_POSITION&lt;/span&gt; structure (something that has been explained by John Spaith &lt;a href="http://blogs.msdn.com/cenet/archive/2007/12/06/gpsid-problem-workaround-on-recent-wm6-release.aspx"&gt;here&lt;/a&gt;). The workaround is simple: just feed the thing with a fake buffer and cast it back to a &lt;span style="font-family:courier new;"&gt;GPS_POSITION&lt;/span&gt;. If you look at the implementation, you will see all this trickery at work. But don't worry - it does work!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-226171685664890915?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/226171685664890915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=226171685664890915' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/226171685664890915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/226171685664890915'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/05/simple-gps-reader-class.html' title='A simple GPS reader class'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-7388302805934458404</id><published>2009-05-12T09:52:00.001+01:00</published><updated>2009-05-12T10:34:22.780+01:00</updated><title type='text'>Windows Mobile Marketplace now open</title><content type='html'>The Windows Mobile Marketplace &lt;a href="http://blogs.msdn.com/windowsmobile/archive/2009/05/11/marketplace-registration-open.aspx"&gt;is now open&lt;/a&gt; (but only for US developers?)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-7388302805934458404?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/7388302805934458404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=7388302805934458404' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7388302805934458404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7388302805934458404'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/05/windows-mobile-marketplace-now-open.html' title='Windows Mobile Marketplace now open'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-3947256882456782228</id><published>2009-05-07T09:15:00.001+01:00</published><updated>2009-05-07T09:18:00.868+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>AllKeys, documented</title><content type='html'>Here is the key capturing API we've all been waiting for since the demise of GAPI: &lt;a href="http://blogs.msdn.com/windowsmobile/archive/2009/05/06/just-say-no-to-gapi-what-you-need-to-know-about-allkeys-and-input-management.aspx"&gt;AllKeys&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-3947256882456782228?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/3947256882456782228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=3947256882456782228' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3947256882456782228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3947256882456782228'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/05/allkeys-documented.html' title='AllKeys, documented'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-3436518670952686244</id><published>2009-05-06T15:00:00.003+01:00</published><updated>2009-05-06T15:15:22.127+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><title type='text'>WTL frames, toolbars and headers</title><content type='html'>The WTL &lt;span style="font-family: courier new;"&gt;CFrameWindowImpl&lt;/span&gt; class template uses a very simple approach to manage the client, toolbar and status bar windows. The preset arrangement for these windows is very simple:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;a client view that occupies most of the frame's client area;&lt;/li&gt;&lt;li&gt;an optional toolbar window that is placed at the top of the frame's client area and above the client view;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;an optional status bar placed at the bottom of the frame's client area and below the client view.&lt;/li&gt;&lt;/ul&gt;The frame window already knows how to handle the three child windows. Each frame contains three member variables for them:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;m_hWndClient&lt;/span&gt; for the client view;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;m_hWndToolBar&lt;/span&gt; for the top toolbar window and&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;m_hWndStatusBar&lt;/span&gt; for bottom status bar&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;To make the three child windows work together you must create them and assign them to the appropriate member variable. The top and bottom windows must implement a special handling of the &lt;span style="font-family: courier new;"&gt;WM_SIZE&lt;/span&gt; message because this is how the frame tells each window to place itself in its client area and thus calculate the remaining area for the client view. This special message is nothing but a &lt;span style="font-family: courier new;"&gt;WM_SIZE&lt;/span&gt; message with both parameters (&lt;span style="font-family: courier new;"&gt;wParam&lt;/span&gt; and &lt;span style="font-family: courier new;"&gt;lParam&lt;/span&gt;) set to zero. Here's a sample from my production code:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void OnSize(UINT nType, CSize size)&lt;br /&gt;{&lt;br /&gt;    if(size.cx == 0 &amp;amp;&amp;amp; size.cy == 0)&lt;br /&gt;    {&lt;br /&gt;        CWindow wndParent(GetParent());&lt;br /&gt;        CRect   rc;&lt;br /&gt;&lt;br /&gt;        wndParent.GetClientRect(&amp;amp;rc);&lt;br /&gt;        rc.top = rc.bottom - m_cyToolbar;&lt;br /&gt;        MoveWindow(&amp;amp;rc);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Easy, huh?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-3436518670952686244?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/3436518670952686244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=3436518670952686244' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3436518670952686244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3436518670952686244'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/05/wtl-frames-toolbars-and-headers.html' title='WTL frames, toolbars and headers'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2652146838606491026</id><published>2009-04-29T09:03:00.001+01:00</published><updated>2009-04-29T09:06:47.000+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MAPI'/><title type='text'>Intercepting mail messages</title><content type='html'>Ever wondered how to intercept an incoming mail message from native code? &lt;a href="http://blogs.msdn.com/hegenderfer/archive/2009/04/28/intercepting-mail-using-imapiadvisesink.aspx"&gt;The Windows Mobile RSS blog&lt;/a&gt; explains how: a very interesting read!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2652146838606491026?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2652146838606491026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2652146838606491026' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2652146838606491026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2652146838606491026'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/04/intercepting-mail-messages.html' title='Intercepting mail messages'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-3170835449029098093</id><published>2009-04-27T09:28:00.003+01:00</published><updated>2009-04-27T09:59:19.325+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><title type='text'>SQL Compact and threads</title><content type='html'>Do you remember the days of Pocket PC 2002 and 2003? Life was pretty simple with no need for certificates, a single screen size and SQL CE only ran on devices. Then Microsoft released SQL Compact 3.1 and suddenly the small database was also on the desktop. By this time I already had a small set of tools that remotely accessed the engine via a streamed RAPI interface and was confronted with the need to port the code to the desktop.&lt;br /&gt;&lt;br /&gt;In its classical form, the code runs in two different processors with an asynchronous link. Porting the code to the desktop, where both the client and the server ran on the same process, meant either a major rewrite or a smart adaptation. I chose the latter and implemented a DMA data stream that is implemented by the "server" DLL on the desktop. The client merely uses a virtual stream that can be attached to a variety of server endpoints, like a RAPI server, a TCP/IP server or even a local server running in the same process (but on different threads).&lt;br /&gt;&lt;br /&gt;This has worked quite successfully until last week when I got a report from a customer complaining about a mysterious error. After exporting a very large (and I mean very large) database from SQL Server to SQL Compact 3.5 on the desktop, the database file would end up with over 350 MB of size but zero tables. After repairing the database it would shrink down to the 20 KB empty databases have.&lt;br /&gt;&lt;br /&gt;I first suspected of the transaction mechanism because the whole process (table creation, data transfer and final script execution) is executed under a single transaction. After confirming with Microsoft that there was no known transaction size limitation, I got back to the drawing board in bewilderment. To make matters worse, no error was being reported!&lt;br /&gt;&lt;br /&gt;The product that caused this issue (&lt;a href="http://www.primeworks-mobile.com/Products/DataPortWizard.html"&gt;Data Port Wizard&lt;/a&gt;) has a very simple usage pattern: you set the source and target databases, set some options and run the data transfer process. At the end the application reports success or error and then quits (after user confirmation). As it turned out, the problem happened when the application exited.&lt;br /&gt;&lt;br /&gt;When transferring data to a desktop SDF file, everything works under the same desktop process. The SQL Compact data provider runs in its own thread (not on the UI thread) due to the reason I pointed out at the beginning: I wanted to reuse the remote provider code that runs on a different CPU, so I implemented it as running on a different thread with a DMA communication to the client code. When the client application closes, it signals the SQL Compact data provider to shut down and waits a little while for it to reply. If no reply arrives on time, the desktop client proceeds to terminate the application.&lt;br /&gt;&lt;br /&gt;Apparently with very large databases, the SQL Compact engine takes a bit longer to shut down. This is in fact something to be expected because there are larger buffers to flush to storage and there is also the auto-shrink feature that runs when the connection closes. When this whole thing is running on a remote device, your desktop client can afford not to wait for the remote provider to shut down because it is running in a different CPU. When running under the same process, you don't have that luxury. If you don't wait for the SQL Compact engine to shut down in its own thread and you shut down the application, you will be preventing the database engine from correctly shutting down altogether. You can imagine the mayhem this causes to your database...&lt;br /&gt;&lt;br /&gt;Lesson: if you run SQL Compact on a different thread, make sure you wait until the connection closes before you shut down your application. You have been warned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-3170835449029098093?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/3170835449029098093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=3170835449029098093' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3170835449029098093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3170835449029098093'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/04/sql-compact-and-threads.html' title='SQL Compact and threads'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2044751521948919769</id><published>2009-04-21T17:35:00.003+01:00</published><updated>2009-04-21T17:39:09.403+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GDI+'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Native GDI+ on CodeProject</title><content type='html'>Vincent Richomme just posted an &lt;a href="http://www.codeproject.com/KB/mobile/gdiplusandwinmobile.aspx"&gt;article&lt;/a&gt; on Code Project on how to use the GDI+ libaries through native code. If you think it's hard to add that extra cool look to your native GDI app, do take a look at Vincent's article!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2044751521948919769?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2044751521948919769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2044751521948919769' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2044751521948919769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2044751521948919769'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/04/native-gdi-on-codeproject.html' title='Native GDI+ on CodeProject'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-7452484509198899665</id><published>2009-04-15T12:40:00.000+01:00</published><updated>2009-04-15T12:42:35.789+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>IE8 and Visual Studio</title><content type='html'>If you installed Internet Explorer 8 on your development machine, you may find it impossible to create new C++ projects. Here's an &lt;a href="http://blogs.msdn.com/vcblog/archive/2009/03/28/some-vs2005-and-vs2008-wizards-pop-up-script-error.aspx"&gt;explanation and workaround&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-7452484509198899665?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/7452484509198899665/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=7452484509198899665' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7452484509198899665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7452484509198899665'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/04/ie8-and-visual-studio.html' title='IE8 and Visual Studio'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4137268804324051399</id><published>2009-04-14T17:49:00.002+01:00</published><updated>2009-04-14T18:11:26.044+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Is IImage caching a good idea?</title><content type='html'>On my previous post I described a very simple solution to improve the performance of &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;IImage::Draw&lt;/span&gt; - caching the converted image. This does speed up the process of drawing the alpha blended picture but has one drawback: you store the image twice. From what I understood from the &lt;a href="http://msdn.microsoft.com/en-us/library/aa915465.aspx"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;IImagingFactory::CreateImageFromBuffer&lt;/span&gt;&lt;/a&gt; online documentation, the supplied buffer is not immediately used and must be there throughout the &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;IImage&lt;/span&gt; object lifetime. So when you cache the image you are essentially storing two representations of the same thing (the original encoding  and the decoded version). While this may not be a big issue for small images, this becomes a serious problem when using lots of images and / or larger images. So what can we do about this?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The idea is to have a single 32 bpp ARGB &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;HBITMAP&lt;/span&gt; in memory per image. As I showed before, using the shell API to load the images is a bad idea because it shrinks them to 16 bpp. Is there any other alternative to this? We can try to create a 32 bpp bitmap in memory and then use the&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; IImage&lt;/span&gt; object to paint it. After releasing the &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;IImage&lt;/span&gt; object, we should get a properly-formatted 32 bpp ARGB bitmap. On my next post I will illustrate this technique that was validated by master guru &lt;a href="http://blog.opennetcf.com/afeinman/"&gt;Alex Feinman&lt;/a&gt;. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4137268804324051399?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4137268804324051399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4137268804324051399' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4137268804324051399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4137268804324051399'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/04/is-iimage-caching-good-idea.html' title='Is IImage caching a good idea?'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6031746678508675493</id><published>2009-04-13T19:21:00.004+01:00</published><updated>2009-04-13T19:32:14.347+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Revisiting the Carousel - II</title><content type='html'>I finally found a solution for the speed problem of rendering the carousel icons: caching the image. After a big wild goose chase, the solution was under my very nose all the time. To see the dramatic performance improvement, open the CarouselDemo2 project I published on my &lt;a href="http://nativemobile.blogspot.com/2009/04/revisiting-carousel.html"&gt;last post&lt;/a&gt;, and go to the &lt;span style="font-family:courier new;"&gt;image.h&lt;/span&gt; file. At the top of the file, there is a private method named &lt;span style="font-family:courier new;"&gt;CreateImage&lt;/span&gt;, where the &lt;span style="font-family:courier new;"&gt;IImage&lt;/span&gt; object is created. Right after creating the object:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;hr = spFactory-&gt;CreateImageFromBuffer(m_pImageData, m_nImageSize, BufferDisposalFlagNone, &amp;amp;m_spImage);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;just add the following lines:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(SUCCEEDED(hr))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    hr = m_spImage-&gt;SetImageFlags(ImageFlagsCaching);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now run the demo again and see how much the performance has improved!&lt;br /&gt;&lt;br /&gt;Now that this issue is solved, let me tell you about the wild goose chase. My original idea was to use the &lt;span style="font-family:courier new;"&gt;AlphaBlend&lt;/span&gt; API that has been added to Windows Mobile 5. This function does support per-pixel alpha blending so it looked very promising. Unfortunately, there seems to be no easy way to load a 32 bpp bitmap image with Windows Mobile. I tried using &lt;span style="font-family:courier new;"&gt;SHLoadImageResource&lt;/span&gt; (I read somewhere that this would keep the alpha channel intact) but the returned HBITMAP was smashed down to 16 bpp, so the alpha channel was lost. I still have not given up to find an easy way to load the PNG files into memory, and when I do you will be the first to know. Oh, by the way, if you &lt;span style="font-style: italic;"&gt;do know&lt;/span&gt; please post a comment here!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6031746678508675493?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6031746678508675493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6031746678508675493' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6031746678508675493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6031746678508675493'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/04/revisiting-carousel-ii.html' title='Revisiting the Carousel - II'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-8892613626672287774</id><published>2009-04-11T13:24:00.007+01:00</published><updated>2009-04-11T23:43:52.453+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Revisiting the Carousel</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_AksH5-lumMs/SeETsQrVYKI/AAAAAAAAAcY/ONQT9kqQsu0/s1600-h/CarouselLo.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 240px; height: 131px;" src="http://2.bp.blogspot.com/_AksH5-lumMs/SeETsQrVYKI/AAAAAAAAAcY/ONQT9kqQsu0/s400/CarouselLo.png" alt="" id="BLOGGER_PHOTO_ID_5323557885640532130" border="0" /&gt;&lt;/a&gt;What's the difference between the two QVGA carousel implementations above? And what about the two VGA implementations below?&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_AksH5-lumMs/SeCML-ksw3I/AAAAAAAAAcQ/jW9gP_ZSYdE/s1600-h/CarouselHi.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 220px;" src="http://2.bp.blogspot.com/_AksH5-lumMs/SeCML-ksw3I/AAAAAAAAAcQ/jW9gP_ZSYdE/s400/CarouselHi.png" alt="" id="BLOGGER_PHOTO_ID_5323408896955302770" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The top carousel icons look much better than the ones below, especially the ones with round shapes. What's the difference? While the images at the bottom carousel are regular Windows icons drawn from an image list container, the images at the top carousel are PNG images drawn using the &lt;span style="font-family:courier new;"&gt;IImage&lt;/span&gt; object. These PNG files were created with an "alpha channel", an extra byte of information that specifies how transparent each pixel is. Contrary to Windows CE icons which support only the concept of full transparency or full opaqueness, an alpha value determines how transparent each pixel is, so it can blend with the background and create very smooth transitions (so much nicer and easier on the eye). Using the right tools (these icons were produced using Axialis Icon Workshop), you can easily create these images and render them on the device screen.&lt;br /&gt;&lt;br /&gt;The sample project (&lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/CarouselDemo2.zip"&gt;CarouselDemo2&lt;/a&gt;) illustrates how this can be implemented in code. First, I removed all the icon-related code and added two new classes (both on the &lt;span style="font-family:courier new;"&gt;image.h&lt;/span&gt; file): &lt;span style="font-family:courier new;"&gt;CImage&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;CImageArray&lt;/span&gt;. The first class encapsulates an &lt;span style="font-family:courier new;"&gt;IImage&lt;/span&gt; object and provides minimal services for loading the image from resources and drawing it on a given DC. The second class merely groups instances of the first in an array for convenience.&lt;br /&gt;&lt;br /&gt;The great thing about &lt;span style="font-family:courier new;"&gt;IImage&lt;/span&gt; is that it allows us to load a raw byte stream of data making up a recognizable bitmap (more codecs can be added) and transforms it into a usable bitmap (not an &lt;span style="font-family:courier new;"&gt;HBITMAP&lt;/span&gt;, mind you). The supported image formats include JPEG, GIF and PNG with the nice alpha channel feature. All you have to do is load the image and draw it. Simple!&lt;br /&gt;&lt;br /&gt;Well, not so fast... Really: it's dreadfully slow! If you run the new demo application you will see what I mean: the carousel scrolls like mud.&lt;br /&gt;&lt;br /&gt;I previously had a similar experience where using &lt;span style="font-family:courier new;"&gt;IImage::Draw&lt;/span&gt; on a graphics-intensive GDI application proved impossible to use. The solution was to pre-render the PNG files (no transparencies here) to an &lt;span style="font-family:courier new;"&gt;HBITMAP&lt;/span&gt; and cache them, so I was not really surprised that the painting would be slower (but not &lt;span style="font-style: italic;"&gt;that&lt;/span&gt; slow!). Is there any way around it? Hopefully yes, and I will write about it (or about my failure to achieve it) on my next blog post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-8892613626672287774?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/8892613626672287774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=8892613626672287774' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8892613626672287774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8892613626672287774'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/04/revisiting-carousel.html' title='Revisiting the Carousel'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_AksH5-lumMs/SeETsQrVYKI/AAAAAAAAAcY/ONQT9kqQsu0/s72-c/CarouselLo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4380242688277678814</id><published>2009-04-07T09:25:00.002+01:00</published><updated>2009-04-07T09:37:44.516+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>The missing iso-8859-1 code page</title><content type='html'>It's definitely not there. Some people have complained about this when parsing XML files using the .NET CF, but I found out about this yesterday night while trying to custom parse an iso-8859-1 encoded KML file. These files are used by Google Earth to add layers of geographical information on top of the displayed map. The content is regular XML with a specialized syntax that is recognized by the Google Earth application and you can find lots of sources of this type of files. Currently I'm developing a native Virtual Earth map browser for Windows mobile and I want to add the option to read these files and dynamically add the information to the map - that's why I met this issue.&lt;br /&gt;&lt;br /&gt;When trying to convert a string using the &lt;span style="font-family: courier new;"&gt;MultiByteToWideChar&lt;/span&gt; API, I got an invalid parameter error when using the iso-8859-1 (28591) code page. A very brief search showed me that this is aknown issue and that, apparently, it's the &lt;a href="http://social.msdn.microsoft.com/forums/en-US/vssmartdevicesvbcs/thread/02c47a3e-5173-4a3e-a2b5-89cb9d32e54b/"&gt;device manufacturer&lt;/a&gt;'s decision to include a given code page. Thankfully there seems to be a solution that should solve most of the conversion cases: &lt;a href="http://groups.google.com/group/microsoft.public.dotnet.framework.compactframework/browse_frm/thread/2dde891b73183dd2/ab891a460ded8897?q=ISO+8859&amp;amp;rnum=2#ab891a460ded8897"&gt;use the windows-1252 code page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now I'm glad that I'm custom-parsing the KML file because I can cheat the encoding section and replace the iso-8859-1 with windows-1252 on-the-fly. I'm not sure I would be so successful if using an automated parser (native or managed). Now the question is: why is iso-8859-1 not there?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4380242688277678814?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4380242688277678814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4380242688277678814' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4380242688277678814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4380242688277678814'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/04/missing-iso-8859-1-code-page.html' title='The missing iso-8859-1 code page'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-3647691013894365969</id><published>2009-03-31T14:03:00.006+01:00</published><updated>2009-03-31T14:15:40.867+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>The Touch Pro menu</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_AksH5-lumMs/SdIWipujm-I/AAAAAAAAAcI/pbANRttrSws/s1600-h/TouchProMenu.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 150px; height: 200px;" src="http://2.bp.blogspot.com/_AksH5-lumMs/SdIWipujm-I/AAAAAAAAAcI/pbANRttrSws/s200/TouchProMenu.png" alt="" id="BLOGGER_PHOTO_ID_5319338894450465762" border="0" /&gt;&lt;/a&gt;This is not really a menu but a window instead, and it's also not what I want to write about. What really interested me was the effect of showing a single menu item at the right side of the menu bar. This is a very cool effect because you use the same toolbar button to both show and hide the menu list. Achieving this effect is actually quite easy: you must add an empty button on the left. Here's the script I used to mimic this effect:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;IDM_MENU_EMPTY_CANCEL RCDATA &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;BEGIN&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    IDM_MENU_EMPTY_CANCEL, 2,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    I_IMAGENONE, ID_MENU_EMPTY, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE, &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    IDS_EMPTY, 0, NOMENU,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    I_IMAGENONE, ID_MENU_CANCEL, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE, &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    ID_MENU_CANCEL, 0, NOMENU,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;END&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The &lt;span style="font-family:courier new;"&gt;IDS_EMPTY&lt;/span&gt; string resource contains one space character only and the &lt;span style="font-family:courier new;"&gt;ID_MENU_EMPTY&lt;/span&gt; command is not handled. This seems to be the same approach that HTC used when writing the user interface: if you click the left soft button or the left menu area, you will see the visual feedback just like it had a real button.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-3647691013894365969?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/3647691013894365969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=3647691013894365969' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3647691013894365969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3647691013894365969'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/03/touch-pro-menu.html' title='The Touch Pro menu'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_AksH5-lumMs/SdIWipujm-I/AAAAAAAAAcI/pbANRttrSws/s72-c/TouchProMenu.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-7685258174191728552</id><published>2009-03-27T08:47:00.003Z</published><updated>2009-03-27T08:51:23.547Z</updated><title type='text'>Camera Capture on CodeProject</title><content type='html'>Here are two interesting articles on using the &lt;span style="font-family:courier new;"&gt;SHCameraCapture&lt;/span&gt; API on C++ applications:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/KB/smart/PPCCapture.aspx"&gt;Using SHCameraCapture from a C++ Pocket PC 2003 Application&lt;/a&gt;&lt;br&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/KB/smart/PPCCapture2.aspx"&gt;What to do if SHCameraCapture Returns E_FAIL?&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-7685258174191728552?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/7685258174191728552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=7685258174191728552' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7685258174191728552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7685258174191728552'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/03/camera-capture-on-codeproject.html' title='Camera Capture on CodeProject'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5330846414870231846</id><published>2009-03-16T10:40:00.003Z</published><updated>2009-03-16T15:14:25.469Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>IImage::Draw</title><content type='html'>Drawing PNG images on the screen has become quite easy since Microsoft released the imaging library for Windows Mobile devices. Christopher Fairbairn illustrated the technique on one of his excellent &lt;a href="http://www.christec.co.nz/blog/archives/361"&gt;blog posts&lt;/a&gt; where he illustrates the process, from acquiring the bitmap data to rendering it on the screen. As he points out, if you load a PNG file with an alpha layer, the transparency will be correctly painted to the image creatin all sorts of nice visual effects. But...&lt;br /&gt;&lt;br /&gt;... this is a very expensive operation! In fact, &lt;span style="font-family:courier new;"&gt;IImage::Draw&lt;/span&gt; is slower than painting a non transparency bitmap using the regular &lt;span style="font-family:courier new;"&gt;BitBlt&lt;/span&gt; API. If  you need raw performance (like when you are repeatedly painting lots of these to the screen, even with a double buffer) yo will get a terrible performance hit. I found out about this in my map rendering scenario, while adding KML-encoded layers. As the number of bitmaps grows, the rendering speed degrades very rapidly to the point where it becomes unusable. What can you do?&lt;br /&gt;&lt;br /&gt;My solution was to pre-render the PNG file into a regular GDI bitmap (adding a white background) and then using the &lt;span style="font-family:courier new;"&gt;BitBlt&lt;/span&gt; API to render it. The performance was back at the expense of some unsightly white backgrounds on my map icons... Seems like this is going to be the solution if I want to stick with the GDI.&lt;br /&gt;&lt;br /&gt;P.S: The white box issue was neatly solved by rendering the PNG against a Magenta (&lt;span style="font-family: courier new;"&gt;RGB(0xff, 0, 0xff)&lt;/span&gt;) background and using the &lt;span style="font-family: courier new;"&gt;TransparentImage&lt;/span&gt; API.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5330846414870231846?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5330846414870231846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5330846414870231846' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5330846414870231846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5330846414870231846'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/03/iimagedraw.html' title='IImage::Draw'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-8425322871972156031</id><published>2009-03-04T17:08:00.003Z</published><updated>2009-03-05T08:32:59.109Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Seek and you shall find</title><content type='html'>I recently found myself involved in a prototype Windows Mobile mapping application using the &lt;a href="http://maps.live.com/"&gt;Virtual Earth&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/bb259689.aspx"&gt;tile system&lt;/a&gt;. Downloading the 256 x 256 bitmaps to a mobile device through a GPRS connection is slow and a bit painful, so I thought about creating an external cache mechanism. This would temporarily store the bitmaps for future use and, instead of writing the bitmaps to the file system I thought about using SQL Compact. There are a few advantages for using a database instead of the file system: you store all the bitmaps in a single file and you get the added benefit of easier maintenance (especially when deleting outdated bitmaps to clear the cache). So I looked back to the OLE DB library I have been working with for some help but I found a major whole (yes, there are more, I know!): there was no support for &lt;span style="font-family:courier new;"&gt;IRowsetIndex::Seek&lt;/span&gt;. Why do I need to use this method when I can equally retrieve individual records using a plain &lt;span style="font-family:courier new;"&gt;SELECT&lt;/span&gt; command? The answer is &lt;span style="font-style: italic;"&gt;speed&lt;/span&gt;. When you go through the SQL Compact Query Processor your application pays a performance penalty that may be avoided (with varying degrees of effort). In this case I wanted to retrieve a single row from a table using an index (no fancy &lt;span style="font-family:courier new;"&gt;JOIN&lt;/span&gt; or &lt;span style="font-family:courier new;"&gt;GROUP BY&lt;/span&gt; clauses) so using a base table is very appropriate, performance-wise.&lt;br /&gt;&lt;br /&gt;The idea is very simple: open a base table cursor and specify the index to use; seek using the required key values and retrieve the row data (if it's there). As I said, you can do this using SQL but there is performance penalty that I did not want to pay, especially when fast painting is required. My major problem was that there was no support for this in the previous version of the OLD DB library, so I had to implement it.&lt;br /&gt;&lt;br /&gt;Implementing the &lt;span style="font-family:courier new;"&gt;IRowsetIndex::Seek&lt;/span&gt; supporting code implies adding an extra column binding code (similar to the one I wrote for the columns). In fact, you need an extra &lt;span style="font-family:courier new;"&gt;IAccessor&lt;/span&gt; object to bind the key columns as well as all the other supporting data structures. After a few hours worth of work, I managed to develop a working version of the code that I'm publishing here. If you look at the &lt;span style="font-family:courier new;"&gt;CRowset&lt;/span&gt; class implementation you will see how its complexity increased to a point where some new abstractions are just crying out to be created...&lt;br /&gt;&lt;br /&gt;When using this code, remember to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Add the &lt;span style="font-family:courier new;"&gt;DBPROP_IRowsetIndex&lt;/span&gt; property (set to true) to the rowset property set;&lt;/li&gt;&lt;li&gt;Call &lt;span style="font-family:courier new;"&gt;CRowset::SetKeyValue&lt;/span&gt; for each one of the index key values: ordinals start at one;&lt;/li&gt;&lt;li&gt;To seek to the requested row, call &lt;span style="font-family:courier new;"&gt;CRowset::Seek&lt;/span&gt; specifying the number of valid key columns (the number of valid values set with &lt;span style="font-family:courier new;"&gt;CRowset::SetKeyValue&lt;/span&gt;).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;If you get an &lt;span style="font-family:courier new;"&gt;S_OK&lt;/span&gt; as return value, the row was found and the data loaded into the row and ready to use.&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/OleDbClientLib3.zip"&gt;OleDbClientLib3.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;EDIT: The link has been fixed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-8425322871972156031?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/8425322871972156031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=8425322871972156031' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8425322871972156031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8425322871972156031'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/03/seek-and-you-shall-find.html' title='Seek and you shall find'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4358860709368299560</id><published>2009-02-27T18:03:00.003Z</published><updated>2009-02-27T18:14:06.952Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>TouchBrowser - III</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_AksH5-lumMs/SagtZ0VFSUI/AAAAAAAAAb4/jt1VnAP4VQQ/s1600-h/TouchBrowser3.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_AksH5-lumMs/SagtZ0VFSUI/AAAAAAAAAb4/jt1VnAP4VQQ/s400/TouchBrowser3.png" alt="" id="BLOGGER_PHOTO_ID_5307542082423179586" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Here's the latest update of the TouchBrowser code. This time I added a gradient to the selection cursor and also added the file size and last access date. The file size needs to be pretty-printed to make reading easier.&lt;br /&gt;&lt;br /&gt;On touch-screen devices, the list now supports a HitTest function that, by delegating to the underlying list item, reports what part of the item was clicked by the user and what action is associated with it. In this case I made the icon area sensitive to the selection action so you now navigate into a directory by clicking the icon. If you just click the file name, nothing will happen beyond scrolling the list and setting the selection cursor.&lt;br /&gt;&lt;br /&gt;Sample: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/TouchBrowser3.zip"&gt;TouchBrowser3.zip&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4358860709368299560?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4358860709368299560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4358860709368299560' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4358860709368299560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4358860709368299560'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/02/touchbrowser-iii.html' title='TouchBrowser - III'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_AksH5-lumMs/SagtZ0VFSUI/AAAAAAAAAb4/jt1VnAP4VQQ/s72-c/TouchBrowser3.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-8397403605954266355</id><published>2009-02-27T09:55:00.001Z</published><updated>2009-02-27T09:58:10.461Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><title type='text'>SQL Compact Insert Performance</title><content type='html'>I've just posted the SQL Compact Insert Performance demo on my &lt;a href="http://mobilesandbox.blogspot.com"&gt;managed code&lt;/a&gt; blog. It compares various approaches for inserting large volumes of data in a SQL Compact database and, although written for a managed code audience, is also relevant for native code and the OLE DB stack (the basic reality is the same, only slightly faster...).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-8397403605954266355?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/8397403605954266355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=8397403605954266355' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8397403605954266355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8397403605954266355'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/02/sql-compact-insert-performance.html' title='SQL Compact Insert Performance'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-3651703154087088295</id><published>2009-02-19T22:33:00.003Z</published><updated>2009-02-19T22:48:53.514Z</updated><title type='text'>TouchBrowser - II</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_AksH5-lumMs/SZ3ekzjJ4wI/AAAAAAAAAbo/oH7QUvxgQII/s1600-h/TouchBrowser2.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 240px; height: 320px;" src="http://4.bp.blogspot.com/_AksH5-lumMs/SZ3ekzjJ4wI/AAAAAAAAAbo/oH7QUvxgQII/s400/TouchBrowser2.png" alt="" id="BLOGGER_PHOTO_ID_5304640660006626050" border="0" /&gt;&lt;/a&gt;Here are a few more tweaks to the touch browser sample I published in my last post. One of the issues that nagged me was the item's height - too small for finger use. This new sample uses the large system image list which makes for bigger items that can be more easily selected with a finger.&lt;br /&gt;&lt;br /&gt;As you can see from the image, directories and regular files are rendered differently. File items will also have the file size and last change date printed in the list for the next release.&lt;br /&gt;&lt;br /&gt;In this version I also fixed the bub in the &lt;span style="font-family: courier new;"&gt;EnsureVisible&lt;/span&gt; function. When you use the direction keys to navigate the list the items are now correctly shown and the list scrolls with a small animation.&lt;br /&gt;&lt;br /&gt;My major concern with this code is finger-friendliness. There are still a lot of rough edges and it works best with a stylus - not my intended purpose. I'm still wondering how to solve this issue and make the code consistently recognize a drag gesture. Finally, I will also have to change the way the code accepts an action on an item. One of the ideas I'm exploring for this is to define a "hot" area in the item that will be used to take the action (in this case to open a file or a directory). Each item will know where its hot area is and will report it back to the container in a &lt;span style="font-family: courier new;"&gt;HitTest&lt;/span&gt; - type of function.&lt;br /&gt;&lt;br /&gt;Sample: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/TouchBrowser2.zip"&gt;TouchBrowser2.zip&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-3651703154087088295?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/3651703154087088295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=3651703154087088295' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3651703154087088295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3651703154087088295'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/02/touchbrowser-ii.html' title='TouchBrowser - II'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_AksH5-lumMs/SZ3ekzjJ4wI/AAAAAAAAAbo/oH7QUvxgQII/s72-c/TouchBrowser2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6109781096573722081</id><published>2009-02-11T16:15:00.003Z</published><updated>2009-02-11T16:32:19.383Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>TouchBrowser - I</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_AksH5-lumMs/SZL7Pvb4DsI/AAAAAAAAAbY/49EQjykeM_Q/s1600-h/TouchBrowser.PNG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 240px; height: 320px;" src="http://3.bp.blogspot.com/_AksH5-lumMs/SZL7Pvb4DsI/AAAAAAAAAbY/49EQjykeM_Q/s400/TouchBrowser.PNG" alt="" id="BLOGGER_PHOTO_ID_5301575959218491074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;My planning for the first half of 2009 includes writing a SQL Compact explorer, something like the old isqlw mobile application. One of the components this application needs is a friendly way to select the database files - something along the lines of the open file dialog, only a bit better.&lt;br /&gt;&lt;br /&gt;Towards this end, I picked up the "touch" window code used in the property list and adapted it to a very simple file browser. The sample application that I'm publishing includes a revised version of the atltouch.h file and implements a very simple-minded "file explorer" window.&lt;br /&gt;&lt;br /&gt;You navigate either by scrolling the list or by using the arrow keys. To list a sub folder, just click it or select it and press the enter key. To back up to the previous level, use the main menu "Up" command.&lt;br /&gt;&lt;br /&gt;There are still some issues to be sorted out in this code, like the apparent sensitivity when you start dragging a directory entry up or down - you may end up expanding that directory instead of dragging the list. I have struggled with this issue ever since I started to write this code and I'm starting to believe that a different approach may be needed, like the addition of an action button to the right of each file: only by pressing it will the user get the associated action (opening a sub-folder, for instance). This solution implies having larger list items so that a finger can be effectively used (but this is also an issue with WM devices that are expecting a stylus, not a bulky finger).  I will be investigating these issues and posting the code in the next few posts.&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/TouchBrowser.zip"&gt;TouchBrowser.zip&lt;/a&gt; (27 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6109781096573722081?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6109781096573722081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6109781096573722081' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6109781096573722081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6109781096573722081'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/02/touchbrowser-i.html' title='TouchBrowser - I'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_AksH5-lumMs/SZL7Pvb4DsI/AAAAAAAAAbY/49EQjykeM_Q/s72-c/TouchBrowser.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-3118845336130737131</id><published>2009-02-05T12:18:00.002Z</published><updated>2009-02-06T12:00:39.033Z</updated><title type='text'>Minor bug correction</title><content type='html'>There is a bug in the last version of atltouch.h that causes a debug assertion when the user clicks the empty area of the list. To solve it open the &lt;span style="font-family:courier new;"&gt;atltouch.h&lt;/span&gt; file and look for the &lt;span style="font-family:courier new;"&gt;ActivateItem&lt;/span&gt; method on line 910. Before the last call to &lt;span style="font-family:courier new;"&gt;NotifyItemChange&lt;/span&gt;, insert the following line:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if(IsValidItem(iItem))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Thanks, Vincent!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-3118845336130737131?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/3118845336130737131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=3118845336130737131' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3118845336130737131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3118845336130737131'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/02/minor-bug-correction.html' title='Minor bug correction'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2449595224546156386</id><published>2009-02-04T12:04:00.003Z</published><updated>2009-02-04T12:20:30.831Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Why does CeRapiInitEx return E_INVALIDARG?</title><content type='html'>This was a very hard debugging session. Suddenly I found that while using exactly the same DLLs, &lt;a href="http://www.primeworks-mobile.com/Products/DataPortWizard.html"&gt;Wizard&lt;/a&gt; was failing to open a RAPI connection while &lt;a href="http://www.primeworks-mobile.com/Products/DataPortConsole.html"&gt;Console&lt;/a&gt; was working without any issues. Yes, the code and the binaries were the same. I tried everything, from file and directory rights to the .NET trust, not forgetting the application threading model. Nothing worked: Wizard consistently reported an &lt;span style="font-family:courier new;"&gt;E_INVALIDARG&lt;/span&gt; error when calling &lt;span style="font-family:courier new;"&gt;CeRapiInitEx&lt;/span&gt; (both static and dynamically linked). What to do?&lt;br /&gt;&lt;br /&gt;Out of desperation I called the RAPI initialization code on the main form constructor. Surprise: it works! If I move the code to the button event handler it failed. Then I tried the code on the form load event, only to find that the code also failed. What could be happening between the main form constructor and the form event handling code?&lt;br /&gt;&lt;br /&gt;Wait, let's try the code at the &lt;span style="font-style: italic;"&gt;end&lt;/span&gt; of the main form constructor. &lt;span style="font-style: italic;"&gt;Voilá&lt;/span&gt;, it failed. At the start of the constructor I get an &lt;span style="font-family:courier new;"&gt;S_OK&lt;/span&gt; and at the end I get an &lt;span style="font-family:courier new;"&gt;E_INVALIDARG&lt;/span&gt;. Why? Some time ago I tried to be really smart (lesson: don't try to be smart) and wrote some code that would test the presence of a particular database engine OLE DB &lt;span style="font-family:courier new;"&gt;CLSID&lt;/span&gt; so that the user would see a list of the available engines on her PC. This actually worked badly and instead of dynamically building the UI labels, I went back to static text &lt;span style="font-style: italic;"&gt;but&lt;/span&gt; I forgot to remove the calls. They look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;DPTRACK_API int IsLocalEngineInstalled(GUID guid)&lt;br /&gt;{&lt;br /&gt;   CComPtr&amp;lt;IDBInitialize&amp;gt;    spInitialize;&lt;br /&gt;   HRESULT                   hr;&lt;br /&gt;&lt;br /&gt;   CoInitializeEx(NULL, COINIT_MULTITHREADED);&lt;br /&gt;   hr = CoCreateInstance(guid, NULL, CLSCTX_INPROC_SERVER,&lt;br /&gt;                         IID_IDBInitialize,&lt;br /&gt;                         (void**)&amp;amp;spInitialize);&lt;br /&gt;   CoUninitialize();&lt;br /&gt;&lt;br /&gt;   return SUCCEEDED(hr);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;After removing the calls to this toxic code, Wizard works again! Why is CeRapiInitEx sensitive to COM initialization?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2449595224546156386?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2449595224546156386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2449595224546156386' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2449595224546156386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2449595224546156386'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/02/why-does-cerapiinitex-returns.html' title='Why does CeRapiInitEx return E_INVALIDARG?'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2927088029644445277</id><published>2009-02-03T09:16:00.003Z</published><updated>2009-02-03T09:31:10.273Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Property List Notifications</title><content type='html'>In my &lt;a href="http://nativemobile.blogspot.com/2009/01/property-list.html"&gt;last post&lt;/a&gt; I presented a custom control based on the previously published &lt;span style="font-family:courier new;"&gt;CTouchWindow&lt;/span&gt; WTL class. In this post I'm updating the code to support individual item enabling and disabling and also to illustrate how the client code can manage item notifications.&lt;br /&gt;&lt;br /&gt;Each &lt;span style="font-family:courier new;"&gt;CTouchListItem&lt;/span&gt; (the base class for &lt;span style="font-family:courier new;"&gt;CPropertyListItem&lt;/span&gt;) now supports two new functions to control and report the enabled state: &lt;span style="font-family:courier new;"&gt;SetEnabled&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;IsEnabled&lt;/span&gt;. After changing the item state your code will have to update the item in order to reflect its updated status (this is very likely to change in the near future).&lt;br /&gt;&lt;br /&gt;The new sample code now implements a very simple notification handling mechanism that tests the check state of the check box. This is done in the dialog's &lt;span style="font-family:courier new;"&gt;OnItemActivated&lt;/span&gt; method, called after a particular item is activated or deactivated. In this case, I test if the activated item is the check box item and enable or disable the second group (collapsing it when disabling).&lt;br /&gt;&lt;br /&gt;As always, comments are welcome!&lt;br /&gt;&lt;br /&gt;Sample: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/PropList2.zip"&gt;PropList2.zip&lt;/a&gt; (46 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2927088029644445277?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2927088029644445277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2927088029644445277' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2927088029644445277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2927088029644445277'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/02/property-list-notifications.html' title='Property List Notifications'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4332306111624746766</id><published>2009-01-21T14:06:00.006Z</published><updated>2009-01-21T14:52:40.323Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>The Property List</title><content type='html'>Before I can go any further in the development of the SQL Explorer device application, I must make sure that I have some components ready for use. These will include (but will not be limited to):&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A tree component to display the database schema;&lt;/li&gt;&lt;li&gt;A property list control to edit/display object properties such as connection, table and column properties;&lt;/li&gt;&lt;li&gt;A grid or table-like display for table and query results;&lt;/li&gt;&lt;li&gt;A splitter control for compound views;&lt;/li&gt;&lt;li&gt;A decent file open dialog box.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It surely would be easy to just use the controls that Windows Mobile has in store for us: the tree view and the list view. These are undoubtedly the most used controls but are somewhat &lt;em&gt;déja-vu&lt;/em&gt; and are arguably hard to use (especially the list view). I decided to (guess what) write these controls from scratch using something the WTL &lt;span style="font-family:courier new;"&gt;&lt;a href="http://nativemobile.blogspot.com/2008/08/touch-list-ii.html"&gt;CTouchWindow&lt;/a&gt;&lt;/span&gt; class that I published here a some months ago.&lt;/p&gt;&lt;p&gt;This class is a nice candidate to be a base class for the new tree, grid and property list controls because it enables a touch-like interface. My first approach was to implement the property list control taking some of my previous work as a model: &lt;a href="http://www.codeproject.com/KB/mobile/FormListSample.aspx"&gt;A list-based form for Windows Mobile&lt;/a&gt;. There are two nagging issues with this code: it uses MFC and subclasses the list view control. As I've learned by implementing the WTL version I'm presenting here, subclassing and custom-painting the list view is more work than you need to implement the control.&lt;/p&gt;&lt;p&gt;&lt;a href="http://1.bp.blogspot.com/_AksH5-lumMs/SXcwrCKrtFI/AAAAAAAAAa4/lXRewxzfVfk/s1600-h/PropList1.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5293753402871493714" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 240px; CURSOR: hand; HEIGHT: 320px" alt="" src="http://1.bp.blogspot.com/_AksH5-lumMs/SXcwrCKrtFI/AAAAAAAAAa4/lXRewxzfVfk/s400/PropList1.png" border="0" /&gt;&lt;/a&gt; The property list is shown here contains a list of editable items and groups. Groups are shown as collapsed (the + sign indicates that the item can be expanded) and, like the original MFC implementation, each group can contain only editable items, not other goups (I may change this later on). &lt;/p&gt;&lt;p&gt;A group should be used as a means to group related data items and to ease the list navigation. When clicked the group expands to display the contained editable items. By clicking again, the group collapses and hides the contained items. This is the same principle that you can see at work with a tree, so extending this concept to a "touch tree" should not be very difficult.&lt;/p&gt;&lt;p&gt;Each editable item may be in either of two states: focused or activated. An item gets the focus when it is clicked and when either the up or down keys are used to change the selection. A focused item shows the focus rectangle around it. When the enter key is pressed (or when the user clicks the item) it is activated (note that activating implies setting the focus). The notable exception to this rule is the text editor item that activates itself when it receives the focus.&lt;/p&gt;&lt;p&gt;When an item is activated, it generally creates a Windows control to perform the editing. The exceptions to this rule are the check box (changes its state) and the group item (expands / collapses the contained items).&lt;/p&gt;&lt;p&gt;As of this implementation, the supported data item types are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Text editor&lt;/li&gt;&lt;li&gt;Date time editor&lt;/li&gt;&lt;li&gt;Check box&lt;/li&gt;&lt;li&gt;Combo box&lt;/li&gt;&lt;/ul&gt;Here is the expanding property list:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_AksH5-lumMs/SXcz16kmTwI/AAAAAAAAAbA/2o_jQ2JQOkQ/s1600-h/PropList2.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5293756888346152706" alt="" src="http://3.bp.blogspot.com/_AksH5-lumMs/SXcz16kmTwI/AAAAAAAAAbA/2o_jQ2JQOkQ/s400/PropList2.png" border="0" /&gt;&lt;/a&gt; &lt;a href="http://3.bp.blogspot.com/_AksH5-lumMs/SXc0CMF9wTI/AAAAAAAAAbI/iHrYL4wCO98/s1600-h/PropList3.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5293757099207934258" alt="" src="http://3.bp.blogspot.com/_AksH5-lumMs/SXc0CMF9wTI/AAAAAAAAAbI/iHrYL4wCO98/s400/PropList3.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The scroll bar to the right is custom-painted and is not yet the final version (I'm still thinking about allowing the use of old style scroll bars). The advantage of this type of scroll bar is its transparency - you can actually read what's beneath it so you do get a few more pixels of screen real estate.&lt;br /&gt;&lt;br /&gt;I will make lots of changes and additions to this code but, in the meantime, please do take a look at it and be so kind as to use it and criticize it.&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/PropList.zip"&gt;PropList.zip&lt;/a&gt; (45 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4332306111624746766?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4332306111624746766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4332306111624746766' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4332306111624746766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4332306111624746766'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/01/property-list.html' title='The Property List'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_AksH5-lumMs/SXcwrCKrtFI/AAAAAAAAAa4/lXRewxzfVfk/s72-c/PropList1.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5607710236457180955</id><published>2009-01-09T11:07:00.004Z</published><updated>2009-01-09T11:22:39.857Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Enumerating Unique Constraints</title><content type='html'>There's no big deal about getting the list of UNIQUE constraints - they get listed as indexes by the &lt;span style="font-family:courier new;"&gt;CIndexesRowset&lt;/span&gt; class. When using this schema rowset you get everything that is implemented as an index by the database engine:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Indexes&lt;/li&gt;&lt;li&gt;Primary Key constraints&lt;/li&gt;&lt;li&gt;Unique constraints&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;While the schema rowset can distinguish between a regular index and a PRIMARY KEY, there's no telling if the listed index is a UNIQUE constraint or not. To correct this, you must first list all the UNIQUE constraints using the new &lt;span style="font-family:courier new;"&gt;CTableDefinition::FillUniqueArray&lt;/span&gt; method (see the updated sample below). As you can see, a unique index is also represented by a CIndex object, but stored in a different collection in the &lt;span style="font-family:courier new;"&gt;CTableSchema&lt;/span&gt; class. When the indexes are finally enumerated, the list is filtered for known UNIQUE constraints.&lt;br /&gt;&lt;br /&gt;Another addition to the sample code is the ability to open any SQL Compact database on your device by using the Menu / Open sequence. The code that opens the database uses the installed SQL Compact OLE DB engines to "sense" the correct database format (see the updated &lt;span style="font-family:courier new;"&gt;CSchemaTreeFrame::OpenDataSource&lt;/span&gt; method).&lt;br /&gt;&lt;br /&gt;On the next post I will start building the SQL Compact Explorer application by using this sample as a starting point. I will also use this application to bring back some of the code that I have been working on, namely the touch list and all the derivatives that have been developed but left unpublished.&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/SchemaTree4.zip"&gt;SchemaTree4.zip&lt;/a&gt; (155 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5607710236457180955?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5607710236457180955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5607710236457180955' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5607710236457180955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5607710236457180955'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/01/enumrating-unique-constraints.html' title='Enumerating Unique Constraints'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-1654472424820363705</id><published>2009-01-06T22:48:00.002Z</published><updated>2009-01-06T22:55:29.258Z</updated><title type='text'>Windows Mobile VM Article</title><content type='html'>A very interesting article about Windows Mobile Virtual Memory has just turned up on Code Project:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/KB/mobile/VirtualMemory.aspx"&gt;Visualizing the Windows Mobile Virtual Memory Monster&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Not only this is a worthwhile read, you will also get a couple of links into the Windows Mobile RSS (Reed and Steve Stuff) Feed blog where the Windows Mobile virtual memory manager is discussed.&lt;br /&gt;&lt;br /&gt;On my next post I will publish the revised version of the SchemaTree sample with a few additions, like the ability to open any SQL Compact database on the device. From then on, the project will be renamed and I will start building an on-device SQL Compact explorer application. In native code, of course!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-1654472424820363705?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/1654472424820363705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=1654472424820363705' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1654472424820363705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1654472424820363705'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2009/01/windows-mobile-vm-article.html' title='Windows Mobile VM Article'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-9059366682067346585</id><published>2008-12-19T10:52:00.002Z</published><updated>2008-12-19T11:35:26.901Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Enumerating Foreign Key Constraints</title><content type='html'>After enumerating columns and indexes, now it's time to work on the first of the three types of constraints that are supported by SQL Compact: foreign key constraints. Constraint definitions are also retrieved by calling &lt;span style="font-family:courier new;"&gt;ITableCreation:.GetTableDefinition&lt;/span&gt;. These are returned in an array of &lt;span style="font-family:courier new;"&gt;DBCONSTRAINTDESC&lt;/span&gt; structures that contain all the supported constraints. Each record contains one constraint whose type is stored on the &lt;span style="font-family:courier new;"&gt;ConstraintType&lt;/span&gt; member. The SQL Compact header file defines the following values:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;DBCONSTRAINTTYPE_UNIQUE&lt;/span&gt; - A unique constraint.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;DBCONSTRAINTTYPE_FOREIGNKEY&lt;/span&gt; - A foreign key constraint.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;DBCONSTRAINTTYPE_PRIMARYKEY&lt;/span&gt; - A primary key constraint.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;DBCONSTRAINTTYPE_CHECK&lt;/span&gt; - A check constraint (not supported by the current SQL Compact versions)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;DBCONSTRAINTTYPE_SSCE_DEFAULT&lt;/span&gt; - Apparently this is a default value constraint. I have found no documentation about this constant and will investigate it later.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;For now, we concentrate on the foreign key constraints and how to show them on the &lt;span style="font-family:courier new;"&gt;SchemaTree&lt;/span&gt; sample aplpication. In this version of tha sample, foreign keys will be displayed in a folder of their own, but for future versions this folder will be renamed "Constraints" and will contain all table contraints, not just foreign keys.&lt;br /&gt;&lt;br /&gt;A foreign key definition is stored in the new &lt;span style="font-family:courier new;"&gt;CForeignKey&lt;/span&gt; class. You can see these classes being built from the array of &lt;span style="font-family:courier new;"&gt;DBCONSTRAINTDESC&lt;/span&gt; structures in the new &lt;span style="font-family:courier new;"&gt;CTableDefinition::FillForeignKeyArray&lt;/span&gt; function, where each array item is tested for the correct type and then fed to the &lt;span style="font-family: courier new;"&gt;CForeignKey&lt;/span&gt; class constructor, where all thework takes place. Each foreign key contains a list of matched columns from the reference table and the base table (each pair is stored in an instance of the &lt;span style="font-family: courier new;"&gt;CForeignKeyPair&lt;/span&gt; class).&lt;br /&gt;&lt;br /&gt;Displaying these in the schema tree is quite straightforward and follows the same rules I have used for columns and indexes. Please note that there are new accessors for foreign keys on the &lt;span style="font-family: courier new;"&gt;CTableSchema&lt;/span&gt; class.&lt;br /&gt;&lt;br /&gt;On my next post I will also enumerate primary keys and unique constraints, put them all under the same folder and start moving towards an on-device SQL Compact editor. I already got a name suggestion from &lt;a href="http://msmvps.com/blogs/albertosilva/default.aspx"&gt;Alberto Silva&lt;/a&gt;: SQL Explorer. More names, anyone?&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/SchemaTree3.zip"&gt;SchemaTree3.zip&lt;/a&gt; (1.2 MB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-9059366682067346585?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/9059366682067346585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=9059366682067346585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/9059366682067346585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/9059366682067346585'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/12/enumerating-foreign-key-constraints.html' title='Enumerating Foreign Key Constraints'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-7018840282921137566</id><published>2008-12-13T15:29:00.002Z</published><updated>2008-12-13T15:36:42.271Z</updated><title type='text'>Native Pointers</title><content type='html'>No, I'm not talking about memory addresses, just interesting bits of information for the Native Mobile developer.&lt;br /&gt;&lt;br /&gt;MSDN forums have recently moved to a new platform and got new URLs. Here are my favorites:&lt;br /&gt;&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/vssmartdevicesnative/threads/"&gt;Visual Studio Smart Device Development - Native C++ Project&lt;/a&gt;&lt;br /&gt;&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/sqlce/threads/"&gt;SQL Server Compact&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;On another note, Christopher Fairbairn just wrote another &lt;a href="http://www.christec.co.nz/blog/archives/361"&gt;great post in his blog&lt;/a&gt; where he discusses some very cool techniques for Native Mobile developers, such as playing sound, using COM and displaying PNG images. A must read!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-7018840282921137566?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/7018840282921137566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=7018840282921137566' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7018840282921137566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7018840282921137566'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/12/native-pointers.html' title='Native Pointers'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2130873182732913820</id><published>2008-12-11T10:23:00.002Z</published><updated>2008-12-11T10:34:18.704Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ATL'/><title type='text'>Code changes</title><content type='html'>After a second look at the array &lt;span style="font-family: courier new;"&gt;CAtlArray&lt;t&gt;&lt;/span&gt; implementation, I'm planning to change all the containers from value to pointer (instead of &lt;span style="font-family: courier new;"&gt;CAtlArray&lt;ccolumn&gt;&lt;/span&gt;, I will change this to &lt;span style="font-family: courier new;"&gt;CAtlArray&lt;ccolumn*&gt;&lt;/span&gt;). The reason is quite simple: when growing the buffer through &lt;span style="font-family: courier new;"&gt;Add&lt;/span&gt;, the existing items are moved to the new buffer with a simple &lt;span style="font-family: courier new;"&gt;Checked::memmove_s&lt;/span&gt; call. The contained class copy constructor is not called which may lead to memory leaks (depending on the contained class implementation). If the array merely contains pointers, everything works as expected and all memory relocations will be much faster (only the pointers are copied, not the objects themselves). The downsidr to this approach is that I will have to manually implement the code to release all the objects pointed to by the array.&lt;br /&gt;&lt;br /&gt;Finally, don't miss this great post on the Windows Mobile Team Blog: &lt;a href="http://blogs.msdn.com/windowsmobile/archive/2008/12/08/uninstalling-applications-programmatically-in-windows-mobile.aspx"&gt;Uninstalling Applications Programmatically in Windows Mobile&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2130873182732913820?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2130873182732913820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2130873182732913820' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2130873182732913820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2130873182732913820'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/12/code-changes.html' title='Code changes'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2740263534159684654</id><published>2008-12-10T14:55:00.002Z</published><updated>2008-12-10T15:25:28.948Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>The perfect time-waster</title><content type='html'>Reinventing the wheel. That's what I have been doing for the last few days implementing object arrays in C++... Why? Apparently some template classes are not very easily exportable on a DLL so you cannot use useful stuff like &lt;span style="font-family: courier new;"&gt;CString&lt;/span&gt; or &lt;span style="font-family: courier new;"&gt;CAtlArray&lt;/span&gt; as exported class members. After having implemented a very simple string class and while working on object array allocation I decided it was enough: from now on the OLE DB Client library will not live in a DLL but either on a LIB or embedded in the client project. Enough is enough - I want to move ahead and implement the cool stuff, not arrays and strings so that the damned thing can be neatly exported as a DLL.&lt;br /&gt;&lt;br /&gt;The code I'm presenting today has some additions to the OLE DB Client library, namely some new schema-related classes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;CSchema&lt;/span&gt; - Contains an array of table &lt;span style="font-family: courier new;"&gt;CTableSchema&lt;/span&gt; objects and a reference to a &lt;span style="font-family: courier new;"&gt;CSession&lt;/span&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;CTableSchema&lt;/span&gt; - Contains a table schema information. This class is prepared to load this information on demand in order to avoid a performance penalty when enumerating the database schema (all tables are loaded and each table schema is loaded on demand).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;CTableDefinition&lt;/span&gt; - Helper class that loads the table definition in a single OLE DB call. This populates the columns and constraints collections. Indexes are loaded separately through a specialized schema rowset (see the &lt;span style="font-family: courier new;"&gt;LoadIndexes&lt;/span&gt; method).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;CColumn&lt;/span&gt; - Contains column schema information.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;CIndex&lt;/span&gt; - Contains index schema information and a list of index columns.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;CIndexColumn&lt;/span&gt; - An individual index column.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Please note that some of these classes will change in content and placement (I mean the .cpp file).&lt;br /&gt;&lt;br /&gt;The sample project is the same - it enumerates in a tree the schema of the sample database placed on the device root. As you can see from the code, the tree lazily loads the table schema information (when the user expands either the "Columns" or the "Indexes" folder).&lt;br /&gt;&lt;br /&gt;After loking a bit at this sample and to how the OLE DB Client has evolved, I started wondering about writing a "Query Analyzer" type of application. This would mimick most of the "old" SQL Compact Query Analyzer application and would add a few more features. Writing this application would require development in other areas such as the user interface, but I think that it will be a very interesting challenge.&lt;br /&gt;&lt;br /&gt;What features would you like to see in the open source QA? What name would you give such app?&lt;br /&gt;&lt;br /&gt;Sample: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/SchemaTree2.zip"&gt;SchemaTree2.zip&lt;/a&gt; (1.21 MB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2740263534159684654?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2740263534159684654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2740263534159684654' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2740263534159684654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2740263534159684654'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/12/perfect-time-waster.html' title='The perfect time-waster'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4947039498160882192</id><published>2008-12-02T21:54:00.006Z</published><updated>2008-12-03T09:50:06.956Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Enumerating Columns with IDBSchemaRowset</title><content type='html'>While it's freezing out there (for Lisbon standards, of course) I have been busy working on the schema enumeration code for the OLE DB Client library. My first approach is to enumerate database tables and columns using the &lt;a href="http://msdn.microsoft.com/en-us/library/ms713686%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;IDBSchemaRowset&lt;/span&gt;&lt;/a&gt; interface. Access to this interface is encapsulated in the &lt;span style="font-family:courier new;"&gt;CRowsetInterface&lt;/span&gt; class that is derived in &lt;span style="font-family:courier new;"&gt;CTablesRowset&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;CColumnsRowset&lt;/span&gt; classes to enumerate tables and columns respectively. The &lt;span style="font-family:courier new;"&gt;IDBSchemaRowset&lt;/span&gt; interface works by accepting a set of "restrictions" and generates a schema rowset containing the requested data. Schema rowsets are formally defined on the &lt;a href="http://msdn.microsoft.com/en-us/library/ms712921%28VS.85%29.aspx"&gt;Appendix B of the OLE DB Programmer's Guide&lt;/a&gt;, where you can see the returned columns and the accepted "restrictions". SQL Compact implements a subset of these, as described in the &lt;a href="http://msdn.microsoft.com/en-us/library/ms174100.aspx"&gt;BOL&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Using the &lt;span style="font-family:courier new;"&gt;CTablesRowset&lt;/span&gt; is quite easy (and you have seen it at work in a previous sample where it was used to test for the presence of a given table):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CTablesRowset tables(m_session);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CRowset rowset;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;HRESULT hr;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;hr = tables.Open(NULL, NULL, NULL, NULL, rowset);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;The first four NULL parameters mean that you don't want to filter on any of the supported restrictions, so you will get a list of all the tables in the database. SQL Compact does not support table catalogs nor table schemas so the first two parameters are always NULL for this provider. The third restriction is the table name and the fourth is the table type (see the possible values for this in the &lt;a href="http://msdn.microsoft.com/en-us/library/ms716980%28VS.85%29.aspx"&gt;TABLES schema rowset reference&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;When scrolling through the tables rowset, you retrieve the current table name like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CString strTable;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;rowset.GetValue(3, strTable);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now that we have the table name, we can enumerate its columns by using the CColumnsRowset and imposing a restriction on the table name (see the &lt;a href="http://msdn.microsoft.com/en-us/library/ms723052%28VS.85%29.aspx"&gt;COLUMNS schema rowset reference&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CColumnsRowset columns(m_session);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CRowset rsColumns;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;hr = columns.Open(NULL, NULL, strTable, NULL, rsColumns);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This retrieves all columns from the given table and you can get the column name from ordinal 4. As you can see from the COLUMNS schema rowset, there are lots of additional schema information about a column, like its OLE DB type, "nullability", size and more.&lt;br /&gt;&lt;br /&gt;Although this is a quite convenient way to retrieve a table schema, we can use another OLE DB interface that in a single call returns column and constraint information. On the next post, I will look at &lt;span style="font-family:courier new;"&gt;ITableCreation&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Sample code:&lt;br /&gt;&lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/SchemaTree.zip"&gt;SchemaTree.zip&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/OleDbClientLib2.zip"&gt;OleDbClientLib2.zip&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4947039498160882192?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4947039498160882192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4947039498160882192' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4947039498160882192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4947039498160882192'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/12/enumerating-columns-with-ischemarowset.html' title='Enumerating Columns with IDBSchemaRowset'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4884825525924835060</id><published>2008-11-24T11:32:00.003Z</published><updated>2008-11-24T11:36:56.495Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='MSDN Magazine'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Connection Manager Article</title><content type='html'>The latest issue of &lt;a href="http://msdn.microsoft.com/en-us/magazine/default.aspx"&gt;MSDN Magazine&lt;/a&gt; is out and it features a great article from Marcus Perryman: &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd263096.aspx"&gt;Going Places: How Connection Manager Connects&lt;/a&gt;. The reason why I'm also referring to this article here is that its code samples are in C, a rarity these days.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4884825525924835060?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4884825525924835060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4884825525924835060' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4884825525924835060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4884825525924835060'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/11/connection-manager-article.html' title='Connection Manager Article'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4926931439099171673</id><published>2008-11-23T16:40:00.003Z</published><updated>2008-11-23T17:14:17.390Z</updated><title type='text'>SQL Compact Schemas</title><content type='html'>Now that I have looked into the most basic principles of using a SQL Compact database from native code (base table cursors and command execution), I will now look at the available tools to enumerate and manipulate the database schema. There are essentially two ways to go about this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;SQL commands&lt;/li&gt;&lt;li&gt;OLE DB interfaces&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Using SQL commands&lt;/span&gt;&lt;br /&gt;This may be the easiest approach and is also language-independent - you can use these techniques from both native and managed code. To determine what's in your database you can execute &lt;span style="font-family: courier new;"&gt;SELECT&lt;/span&gt; commands against the &lt;a href="http://msdn.microsoft.com/en-us/library/ms174156.aspx"&gt;&lt;span style="font-family: courier new;"&gt;INFORMATION_SCHEMA&lt;/span&gt;&lt;/a&gt; system views. These work like regular &lt;span style="font-family: courier new;"&gt;SELECT&lt;/span&gt; commands and return specific rowsets:&lt;br /&gt;&lt;ul&gt;&lt;li style="font-family: courier new;"&gt;COLUMNS&lt;/li&gt;&lt;li style="font-family: courier new;"&gt;INDEXES&lt;/li&gt;&lt;li style="font-family: courier new;"&gt;KEY_COLUMN_USAGE&lt;/li&gt;&lt;li style="font-family: courier new;"&gt;PROVIDER_TYPES&lt;/li&gt;&lt;li style="font-family: courier new;"&gt;TABLES&lt;/li&gt;&lt;li style="font-family: courier new;"&gt;TABLE_CONSTRAINTS&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;REFERENTIAL_CONSTRAINTS&lt;/span&gt; (not documented for 2.0)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;To retrieve information from one of these views, you just execute a simple query like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;SELECT * FROM INFORMATION_SCHEMA.TABLES&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This will return all tables in your database. The advantage of using a &lt;span style="font-family: courier new;"&gt;SELECT&lt;/span&gt; command is that you can add a &lt;span style="font-family: courier new;"&gt;WHERE&lt;/span&gt; clause and filter the result. If you need to make changes to your database schema you can use all the supported DDL commands. Since version 3.0 came out, Microsoft even provided us with a stored procedure to rename tables: &lt;a href="http://msdn.microsoft.com/en-us/library/bb726044.aspx"&gt;&lt;span style="font-family: courier new;"&gt;sp_rename&lt;/span&gt;&lt;/a&gt;. Unfortunately you cannot rename columns which sometimes is needed.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Using OLE DB interfaces&lt;/span&gt;&lt;br /&gt; All of this (and a bit more) can also be done through some of the exposed OLE DB interfaces, namely the following Session interfaces:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;IDBSchemaRowset&lt;/span&gt; - Generates rowsets that are similar to the ones returned by the &lt;span style="font-family: courier new;"&gt;INFORMATION_SCHEMA&lt;/span&gt; views.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;IIndexDefinition&lt;/span&gt; - Creates and drops indexes.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;ITableCreation&lt;/span&gt; - Retrieves the table definition (full schema).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;ITableDefinition&lt;/span&gt; - Creates drops tables, adds and drops columns.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;ITableDefinitionWithConstraints&lt;/span&gt; - Same as above, but also manages table constraints.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;IAlterIndex&lt;/span&gt; - Only renames indexes in SQL Compact.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: courier new;"&gt;IAlterTable&lt;/span&gt; - Allows changing table properties like the table name, column defaults and identity properties. You can also use this interface to rename columns (not available in managed code).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Note that when using these interfaces, you are accessing the storage engine directly, circumventing the Query Processor.&lt;br /&gt;&lt;br /&gt;On my next post I'm planning to publish a sample that illustrates how to use these interfaces.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4926931439099171673?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4926931439099171673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4926931439099171673' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4926931439099171673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4926931439099171673'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/11/sql-compact-schemas.html' title='SQL Compact Schemas'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4239879933001699904</id><published>2008-11-20T14:54:00.003Z</published><updated>2008-11-20T14:56:12.108Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='User Interface'/><title type='text'>Logo Certification Article</title><content type='html'>Here's a &lt;a href="http://www.codeproject.com/KB/mobile/logohelper.aspx"&gt;very nice article&lt;/a&gt; for native mobile developers that addresses the required coding for some of the strict Windows Mobile Logo Certification. A worthwhile read.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4239879933001699904?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4239879933001699904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4239879933001699904' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4239879933001699904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4239879933001699904'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/11/logo-certification-article.html' title='Logo Certification Article'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5503873986708997634</id><published>2008-11-18T11:09:00.005Z</published><updated>2008-11-20T14:01:40.403Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Implementing SQL Compact Command Parameter BLOBs</title><content type='html'>After much ramblings, tests and misconceptions, I finally closed the chapter on SQL Compact command parameters. The sample code (see below) illustrates how to use a BLOB command parameter using the "variable length" binding buffer. Whenever the total size of the columns exceeds the allocated binding buffer size, the binding process is repeated increasing the binding buffer size. Although this is not an optimal solution (being able to use storage objects for this purpose would be much better), it frees you from having to specify the maximum size for BLOB parameters - the code calculates this for you.&lt;br /&gt;&lt;br /&gt;Before you can execute a command with parameters, you &lt;span style="font-style: italic;"&gt;must&lt;/span&gt; prepare it by calling the &lt;span style="font-family:courier new;"&gt;Prepare &lt;/span&gt;method (failing to do so will cause a run-time error). Here the code determines the number of existing parameters and allocates memory for a "user buffer". This user buffer is an array of &lt;span style="font-family:courier new;"&gt;CDbValue&lt;/span&gt; objects, a &lt;span style="font-family:courier new;"&gt;VARIANT&lt;/span&gt;-like class whose sole purpose is to store parameter values. When the user sets a parameter it is first written to one of these objects and upon execution it is copied to the data buffer. Meanwhile, the code determines if the new set of parameters on the &lt;span style="font-family:courier new;"&gt;CDbValue&lt;/span&gt; array requires rebinding, does so if needed and finally copies the values to the data buffer. This way you just have to set the parameters and execute the command (see the sample code).&lt;br /&gt;&lt;br /&gt;As a side-effect of all these travails, I ended up creating a new class - &lt;span style="font-family:courier new;"&gt;CDbValueRef&lt;/span&gt; - from which &lt;span style="font-family:courier new;"&gt;CDbValue&lt;/span&gt; derives that I use as the "engine" that sets and gets data from various types, performing the necessary data type conversions. As you can now see, the column data access on the &lt;span style="font-family:courier new;"&gt;CRowset&lt;/span&gt; class is performed through an array of such objects that directly reference the bound data buffer, and they know how to handle storage object BLOBs. Now you can access your &lt;span style="font-family:courier new;"&gt;CRowset&lt;/span&gt; data using a type-safe interface.&lt;br /&gt;&lt;br /&gt;Sample: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/InsertBlob.zip"&gt;InsertBlob.zip&lt;/a&gt; (152 KB)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5503873986708997634?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5503873986708997634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5503873986708997634' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5503873986708997634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5503873986708997634'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/11/implemeting-sql-compact-command.html' title='Implementing SQL Compact Command Parameter BLOBs'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6066365909870251731</id><published>2008-11-17T17:27:00.003Z</published><updated>2008-11-17T18:14:54.579Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>I was right...</title><content type='html'>... for the wrong reasons. In fact, you cannot use storage objects to set BLOB command parameters. I found that the usual mechanism does not work because:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;When retrieving command parameter information through &lt;span style="font-family:courier new;"&gt;GetParameterInfo&lt;/span&gt;, you don't get the &lt;span style="font-family:courier new;"&gt;DBPARAMFLAGS_ISLONG&lt;/span&gt; bit set for BLOBs;&lt;/li&gt;&lt;li&gt;Binding a BLOB parameter through a storage object causes the &lt;span style="font-family:courier new;"&gt;Execute&lt;/span&gt; method to fail reporting a &lt;span style="font-family:courier new;"&gt;DBSTATUS_E_CANTCONVERTVALUE&lt;/span&gt; on the BLOB column.&lt;/li&gt;&lt;/ol&gt;So I had to revert to the old code that buffers the parameter values in a buffer and forces a rebind when the new set of parameters is larger than the old parameter buffer (used by the accessor). Now that I got this straight, it's time to finish the new demo that inserts BLOBs using a parametrized &lt;span style="font-family:courier new;"&gt;INSERT&lt;/span&gt; command. Please stay tuned for the next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6066365909870251731?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6066365909870251731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6066365909870251731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6066365909870251731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6066365909870251731'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/11/i-was-right.html' title='I was right...'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6123309927895349674</id><published>2008-11-13T21:26:00.009Z</published><updated>2008-11-13T21:48:46.572Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>I was wrong</title><content type='html'>Tomorrow I will deliver (using the English language) my second presentation in an international Microsoft conference. My first time ever was in 2005 in Nice for the now defunct MEDC (Mobile and Embedded Developers Conference). I have been splitting my time in attending interesting presentations, preparing my own presentation and completing the OLE DB Client library code. It was while working some final details of the presentation that I had an epiphany: I was wrong about BLOB command parameters!&lt;br /&gt;&lt;br /&gt;The fact that the OLE DB specification limits us to using just one parameter accessor handle to set all the parameters does &lt;span style="font-style: italic; font-weight: bold;"&gt;not&lt;/span&gt; mean that we are unable to use storage objects. Why? When I discussed the limitation of the SQL Compact engine that prevents it to create more than one storage object at the same time, it actually applies to when the data flows from the provider to the consumer, like when you are reading data from a base table cursor or from a query cursor. It does not apply to when data flows &lt;span style="font-style: italic;"&gt;from the consumer to the provider&lt;/span&gt;. In fact, we experienced no such limitation when inserting or updating data through a base table cursor. The consumer application can create as many storage object as it pleases to, and this is the exact same situation with command parameters: the consumer application can only write to them because SQL Compact does not support output parameters.&lt;br /&gt;&lt;br /&gt;Right now this is still a theory that seems to make a lot of sense to me and I will focus now on proving it right. Meanwhile, I developed a new set of classes to manage column values in such a way that they would do double duty when used on a rowset and on command parameters. For the latter, these classes would work as intermediate data buffers that would be used as temporary storage for application-provided parameter data. When needed, the &lt;span style="font-family:courier new;"&gt;CCommand&lt;/span&gt; code would bind these to a real data buffer, recreating the accessor handle when needed. In fact, I have just tested the code and it works... But this can't be right. If I can bind the parameters before setting them (just like in the &lt;span style="font-family:courier new;"&gt;CRowset&lt;/span&gt; class) then I will have the best solution.&lt;br /&gt;&lt;br /&gt;Back to the drawing board. (If you want to see the code as it is, please drop me a line.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6123309927895349674?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6123309927895349674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6123309927895349674' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6123309927895349674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6123309927895349674'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/11/i-was-wrong.html' title='I was wrong'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5333746411541690701</id><published>2008-10-31T11:53:00.003Z</published><updated>2008-10-31T15:31:10.737Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><title type='text'>SQL Compact Command Parameter BLOBs</title><content type='html'>The problem &lt;span style="font-style: italic;"&gt;du jour&lt;/span&gt; is to make the &lt;span style="font-family:courier new;"&gt;CCommand&lt;/span&gt; class accept BLOB parameters, something that I have been thinking about the last week or so. Let me recap what's at stake.&lt;br /&gt;&lt;br /&gt;When executing a SQL command with parameters, the OLE DB standard allows only for a single accessor handle to be provided by the consumer. This accessor handle is created to bind the command parameter data to a data buffer, just like in a normal rowset. By just having one accessor to handle bind the whole set of parameters means that we cannot bind more than one BLOB with SQL Compact, due to its OLE DB provider limitations. In order to have a general solution, we must bind the BLOB parameter as regular columns &lt;span style="font-style: italic;"&gt;but&lt;/span&gt; we must know how much memory to allocate for each BLOB parameter, and for each instance of the command execution.&lt;br /&gt;&lt;br /&gt;After some thought I concluded that there are two acceptable approaches:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Ask the user to provide maximum acceptable size for each BLOB. This is what the ADO .NET provider does and essentially delegates this responsibility to the user. Do you know in advance what is the maximum size of each BLOB that you are going to feed as a parameter? If so this is acceptable, if not... The great advantage of this approach is that you can make an &lt;span style="font-style: italic;"&gt;apriori&lt;/span&gt; parameter binding (and make it only once).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Be smart about it and recreate the binding when needed. This requires keeping track of the current BLOB binding sizes and increasing the binding array when needed. This approach frees the user from having to specify a maximum size for the BLOB columns but requires that the binding be rebuilt when a larger BLOB is used.&lt;/li&gt;&lt;/ol&gt;Because the second option seems to be hardest to implement, that is exactly the one I chose. See you in the next post with the code!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5333746411541690701?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5333746411541690701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5333746411541690701' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5333746411541690701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5333746411541690701'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/sql-compact-command-parameter-blobs.html' title='SQL Compact Command Parameter BLOBs'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6450754954974860376</id><published>2008-10-23T15:29:00.002+01:00</published><updated>2008-10-23T16:52:48.529+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>SQL Compact Command Parameters - II</title><content type='html'>After a bit of work, here's the new version of the OLE DB Client library with basic support for command parameters. The sample code implements a very simple query:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;SELECT * FROM Customers WHERE Country = @c&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and executes it by setting the parameter value to 'Germany' (using the same sample database).&lt;br /&gt;&lt;br /&gt;The first change you will see in the sample code is that I downgraded the solution to VS 2005 format due to some requests to do so. VS 2008 users can easily upgrade the solution, so this is a minor issue. For convenience, I'm also packaging everything in a single ZIP file. Also, all the samples from now on will deploy to the same device directory (typically in &lt;span style="font-family: courier new;"&gt;\Program Files\OleDbClient&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Executing a SQL Compact command with parameters is quite simple. In a nutshell:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;command.SetText(pszCommand);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;hr = command.Prepare();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;if(FAILED(hr)) ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;command.SetParam(1, _T("Germany"));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;hr = command.Execute(rowset);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Remember from my last post that parameterized commands must be prepared before executing. If you look under the hood, you will see that parameters are bound (using code very similar to &lt;span style="font-family: courier new;"&gt;CRowset&lt;/span&gt;'s column binding code) in the &lt;span style="font-family: courier new;"&gt;Prepare&lt;/span&gt; method. You can only set command parameter values after the &lt;span style="font-family: courier new;"&gt;Prepare&lt;/span&gt; method executes successfully.&lt;br /&gt;&lt;br /&gt;This code still has some limitations, and the most notable one is the inability to handle BLOB parameters. When executing SQL commands, the OLE DB provider only accepts one accessor handle to bind all parameters. As we have seen in previous posts, this prevents us from binding more than one BLOB parameter. The only solution I devised for this when using the ATL OLE DB Consumer Templates was to force the BLOB parameters to have a maximum lenght and bind them as regular columns. Of course, this implies a change to the parameter binding code and some user intervention...&lt;br /&gt;&lt;br /&gt;Sample code: &lt;a href="http://www.primeworks.eu/Downloads/CodeProject/OleDbClientLib.zip"&gt;OleDbClientLib.zip&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6450754954974860376?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6450754954974860376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6450754954974860376' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6450754954974860376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6450754954974860376'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/sql-compact-command-parameters-ii.html' title='SQL Compact Command Parameters - II'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6166140082534314373</id><published>2008-10-19T21:40:00.002+01:00</published><updated>2008-10-19T21:59:42.111+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>SQL Compact Command Parameters</title><content type='html'>Command parameters can be thought of as &lt;span style="font-style: italic;"&gt;value replacements&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;variables&lt;/span&gt; for SQL commands. You use a command parameter when you need to execute a SQL command multiple times changing one or more values on each execution. Instead of rebuilding the command text every time the command is executed, your code merely changes a variable value. This means that your code changes from this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;SELECT * FROM Customers WHERE Country = 'Germany'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;to this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;SELECT * FROM Customers WHERE Country = @p&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note that the command parameter (&lt;span style="font-family: courier new;"&gt;@p&lt;/span&gt;) replaces a literal value that will change every time you execute the command. Command parameters have some interesting advantages over string concatenation:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Command parameters are strongly typed;&lt;/li&gt;&lt;li&gt;Command parameters make the command run faster;&lt;/li&gt;&lt;li&gt;Command parameters are safe because they avoid SQL injection attacks.&lt;/li&gt;&lt;/ul&gt;Suppose that you need to pass a date value as a parameter to a SQL command. How exactly do you format a date value in order to be correctly interpreted by the query processor? When using command parameters you just don't are about this - you just feed the parameter with the binary value and it atakes care of the rest, no string formatting contortions needed.&lt;br /&gt;&lt;br /&gt;The OLE DB provider &lt;span style="font-style: italic;"&gt;requires&lt;/span&gt; that parameterized commands be prepared (compiled) before executing. Contrary to the managed ADO .NET provider, the OLE DB provider does check the command for errors and enumerates all the given parameters and even infers their data types (your code can then read this informtion and use it). Preparing a command with the ADO .NET provider for CF merely marks the command as requiring preparation before executing. Either way, a prepared command runs faster than an unprepared one.&lt;br /&gt;&lt;br /&gt;Finally, with command parameters there is no way to let your user change the syntax of the underlying SQL command. If you use string concatenation to build command strings (with user input), you risk exposing your code to SQL injection attacks that may break your application code or even its security.&lt;br /&gt;&lt;br /&gt;Since version 3.0, SQL Compact supports named parameters meaning that you can give your command parameters some meaningful names. All command parameter identifiers must be prepended by a '@' character. If you are still using SQL CE 2.0 then you are out of luck as all command parameters are identified by a single '?' character and distinguishable by their ordinal position only.&lt;br /&gt;&lt;br /&gt;After this brief introduction, I will look at the details of implementing a SQL command parameter management code and some of the finer details of binding, such as what to do with BLOBs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6166140082534314373?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6166140082534314373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6166140082534314373' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6166140082534314373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6166140082534314373'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/sql-compact-command-parameters.html' title='SQL Compact Command Parameters'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-3763379137076041233</id><published>2008-10-16T21:58:00.003+01:00</published><updated>2008-10-16T22:11:40.059+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><title type='text'>Very fast row counting on SQL Compact</title><content type='html'>What's the fastest way to retrieve a table's row count in SQL Compact 3.0 and 3.5? Use the &lt;a href="http://msdn.microsoft.com/en-us/library/ms174108.aspx"&gt;&lt;span style="font-family: courier new;"&gt;sp_show_statistics&lt;/span&gt;&lt;/a&gt; stored procedure! Pass your table name as the first parameter (the second is optional) and you will get back a few statistics about the table and its indexes, so more than one row might be returned. The row count is on the &lt;span style="font-family: courier new;"&gt;ROWS&lt;/span&gt; column (ordinal 3), an unsigned 32-bit integer.&lt;br /&gt;&lt;br /&gt;Note that this is not supported in versions 2.0 and earlier.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-3763379137076041233?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/3763379137076041233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=3763379137076041233' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3763379137076041233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/3763379137076041233'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/very-fast-row-counting-on-sql-compact.html' title='Very fast row counting on SQL Compact'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2405764206456383521</id><published>2008-10-16T09:18:00.002+01:00</published><updated>2008-10-16T09:21:19.406+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tech Ed'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><title type='text'>Meet me at Tech Ed EMEA 2008</title><content type='html'>Meet me in Tech Ed EMEA 2008 where I will deliver a presentation about "&lt;span style="color: rgb(1, 1, 1); cursor: default;" onclick="toggle('1e726dd6-2d3a-45ce-8bd9-9365a66ff819')"&gt;&lt;a href="https://emea.msteched.com/dev/public/sessions.aspx"&gt;Microsoft SQL Server 2005 Compact Edition Ultimate Performance Tuning&lt;/a&gt;" (Windows Mobile track). See you there!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2405764206456383521?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2405764206456383521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2405764206456383521' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2405764206456383521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2405764206456383521'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/meet-me-at-tech-ed-emea-2008.html' title='Meet me at Tech Ed EMEA 2008'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6617875833123957275</id><published>2008-10-15T11:40:00.003+01:00</published><updated>2008-10-15T12:08:08.300+01:00</updated><title type='text'>New column binding and commands</title><content type='html'>As promised in a &lt;a href="http://nativemobile.blogspot.com/2008/10/blob-update-code.html"&gt;previous post&lt;/a&gt;, I changed the way columns are bound in the &lt;span style="font-family:courier new;"&gt;CRowset&lt;/span&gt; class so that the class retains all the important column information retrieved from the &lt;span style="font-family:courier new;"&gt;IColumnsInfo&lt;/span&gt; interface, but also the binding offsets. You can see all of this at work in the new version of &lt;span style="font-family:courier new;"&gt;CRowset&lt;/span&gt; in the sample files.&lt;br /&gt;&lt;br /&gt;You will also find the first implementation of the &lt;span style="font-family:courier new;"&gt;CCommand&lt;/span&gt; class, an abstraction over the OLE DB Command object. This first implementation is very simple and allows only for execution of a command text (no parameters yet) returning a &lt;span style="font-family:courier new;"&gt;CRowset&lt;/span&gt; and/or an affected row count.&lt;br /&gt;&lt;br /&gt;Using a &lt;span style="font-family:courier new;"&gt;CCommand&lt;/span&gt; object is very simple (much like using &lt;span style="font-family:courier new;"&gt;CTable&lt;/span&gt;):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CCommand command(m_session);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;command.SetText(_T("SELECT * FROM Employees"));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;hr = command.Execute(m_rowset);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Start by declaring a &lt;span style="font-family:courier new;"&gt;CCommand&lt;/span&gt; object passing the open &lt;span style="font-family:courier new;"&gt;CSession&lt;/span&gt; object as parameter. Next, set the command text and then call execute passing a &lt;span style="font-family:courier new;"&gt;CRowset&lt;/span&gt; object as parameter. You can now use the rowset to navigate the rows and retrieve data.&lt;br /&gt;&lt;br /&gt;Note that the returning rowset &lt;span style="font-style: italic;"&gt;may&lt;/span&gt; not have a bookmark (not in this case, anyway) so you must be careful how you index the resulting columns. Remember that &lt;span style="font-family:courier new;"&gt;CRowset::GetColumnCount&lt;/span&gt; returns the total number of columns including the bookmark, if present. Also, columns are referred to by their ordinal position and the first data column is always at ordinal 1, so if you are iterating through all columns using &lt;span style="font-family:courier new;"&gt;GetColumnCount&lt;/span&gt;, make sure you always start at 1 and also add 1 if the rowset does &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; have bookmarks (see &lt;span style="font-family:courier new;"&gt;CRowset::HasBookmark&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Finally, if you don't set any specific command properties (as in this case) you get a forward-only cursor, so there is no going back...&lt;br /&gt;&lt;br /&gt;Sample files: &lt;a href="http://www.primeworks.eu/Downloads/CodeProject/EditRow5.zip"&gt;EditRow5.zip&lt;/a&gt;, &lt;a href="http://www.primeworks.eu/Downloads/CodeProject/oledbcli4.zip"&gt;oledbcli4.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;P.S.: &lt;span style="font-style: italic; font-weight: bold;"&gt;Don't&lt;/span&gt; try to use the EditRow sample to edit rows coming from the command rowset! I just adapted the sample to show how easy it is to display command data. The resulting is read-only.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6617875833123957275?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6617875833123957275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6617875833123957275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6617875833123957275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6617875833123957275'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/new-column-binding-and-commands.html' title='New column binding and commands'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-8510309176476191578</id><published>2008-10-10T15:52:00.004+01:00</published><updated>2008-10-10T16:23:44.399+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>OLE DB Commands and SQL Compact</title><content type='html'>OLE DB Commands are created through the &lt;a href="http://msdn.microsoft.com/en-us/library/ms711625%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;IDBCreateCommand&lt;/span&gt;&lt;/a&gt; Session object interface. Just find your Session object and call &lt;span style="font-family:courier new;"&gt;QueryInterface&lt;/span&gt; using the &lt;span style="font-family:courier new;"&gt;IID_IDBCreateCommand&lt;/span&gt; GUID. This interface just exposes one method - &lt;a href="http://msdn.microsoft.com/en-us/library/ms709772%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;CreateCommand&lt;/span&gt;&lt;/a&gt; - that you use to create OLE DB Command objects. As with most COM and OLE DB objects, several interfaces are exposable for a given object subject to provider implementation. For SQL Compact the following interfaces are exposed:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms709737%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;ICommand&lt;/span&gt;&lt;/a&gt; - Execute the command through this interface. As I noted in a previous post, the &lt;a href="http://msdn.microsoft.com/en-us/library/ms714402%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;Cancel&lt;/span&gt;&lt;/a&gt; method is not implemented in SQL Compact.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms713621%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;ICommandPrepare&lt;/span&gt;&lt;/a&gt; - Use this interface to &lt;a href="http://msdn.microsoft.com/en-us/library/ms718370%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;Prepare&lt;/span&gt;&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/ms719635%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;Unprepare&lt;/span&gt;&lt;/a&gt; the command. Command preparation is useful when executing the same command more than once and is required when using command parameters. Contrary to what happens with the ADO .NET provider, the &lt;span style="font-family:courier new;"&gt;Prepare&lt;/span&gt; method actively validates the SQL Command against the existing database, returning errors for incorrect syntax.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms723044%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;ICommandProperties&lt;/span&gt;&lt;/a&gt; - Gets or sets the properties associated with the Command.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a style="font-family: courier new;" href="http://msdn.microsoft.com/en-us/library/ms714914%28VS.85%29.aspx"&gt;ICommandText&lt;/a&gt; - Gets or sets the command text. This interface inherits from &lt;span style="font-family:courier new;"&gt;ICommand&lt;/span&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a style="font-family: courier new;" href="http://msdn.microsoft.com/en-us/library/ms712937%28VS.85%29.aspx"&gt;ICommandWithParameters&lt;/a&gt; - Manages command parameters (we will have to implement a data binding scheme similar to what exists in &lt;span style="font-family:courier new;"&gt;CRowset&lt;/span&gt;). SQL Compact allows only for input parameters, not output.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;As you can see, this is enough to run SQL commands against SQL Compact's Query Processor. For now, we leave this here as a reference while I go back to work and start implementing these features in the OLE DB Client library.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-8510309176476191578?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/8510309176476191578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=8510309176476191578' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8510309176476191578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/8510309176476191578'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/ole-db-commands-and-sql-compact.html' title='OLE DB Commands and SQL Compact'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-1269349158397730335</id><published>2008-10-10T10:21:00.003+01:00</published><updated>2008-10-10T10:45:31.294+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>BLOB update code</title><content type='html'>The sample code I'm posting today illustrates the techniques I described on my &lt;a href="http://nativemobile.blogspot.com/2008/10/updating-rows-with-blobs.html"&gt;last post&lt;/a&gt;. Please note that this is really a &lt;span style="font-style: italic;"&gt;sample&lt;/span&gt; - I will change it in the next incarnation in order to be more effective when binding data. Right now you can see a bit of a mess when binding columns because both the &lt;span style="font-family:courier new;"&gt;DBCOLUMNINFO&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;DBBINDING&lt;/span&gt; arrays are being used to find the column information addresses on the data buffer. Next version will have a unique array with all the required info to correctly and accurately describe each column. Enough of this and let's look at the code.&lt;br /&gt;&lt;br /&gt;First of all, take a look at &lt;span style="font-family:courier new;"&gt;CRowset::SetValue&lt;/span&gt;. Here you see how text strings (only!) are written and how the code decides if the column is a BLOB or not. If we are writing to a BLOB column, the code creates a &lt;span style="font-family:courier new;"&gt;CBlobStream&lt;/span&gt; object and writes the string contents to it. Upon success, a pointer to the &lt;span style="font-family:courier new;"&gt;CBlobStream&lt;/span&gt; object is stored in the rowset data buffer. When this data is written to the provider (by calling &lt;span style="font-family:courier new;"&gt;IRowsetChange::SetData&lt;/span&gt; on the BLOB column's accessor handle), the provider calls the &lt;span style="font-family:courier new;"&gt;CBlobStream::Read&lt;/span&gt; method to read all the string contents into the BLOB storage. When it is done with it, the provider calls the &lt;span style="font-family:courier new;"&gt;Release&lt;/span&gt; method and the &lt;span style="font-family:courier new;"&gt;CBlobStream&lt;/span&gt; deletes itself - neat.&lt;br /&gt;&lt;br /&gt;Finally, take a look at the &lt;span style="font-family:courier new;"&gt;CRowset::Insert&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;CRowset::Delete&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;CRowset::SetData&lt;/span&gt; methods. These implement the changes I described before. Also, note that these methods will work even if the &lt;span style="font-family:courier new;"&gt;IRowsetUpdate&lt;/span&gt; interface is not exposed.&lt;br /&gt;&lt;br /&gt;Next up - After rewriting most of the column binding code, I will start talking about commands.&lt;br /&gt;&lt;br /&gt;Sample files: &lt;a href="http://www.primeworks.eu/Downloads/CodeProject/EditRow4.zip"&gt;EditRow4.zip&lt;/a&gt;, &lt;a href="http://www.primeworks.eu/Downloads/CodeProject/oledbcli3.zip"&gt;oledbcli3.zip&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-1269349158397730335?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/1269349158397730335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=1269349158397730335' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1269349158397730335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1269349158397730335'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/blob-update-code.html' title='BLOB update code'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-5219111282503970868</id><published>2008-10-09T11:45:00.002+01:00</published><updated>2008-10-09T12:13:09.679+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Updating rows with BLOBs</title><content type='html'>As I have &lt;a href="http://nativemobile.blogspot.com/2008/09/lets-talk-about-blobs.html"&gt;previously discussed&lt;/a&gt;, we need to make some substantial changes to our code if we want to update rows with BLOB columns. So how exactly do we update these things? The first thing we need is to implement an object that behaves like an &lt;span style="font-family: courier new;"&gt;ISequentialStream&lt;/span&gt; COM object. Our code will create one such object per BLOB column, store the data in this object and then store a pointer to this object in the rowset buffer. When updating data, the OLE DB provider will read it (just like our code reads the storage objects coming from the provider) and then releases it. To make our life easier, our implementation of this object should delete itself when the reference count reaches zero. This way we will not have to worry about deleting it later.&lt;br /&gt;&lt;br /&gt;After setting all the row data (BLOB and otherwise), we can insert or update it. If you want to delete a row it is pointless to write data to it. If you remember, I said that when using BLOBs with SQL Compact we must use the deferred update mode by requesting the &lt;span style="font-family: courier new;"&gt;IRowsetUpdate&lt;/span&gt; interface. Here's how the code changes for each operation (insert, update or delete):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Insert&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Call &lt;span style="font-family: courier new;"&gt;IRowsetChange::InsertRow&lt;/span&gt; - this sets the non-BLOB data;&lt;/li&gt;&lt;li&gt;Call &lt;span style="font-family: courier new;"&gt;IRowsetChange::SetData&lt;/span&gt; for each BLOB accessor;&lt;/li&gt;&lt;li&gt;Call &lt;span style="font-family: courier new;"&gt;IRowsetUpdate::Update&lt;/span&gt; to commit the changes.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Update&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Call &lt;span style="font-family: courier new;"&gt;IRowsetChange::SetData&lt;/span&gt; for each accessor.&lt;/li&gt;&lt;li&gt;Call &lt;span style="font-family: courier new;"&gt;IRowsetUpdate::Update&lt;/span&gt; to commit the row changes.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Delete&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Call &lt;span style="font-family: courier new;"&gt;IRowsetChange::DeleteRow&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Call &lt;span style="font-family: courier new;"&gt;IRowsetUpdate::Update&lt;/span&gt;.&lt;/li&gt;&lt;/ol&gt;Note that if any of these processes fails before calling &lt;span style="font-family: courier new;"&gt;Update&lt;/span&gt;, you should call &lt;span style="font-family: courier new;"&gt;Undo&lt;/span&gt; to revert any changes made to the row. I'll show you the code in the next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-5219111282503970868?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/5219111282503970868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=5219111282503970868' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5219111282503970868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/5219111282503970868'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/updating-rows-with-blobs.html' title='Updating rows with BLOBs'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6358972262683573592</id><published>2008-10-08T08:37:00.003+01:00</published><updated>2008-10-08T08:45:59.415+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>ICommand::Cancel is a dummy</title><content type='html'>No, I'm not going to talk about the &lt;a style="font-family: courier new;" href="http://msdn.microsoft.com/en-us/library/ms709737%28VS.85%29.aspx"&gt;ICommand&lt;/a&gt; interface right now, but I just found out that the &lt;a style="font-family: courier new;" href="http://msdn.microsoft.com/en-us/library/ms714402%28VS.85%29.aspx"&gt;ICommand::Cancel&lt;/a&gt; implementation on the SQL Compact OLE DB provider is a &lt;a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3962675&amp;amp;SiteID=1"&gt;dummy&lt;/a&gt;. Good to know!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6358972262683573592?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6358972262683573592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6358972262683573592' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6358972262683573592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6358972262683573592'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/icommandcancel-is-dummy.html' title='ICommand::Cancel is a dummy'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-120032009864937356</id><published>2008-10-07T18:01:00.003+01:00</published><updated>2008-10-08T08:41:13.613+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Reading BLOBs</title><content type='html'>My first approach to the BLOB-handling code took a bit longer than expected due to my aging brain. Please understand that the code I'm publishing today is incomplete and will change in the future. I hope that it helps you in understanding what it takes to read BLOB data through the SQL Compact OLE DB provider.&lt;br /&gt;&lt;br /&gt;There are two important changes to the code since last post:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Columns are indexed by their ordinal.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Columns are bound using a two-pass approach - On the first pass the non-BLOB columns are bound using the same accessor handle. The second pass binds the BLOB columns allocating an accessor handle for each column.&lt;/li&gt;&lt;/ol&gt;The bulk of the code that reads the BLOB into memory is on the new &lt;span style="font-family:courier new;"&gt;CRowset::GetValue &lt;/span&gt;method. Note how the column accessor handle is used to retrieve the &lt;span style="font-family:courier new;"&gt;ISequentialStream&lt;/span&gt; pointer and how it is read into a &lt;span style="font-family:courier new;"&gt;CString&lt;/span&gt;. You have to consume all the data immediately because you cannot keep that stream object alive very long, especially if you want to read or write to another BLOB.&lt;br /&gt;&lt;br /&gt;Most of the complexity you see on the code (the difference between binding and column indexes) stems from the fact that columns are being moved around in order to make binding simpler. When life was simpler and there were no BLOBs, there was a direct relation between column and binding entries and there was no need to map between the two. Now that we are moving binding entries around, we must make sure that a mapping exists between both arrays (see the &lt;span style="font-family:courier new;"&gt;GetBindingIndex&lt;/span&gt; method).&lt;br /&gt;&lt;br /&gt;Next post will handle writing data to the BLOB.&lt;br /&gt;&lt;br /&gt;Sample files: &lt;a href="http://www.primeworks.eu/Downloads/CodeProject/EditRow3.zip"&gt;EditRow3.zip&lt;/a&gt;, &lt;a href="http://www.primeworks.eu/Downloads/CodeProject/oledbcli2.zip"&gt;oledbcli2.zip&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-120032009864937356?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/120032009864937356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=120032009864937356' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/120032009864937356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/120032009864937356'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/reading-blobs.html' title='Reading BLOBs'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-2355807551883299671</id><published>2008-10-01T13:48:00.005+01:00</published><updated>2008-10-01T15:14:33.206+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WTL'/><title type='text'>CStdDialogImpl and the OK button</title><content type='html'>Are using &lt;span style="font-family:courier new;"&gt;CStdDialogImpl&lt;/span&gt; as the base class for your WTL dialogs? Are you having difficulty hiding the "ok" button? Here's a simple solution:&lt;br /&gt;&lt;br /&gt;Derive your dialog class (say &lt;span style="font-family:courier new;"&gt;CMyDialog&lt;/span&gt;) from&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CStdDialogImpl&amp;lt;CMyDialog, SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_SIPDOWN&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;On the &lt;span style="font-family:courier new;"&gt;OnInitDialog&lt;/span&gt; handler, call:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SHDoneButton(m_hWnd, SHDB_HIDE);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ModifyStyle(0, WS_NONAVDONEBUTTON, SWP_NOSIZE);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Make sure you change all the calls to &lt;span style="font-family:courier new;"&gt;CStdDialogImpl&amp;lt;CMyDialog&amp;gt;&lt;/span&gt; methods with the new base (you can use a &lt;span style="font-family:courier new;"&gt;typedef&lt;/span&gt; for that).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-2355807551883299671?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/2355807551883299671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=2355807551883299671' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2355807551883299671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/2355807551883299671'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/10/cstddialogimpl-and-ok-button.html' title='CStdDialogImpl and the OK button'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4452128773616415919</id><published>2008-09-30T08:49:00.003+01:00</published><updated>2008-09-30T09:45:50.572+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Let's talk about BLOBs</title><content type='html'>So far we have seen how to edit table data using the &lt;a style="font-family: courier new;" href="http://msdn.microsoft.com/en-us/library/ms715790%28VS.85%29.aspx"&gt;IRowsetChange&lt;/a&gt; interface. The provided sample managed to edit a simple table where all columns had limited size. Table edits are performed in a single step, where all the data is read or written at once, and all the data items are sequentially stored on the same data buffer. This scheme works very well but does not support BLOBs.&lt;br /&gt;&lt;br /&gt;A BLOB is a different beast because it can store a very large amount of data. In SQL Compact there are only two types of BLOBs: the &lt;span style="font-family:courier new;"&gt;image&lt;/span&gt; (variable length byte array) and the &lt;span style="font-family:courier new;"&gt;ntext&lt;/span&gt; types (variable length character array). These can be really large and the maximum theoretical size of a BLOB field is 4 GB in SQL Compact (the same size limit for the whole database).Contrary to smaller data types, you may not be able to store the whole BLOB data in the device memory, so we need a different approach to handling these types.&lt;br /&gt;&lt;br /&gt;The OLE DB standard allows two different ways to bind BLOB data to your accessor: by reference or by value. SQL Compact does not allow by reference binding, so we are limited to binding these by value? What are the differences between both types of data binding?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;When binding by reference, the OLE DB provider allocates memory for each bound BLOB field and fills it with data. A pointer to this data is stored in the accessor buffer along with its status and size. Column data is accessed through an extra pointer indirection and our code must make sure that the BLOB data buffer is released when the data is not needed anymore.&lt;/li&gt;&lt;li&gt;When binding by value, we can either specify (force) a fixed column size or bind through a storage interface. The first approach allows your BLOB data to be manipulated just like any other column but forces you to put a limit on how much data you will handle per BLOB column and this defeats the whole purpose of using them. Alternatively (and most commonly) your code will request that the provider creates a storage object to handle the BLOB data (when reading - when writing data your code must do this). When data is read ftom the table, the provider stores a pointer to either an &lt;a href="http://msdn.microsoft.com/en-us/library/ms718035%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;ISequentialStream&lt;/span&gt;&lt;/a&gt; or an &lt;a href="http://msdn.microsoft.com/en-us/library/aa379238.aspx"&gt;&lt;span style="font-family:courier new;"&gt;ILockBytes&lt;/span&gt;&lt;/a&gt; interface and then your code can read the data through these. When writing, your code must create one of these objects per BLOB column.&lt;/li&gt;&lt;/ul&gt;The last approach - binding by value through storage objects - is the recommended approach, but it becomes harder to implement when your code is handling more than one BLOB per row. In fact, SQL Compact will only manage (read from or write to) one storage object at a time, and if you ask it to instantiate more than one you will get an error. So how do you read from a table (or query) that returns more than one BLOB column? And how do you write the data? Well, you do so one at a time and this means that your code cannot read nor write the whole data in one single step.&lt;br /&gt;&lt;br /&gt;The first change we must make to the rowset code is to add more accessor handles. The first accessor handle will bind the non-BLOB columns and these can be read and written to just like we are doing right now. For each BLOB column the rowset must allocate an additional accessor handle and make a note of it.&lt;br /&gt;&lt;br /&gt;When data is read, the non-BLOB columns are all read, but none of the BLOB columns are. When your client code requests data from a BLOB column, the rowset must know that this is a special case, retrieve the colsumn's accessor handle and call &lt;a href="http://msdn.microsoft.com/en-us/library/ms716988%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;IRowset::GetData&lt;/span&gt;&lt;/a&gt; on that handle. On the data buffer, the OLE DB provider will write a pointer to one of the above-mentioned storage objects (it is chosen by the rowset code when the data binding is created) and your client code must read through it and release it when no longer needed.&lt;br /&gt;&lt;br /&gt;When you need to write data back to the table, your client code will have to create one storage object per BLOB column, store the respective pointers in the data buffer and engage in a multi-step update (new row insertion or existing row update). This means that your code will store the non-BLOB columns first and then store the BLOB columns one at a time, but to be able to achieve this the rowset must be in delayed update mode. You specify this mode by setting the &lt;span style="font-family:courier new;"&gt;DBPROP_IRowsetUpdate&lt;/span&gt; property to &lt;span style="font-family:courier new;"&gt;VARIANT_TRUE&lt;/span&gt; and the rowset now exposes the &lt;a href="http://msdn.microsoft.com/en-us/library/ms714401%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;IRowsetUpdate&lt;/span&gt;&lt;/a&gt; interface. When this interface is exposed, you can call &lt;a href="http://msdn.microsoft.com/en-us/library/ms721232%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;IRowsetChange::SetData&lt;/span&gt;&lt;/a&gt; on the allocated accessor handles without having to worry about having the row in an inconsisten state (due to table constraints, for instace) while you are updating data. When your code is done setting data through all the accessors, just call &lt;a href="http://msdn.microsoft.com/en-us/library/ms719709%28VS.85%29.aspx"&gt;&lt;span style="font-family:courier new;"&gt;IRowsetUpdate::Update&lt;/span&gt;&lt;/a&gt; to update all the changes at once.&lt;br /&gt;&lt;br /&gt;This will be easier to understand through a sample, which I will publish on my next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4452128773616415919?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4452128773616415919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4452128773616415919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4452128773616415919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4452128773616415919'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/09/lets-talk-about-blobs.html' title='Let&apos;s talk about BLOBs'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4423220759719410379</id><published>2008-09-29T11:12:00.002+01:00</published><updated>2008-09-29T11:24:14.283+01:00</updated><title type='text'>Using the OLE DB Client code</title><content type='html'>I was recently asked for permission to use the OLE DB Client library code in a third party application. One of the blog readers asked me about a specific license to go with the code and I pointed him to the &lt;a href="http://www.codeproject.com/info/cpol10.aspx"&gt;CPOL&lt;/a&gt;, the permissive license used by most &lt;a href="http://www.codeproject.com/"&gt;Code Project&lt;/a&gt; articles. I'm actually planning to convert the material from these posts into a series of articles to be published in Code Project under this license. This is a very simple license: you can use the code for whatever purposes you like (even in a commercial application) and the only thing you are required to do is to acknowledge who wrote the original code (see the CPOL details).&lt;br /&gt;&lt;br /&gt;Now that you know this, should you use this code? If you want to use it to learn about OLE DB and the SQL Compact native provider, please go right ahead and use it (and change it, and tweak it and experiment with it). As to using it in a commercial application, I would say "not right now" for two reasons:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The code has not been extensively tested. Although I plan to publish a bug-free (ah ah ah!) library, I cannot take resposibility for any use you make of it. You will be on your own.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;This code will change. Don't start writing your own code based on this library expecting that the library interfaces will not change. They will, and your code will fail to compile.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Now that this is clarified, let's have a look at BLOBs and what we need to support them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4423220759719410379?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4423220759719410379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4423220759719410379' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4423220759719410379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4423220759719410379'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/09/using-ole-db-client-code.html' title='Using the OLE DB Client code'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-7140852079796062882</id><published>2008-09-24T15:46:00.002+01:00</published><updated>2008-09-24T15:55:14.621+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Moving to a DLL</title><content type='html'>Can I put the OLE DB Client library in a DLL? I tried but got some compiler warnings (&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;C4251&lt;/span&gt;) concerning some of the ATL class templates (&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;CComPtr&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;CString&lt;/span&gt;). The reason is that other classes might inherit from these and template definitions are not always exportable.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To solve this problem, I replaced all references of &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;CComPtr&lt;/span&gt; in the protected interface with raw COM pointers, which required me to implement some missing destructors. I also removed the protected &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;CString&lt;/span&gt; in the &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;CTable&lt;/span&gt; class and now the code cleanly compiles into a DLL.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can download the rewritten sample code (&lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/EditRow2.zip"&gt;EditRow2.zip&lt;/a&gt; and &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/oledbcli.zip"&gt;oledbcli.zip&lt;/a&gt;) and test them. Make sure that you place the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;OleDbClient&lt;/span&gt; project in a directory with the same name and at the same level of &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;EditRow&lt;/span&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-7140852079796062882?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/7140852079796062882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=7140852079796062882' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7140852079796062882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/7140852079796062882'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/09/moving-to-dll.html' title='Moving to a DLL'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-4650360796212683991</id><published>2008-09-22T15:26:00.003+01:00</published><updated>2008-09-23T09:33:18.886+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Updating data</title><content type='html'>There are two ways to update data using OLE DB: using SQL DML commands (which I will look at in later posts), or through the &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms715790(VS.85).aspx"&gt;IRowsetChange&lt;/a&gt;&lt;/span&gt; interface exposed through a base table &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;IRowset&lt;/span&gt;. It supports the basic methods to insert new rows (&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms716921(VS.85).aspx"&gt;InsertRow&lt;/a&gt;&lt;/span&gt;), update existing rows (&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms721232(VS.85).aspx"&gt;SetData&lt;/a&gt;&lt;/span&gt;) and to delete rows (&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms724362(VS.85).aspx"&gt;DeleteRows&lt;/a&gt;&lt;/span&gt;) and is only exposed when the consumer sets the &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;DBPROP_IRowsetChange&lt;/span&gt; property to &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;VARIANT_TRUE&lt;/span&gt;.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To illustrate this type of data update, I put up a sample that allows you to edit the "Suppliers" table from the Northwind sample database. The list view display code has been changed in order to support a load-on-demand cache of rows, stored in their native (&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;CRowset&lt;/span&gt;'s) format. The cache items are preloaded when the list view notifies the parent through the &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;LVN_ODCACHEHINT&lt;/span&gt; notification message. Row bookmarks are stored along the row data, so we can now very quickly position the rowset cursor in any row so we can edit its data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Note that when modifying any data, we have to make sure that both the bookmark and the row ID columns are not touched because both are managed by the engine (the row ID is an IDENTITY column that gets automatically filled in upon insert). Apart from this, setting data is just a matter of copying the new row value to the rowset and correctly setting the column status and length (optional for fixed-length types).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This code does not support BLOBs yet. I will look at these in my next post.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sample project: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/EditRow.zip"&gt;EditRow.zip&lt;/a&gt; (1.29 MB)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-4650360796212683991?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/4650360796212683991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=4650360796212683991' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4650360796212683991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/4650360796212683991'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/09/updating-data.html' title='Updating data'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-1084868666667262649</id><published>2008-09-17T09:24:00.002+01:00</published><updated>2008-09-17T09:56:14.634+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><category scheme='http://www.blogger.com/atom/ns#' term='OLE DB'/><title type='text'>Bookmarks</title><content type='html'>So what is a bookmark and why should you care? To put it simply, a bookmark is a row unique identifier on an open rowset that allows for very fast random seeks. In order to get a rowset with bookmarks, you must set the &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;DBPROP_BOOKMARKS&lt;/span&gt; property to &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;VARIANT_TRUE&lt;/span&gt;. The resulting rowset has the bookmark value at column ordinal zero and its size and type varies according to the database engine. On all versions of SQL Compact the bookmark type is a 32-bit integer (&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;DBTYPE_I4&lt;/span&gt; on SQL CE 2.0 and &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;DBTYPE_UI4&lt;/span&gt; on 3.0 and 3.5).&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are two important bookmark restrictions that you must be aware of:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;The bookmark value is valid only for the particular rowset that generated it. You should not store this value for later use after the rowset closes because the bookmark values will be rendered invalid. Even if you open the same rowset again, there is no guarantee that the bookmark values will be the same. (Ok, now that I wrote this disclaimer I can tell you that apparently on base table cursors, SQL Compact does seem to reuse the same bookmark values. Nevertheless don't reuse them, please.)&lt;/li&gt;&lt;li&gt;There is no way to know a bookmark's value before loading the row data to memory. This means that if you are using bookmarks to navigate in your rowset, your code must visit the row before knowing its bookmark value, just like in a book.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;So why should you care about bookmarks? I have found a very interesting use for them: editing table data without using unique indexes or primary keys. The bookmark gives you an exact and unique identifier to any row and the rowset pointer moves very quickly to that particular row.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Before you can seek to a known bookmark, your rowset must be created with the &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;DBPROP_IRowsetBookmark&lt;/span&gt; property set to &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;VARIANT_TRUE&lt;/span&gt;. Doing so exposes the optional &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms714246(VS.85).aspx"&gt;IRowsetBookmark&lt;/a&gt;&lt;/span&gt; interface on the &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;IRowset&lt;/span&gt;, and you can use it to very quickly position your rowset pointer to any valid bookmark by calling the &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms714382(VS.85).aspx"&gt;PositionOnBookmark&lt;/a&gt;&lt;/span&gt; method.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Before looking at BLOBs, the next post will show how to edit data using a base table cursor and bookmarks.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-1084868666667262649?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/1084868666667262649/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=1084868666667262649' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1084868666667262649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/1084868666667262649'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/09/bookmarks.html' title='Bookmarks'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11847577.post-6593050497714165099</id><published>2008-09-15T10:10:00.003+01:00</published><updated>2008-09-15T10:15:20.088+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Compact'/><title type='text'>Sample Databases</title><content type='html'>Isn't this nice? I have been publishing the "OpenTable" sample code but forgot to publish the sample databases. My apologies! You can find the three databases (test20.sdf, test30.sdf and test35.sdf) on this zip file: &lt;a href="http://www.primeworks-mobile.com/Downloads/CodeProject/testxx.zip"&gt;testxx.zip&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Please note that the sample has hard-coded the location of the SDF file in the device root. You can change this, of course.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11847577-6593050497714165099?l=nativemobile.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nativemobile.blogspot.com/feeds/6593050497714165099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11847577&amp;postID=6593050497714165099' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6593050497714165099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11847577/posts/default/6593050497714165099'/><link rel='alternate' type='text/html' href='http://nativemobile.blogspot.com/2008/09/sample-databases.html' title='Sample Databases'/><author><name>João Paulo Figueira</name><uri>http://www.blogger.com/profile/01808451986712386444</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://bp0.blogger.com/_AksH5-lumMs/SCQYuaNZMAI/AAAAAAAAAQs/eA23ckrE4Fw/S220/MVP_profile.jpg'/></author><thr:total>0</thr:total></entry></feed>
