Friday, February 27, 2009
TouchBrowser - III
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.
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.
Sample: TouchBrowser3.zip
SQL Compact Insert Performance
I've just posted the SQL Compact Insert Performance demo on my managed code 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...).
Thursday, February 19, 2009
TouchBrowser - II
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.
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.
In this version I also fixed the bub in the EnsureVisible 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.
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 HitTest - type of function.
Sample: TouchBrowser2.zip
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.
In this version I also fixed the bub in the EnsureVisible 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.
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 HitTest - type of function.
Sample: TouchBrowser2.zip
Wednesday, February 11, 2009
TouchBrowser - I
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.
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.
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.
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.
Sample code: TouchBrowser.zip (27 KB)
Thursday, February 05, 2009
Minor bug correction
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 atltouch.h file and look for the ActivateItem method on line 910. Before the last call to NotifyItemChange, insert the following line:
if(IsValidItem(iItem))
Thanks, Vincent!
if(IsValidItem(iItem))
Thanks, Vincent!
Wednesday, February 04, 2009
Why does CeRapiInitEx return E_INVALIDARG?
This was a very hard debugging session. Suddenly I found that while using exactly the same DLLs, Wizard was failing to open a RAPI connection while Console 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 E_INVALIDARG error when calling CeRapiInitEx (both static and dynamically linked). What to do?
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?
Wait, let's try the code at the end of the main form constructor. Voilá, it failed. At the start of the constructor I get an S_OK and at the end I get an E_INVALIDARG. 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 CLSID 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 but I forgot to remove the calls. They look like this:
After removing the calls to this toxic code, Wizard works again! Why is CeRapiInitEx sensitive to COM initialization?
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?
Wait, let's try the code at the end of the main form constructor. Voilá, it failed. At the start of the constructor I get an S_OK and at the end I get an E_INVALIDARG. 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 CLSID 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 but I forgot to remove the calls. They look like this:
DPTRACK_API int IsLocalEngineInstalled(GUID guid)
{
CComPtr<IDBInitialize> spInitialize;
HRESULT hr;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
hr = CoCreateInstance(guid, NULL, CLSCTX_INPROC_SERVER,
IID_IDBInitialize,
(void**)&spInitialize);
CoUninitialize();
return SUCCEEDED(hr);
}
After removing the calls to this toxic code, Wizard works again! Why is CeRapiInitEx sensitive to COM initialization?
Tuesday, February 03, 2009
Property List Notifications
In my last post I presented a custom control based on the previously published CTouchWindow 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.
Each CTouchListItem (the base class for CPropertyListItem) now supports two new functions to control and report the enabled state: SetEnabled and IsEnabled. 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).
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 OnItemActivated 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).
As always, comments are welcome!
Sample: PropList2.zip (46 KB)
Each CTouchListItem (the base class for CPropertyListItem) now supports two new functions to control and report the enabled state: SetEnabled and IsEnabled. 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).
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 OnItemActivated 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).
As always, comments are welcome!
Sample: PropList2.zip (46 KB)
Subscribe to:
Posts (Atom)