Template Information

Trang

Chủ đề

BSP (44) Device Drivers (43) WinCE (38) WINDOWS DRIVER (19) Linux Device Drivers (18) ARM (17) Android tools and tips (17) DRIVER FILES (16) Windows Device Driver (16) AUDIO DRIVER (12) 8051 (8) OMAP (7) PRINTER DRIVER FILES (7) C Programming (6) ASUS MOTHERBOARD (5) Interfacing (5) NETWORK ADAPTER (5) VIDEO DRIVER (5) CANON (3) Device Driver Downloads (3) MOBILE PHONE (3) Asus Driver (2) EPSON (2) Epson Printer Driver (2) HP LAPTOP DRIVER (2) LAPTOP DRIVER FILES (2) Logitech Driver (2) NETWORK ADAPTOR (2) OMAP 4430 (2) drivers download (2) ACER (1) ACER TABLET (1) ALL IN ONE DRIVER (1) Acer Aspire 5738 Drivers (1) Analog-to-Digital (1) Asus Drivers (1) Asus Motherboard Drivers (1) Chip Architecture (1) DELL (1) Dell D610 Drivers (1) Dell Drivers (1) Device Drivers Download (1) Device drivers interview questions (1) Display Driver (1) Drivers Download for Windows 7 (1) EEPROMs (1) Free Asus Motherboard Drivers (1) Free Drivers Download for Windows 7 (1) GRAPHIC DRIVER (1) HP Driver (1) Hardware (1) Intel Drivers (1) Intel P35 (1) Intel P35 chipset drivers (1) I²C (1) LAPTOP SERVICE MANUAL (1) LCD (1) Logitech Mouse Driver (1) Logitech webcam driver (1) MODEM DRIVER (1) Motherboard Drivers for Windows 7 (1) PARALLEL PORT (1) Pc Driver (1) RTOS (1) Real Time Clock (1) Sensors (1) USB CABLE DRIVER (1) WEBCAM DRIVER (1) WIRELESS ADAPTOR (1) Windows 7 Drivers (1) Windows Mobile (1) acer driver (1) acer driver downloads (1) acer laptop driver (1) chipset drivers (1) network card driver (1) network driver download (1) sdcc (1)

Bài viết ngẫu nhiên

Xem phim HD Online

Số lượt views

Writing a Windows Mobile Today Screen Plugin

Thứ Tư, 26 tháng 10, 2011 / 10:15

Today Screen is a place to display critical information in Windows Mobile. Windows Mobile by default displays appointments, tasks, messages, calendar, owner information etc… We can create plugin to display our own information. A sample Today Screen looks like:
Sample Today Screen
Sample Today Screen
Today screen plugins are DLL which exports the one required function and one optional function. InitializeCustomItem is the required function and CustomItemOptionsDlgProc is the optional one. The DLL should export the InitializeCustomItem as ordinal 240. This function is called by the Shell process when the Today Screen item is initialized. In this function we can create window to be displayed and initialize whatever variables we are using. This is the only function in which we can set the height of the today item’s window. If the Plugin supports the options dialog, then it should export the CustomItemOptionsDlgProc also. In this function we can create options dialog and present the user whatever options are available. The .def file of the DLL should contain the following EXPORTS section
EXPORTS
InitializeCustomItem @ 240 NONAME
CustomItemOptionsDlgProc @ 241 NONAME

After creating the Today item’s window, the system will send the WM_TODAYCUSTOM_REFRESHCACHE message to the window. The WPARAM parameter will contains a pointer to the TODAYLISTITEM structure. This structure and all Today Screen related structures are defined in todaycmn.h header file. The TODAYLISTITEM structure is defined as:
struct _TODAYLISTITEM
{
CHAR szName[MAX_ITEMNAME];
TODAYLISTITEMTYPE tlit;
WORD dwOrder;
DWORD cyp;
OOL fEnabled;
BOOL fOptions;
WORD grfFlags;
TCHAR szDLLPath[MAX_PATH];
INSTANCE hinstDLL;
HWND hwndCustom;
OOL fSizeOnDraw;
BYTE * prgbCachedData;
WORD cbCachedData;
};
The fEnabled member of the structure will be TRUE if the Today item is enabled, otherwise it will be FALSE. The cyp member should contain the height of the windows, if this member is set to 0, the system will not send the WM_TODAYCUSTOM_REFRESHCACHE message.
The syntax of the InitializeCustomItem is:
HWND APIENTRY InitializeCustomItem(TODAYLISTITEM *pItem,HWND hWndParent);
The hWndParent parameter will be the handle of the Today Item’s parent window. If the Today item is not enabled we should immediately return NULL.
The system sends WM_TODAYCUSTOM_CLEARCACHE message to the Today item’s window when it is about to be unloaded. The WPARAM parameter contains a pointer to the TODAYLISTITEM structure. Upon receiving this message we can clear and cached data or any allocated memory we are using and return.
Whenever the Options button is clicked the system will call the CustomItemOptionsDlgProc function. One more requirement is that you should provide the resource for the dialog to be displayed and its resource id should be 500.
In our simple example we just display the battery status and internal memory status. If the battery is charging it will display the string “Charging…” otherwise displays the battery percentage. We will also display percentage of how much memory is used.
The today screen looks like this.
Our Today Screen
Our Today Screen
Many modifications can be done to this sample. One simple modification is to avoid flickering. To do this we can use double buffering or something else. I left this to your imagination.
In this example, to get the battery and memory status we use GetSystemPowerStatusEx and GlobalMemoryStatus functions.
The plugin has to be registered in the registry for the Today Screen to find and locate the custom items. The Registry key is [HKEY_LOCAL_MACHINE]SoftwareMicrosoftTodayItems]. Each Today Screen items should create a subkey with its name under this key. It should contain the following values:
Name Containing the name of the item.
DLL Contains the full path name of the DLL implementing the item.
Flags User-defined DWORD value returned in the grfFlags field of TODAYLISTITEM.
Options DWORD value set to 1 if the item supports an Options dialog box.
Enabled DWORD value set to 1 if the item is enabled.
Type Custom items must set this DWORD value to 4.
We can use Windows CE Remote Registry Editor to edit the key or we can use the CabWiz.exe file to create installation CAB file and specify these key in the .INF file.
Hope this article will give you an introduction to the Today Screen plugins. There are many resources available on the Internet. Just search for the Today Screen API and you will find many examples.
The example is only tested on I-Mate K-JAM, but may work in any other platforms.
Thứ Tư, 26 tháng 10, 2011 10:15 Đọc tiếp >>

Intel P35 Chipset Drivers Download – Solution for Chipset Issues

Thứ Hai, 17 tháng 10, 2011 / 02:48


Your PC is behaving in a strange manner, and you just don’t know what’s wrong with it? Are you sure there isn’t anything wrong with your chipset? May be it is the driver that’s creating all the trouble; try checking it out, once.

Sometimes, the actual trouble is created by the drivers and you waste all your time and energy checking out the other things and worse is when you go to some service center pay them hefty fees only to know that it was nothing but the driver. How you’d then be cursing your Intel P35 Chipset Drivers for causing all the trouble.

Are you wondering how come drivers cause all the troubles? Well, then you just need to know what exactly a driver is and how it works. It is a small software snatch that makes it possible for the device corresponding to it to communicate well with your computer system. And if it goes missing or gets damaged, this communication is not possible which then leads to the workability issues related to that particular device.

So, if the Intel P35 chipset drivers go missing from your computer system, the chipset won’t be working which will cause trouble with your motherboard leading to your entire system coming to a stand still as it won’t be working at all without it. To make the thing technically clear, the various devices and components on your computer just can’t work unless they have their drivers working. In fact, it won’t be wrong to say that the drivers are the actual driving forces behind your devices. And this is why it is essential to have them on your computer system.

You are now wondering how they could simply vanish from your system when you had yourself installed them, right? Well, they won’t be vanishing, but get accidently removed. Say, your anti virus suspected virus in them and suggested you to remove them, or perhaps you were making your system clutter free, and you deleted the Intel P35 chipset drivers along with other software pieces from your system. Quite possible, isn’t it?

There is another possibility as well; that they got damaged over the time and you never cared to check how they are doing. If this is the case, you’ll first have to remove the damaged ones and only then you’ll be able to think about a fresh installation.

So, first of all check out whether they are missing or have got damaged, then simply get online and jump onto any reliable looking site offering Intel P35 chipset drivers, download them and have them installed on your system. And you’ll once again find your system working wonderfully well!
Thứ Hai, 17 tháng 10, 2011 02:48 Đọc tiếp >>

Notifications and Power Management under Windows Mobile: Benefit from Both

Thứ Bảy, 15 tháng 10, 2011 / 01:28

One misty moisty morning
When cloudy was the weather...

One day a good friend of mine, David Herman, came to me, claiming that a piece of software that was supposed to take its data automatically from a remote server in the middle of the night, stopped working on Windows Mobile 2003 devices. More exactly, it had started to operate, but could not perform all the required steps. Not that it didn't work at all, no, but the PDA's screen was turned off, communications weren't opened, and so forth. a After quick search on the Web, I found that, to my great surprise, there is nothing that might solve the problem. Well, maybe I did not search hard enough. Anyway, I've started to investigate the case, and so this article has begun...
This article isn't dedicated to all of title's topics in depth, but rather intends to combine bits from here and from there to get all the stuff working together. There is no need to dive into well-documented functionality, at least for Notifications. Windows CE Power Management articles are also presented in MSDN. It left us just to add one and one. Besides, Windows Mobile 5.0 gives a programmer a few more options for customization, so I will overview them as well.

Two Faces of Notifications

When one talks about Notifications under Windows Mobile, one usually means two main areas: shell notifications (defined in aygshell.h) and user notifications (notify.h respectively). The first type allows your application to inform the user that something important has just happened; for example, that a new message has arrived. The second type is used to deal with a dozen system-level events, such as network connection being established and so forth. This article will discuss both of the above notification types.

User Notifications

I will start from more traditional Windows CE notifications. Those of you who have developed for older versions of Windows CE are definitely familiar with them. You were able to program your application to respond to a set of system events or to be launched at some point in time. But, things have changed since those times, so now you can see the following statement in notify.h:
//
//Obsolete; provided to maintain compatibility only
//
HANDLE CeSetUserNotification (HANDLE hNotification,
TCHAR *pwszAppName,
SYSTEMTIME *lpTime,
PCE_USER_NOTIFICATION
lpUserNotification);
BOOL CeRunAppAtTime (TCHAR *pwszAppName, SYSTEMTIME *lpTime);
BOOL CeRunAppAtEvent(TCHAR *pwszAppName, LONG lWhichEvent);
BOOL CeHandleAppNotifications (TCHAR *pwszAppName);

It means that all those old buddies you used to rely on can stop working anytime. Instead of the above functions, the SDK offers you an equivalent means:
BOOL   CeGetUserNotificationPreferences (HWND hWndParent,
PCE_USER_NOTIFICATION
lpNotification);
HANDLE CeSetUserNotificationEx (HANDLE hNotification,
CE_NOTIFICATION_TRIGGER *pcnt,
CE_USER_NOTIFICATION *pceun);
BOOL CeClearUserNotification (HANDLE hNotification);
BOOL CeGetUserNotification (HANDLE hNotification,
DWORD cBufferSize,
LPDWORD pcBytesNeeded,
LPBYTE pBuffer);
BOOL CeGetUserNotificationHandles (HANDLE *rghNotifications,
DWORD cHandles,
LPDWORD pcHandlesNeeded);
In fact, these are the same APIs but rewritten in other terms. Windows Mobile SDK gives you even more. It defines and uses a CE_NOTIFICATION_TRIGGER struct to declare how to trigger the required entity:
typedef struct UserNotificationTrigger {
DWORD dwSize;
DWORD dwType; //dwType Notification type
//dwEvent - type of event if dwType == CNT_EVENT
DWORD dwEvent;
//lpszApplication - name of application to execute
TCHAR *lpszApplication;
//lpszArguments - command line (sans app name)
TCHAR *lpszArguments;
//stStartTime - begin of notification period
SYSTEMTIME stStartTime;
//stEndTime - end of notification period
SYSTEMTIME stEndTime;
} CE_NOTIFICATION_TRIGGER, *PCE_NOTIFICATION_TRIGGER;
In addition to running your application (with the appropriate command line) at a given time or event, now you can specify a time period. Besides, Windows Mobile or CE.NET supports named events, so you may want to use it for lpszApplication instead of the application name in the form of:
"\\.\Notifications\NamedEvents\Event Name"

Shell Notifications

This kind of notification is also pretty easy. Quite a few functions handle all the job:
LRESULT SHNotificationAdd(SHNOTIFICATIONDATA *pndAdd);
LRESULT SHNotificationUpdate(DWORD grnumUpdateMask,
SHNOTIFICATIONDATA *pndNew);
LRESULT SHNotificationRemove(const CLSID *pclsid, DWORD dwID);
LRESULT SHNotificationGetData(const CLSID *pclsid, DWORD dwID,
SHNOTIFICATIONDATA *pndBuffer);
They allow you manipulate the notification's look-and-feel and features. Windows Mobile 5.0 slightly extends WM 2003's functionality by adding new members to the SHNOTIFICATIONDATA struct:
typedef struct _SHNOTIFICATIONDATA
{
DWORD cbStruct; // for verification and versioning
DWORD dwID; // identifier for this particular
// notification
SHNP npPriority; // priority
DWORD csDuration; // duration of the notification
// (usage depends on prior)
HICON hicon; // the icon for the notification
DWORD grfFlags; // flags - see SHNF_ flags below
CLSID clsid; // unique identifier for the
// notification class
HWND hwndSink; // window to receive command choices,
// dismiss, etc.
LPCTSTR pszHTML; // HTML content for the bubble
LPCTSTR pszTitle; // Optional title for bubble
LPARAM lParam; // User-defined parameter
// From here, this is WM 5.0 stuff
union
{ // Defines the softkey bar for the
// notification
SOFTKEYMENU skm; // Either pass an HMENU in skn
// (and set SHNF_HASMENU)
// or two softkeys in rgskn.
SOFTKEYNOTIFY rgskn[NOTIF_NUM_SOFTKEYS];
};
// Text to put on SK2 on the Today screen. If NULL, will
// default to "Notification"
LPCTSTR pszTodaySK;
// What to execute when SK2 is pressed. If NULL, the toast
// will be displayed.
LPCTSTR pszTodayExec;

} SHNOTIFICATIONDATA;
The following code sample shows one simple scenario:
void ^157BOOL158^::OnBnClickedButton1()
{
SHNOTIFICATIONDATA sn = {0};

sn.cbStruct = sizeof(sn);
sn.dwID = 1971;
sn.npPriority = SHNP_INFORM;
sn.csDuration = 15;
sn.hicon = LoadIcon(AfxGetResourceHandle(),
MAKEINTRESOURCE(IDR_MAINFRAME));
sn.clsid = SAMPLE_GUID;
sn.grfFlags = 0;
sn.pszTitle = TEXT("Sample Notification");
sn.pszHTML = L"<html><body><p><form method="POST" action=>"
L"<p><font color="#0000FF">"
L"Visit <a href="www.developer.com">
<b>Developer.com</b></a> !"
L"</font></p>"
L"<p align=right>
<input type=button name='cmd:1001' value='OK'>"
L"<input type=button name='cmd:1002'
value='Cancel'></p>"
L"</body></html>";
sn.rgskn[0].pszTitle = TEXT("Dismiss");
sn.rgskn[0].skc.wpCmd = 1003;
sn.rgskn[0].skc.grfFlags = NOTIF_SOFTKEY_FLAGS_DISABLED;
sn.rgskn[1].pszTitle = TEXT("Hide Me");
sn.rgskn[1].skc.wpCmd = 1004;
sn.rgskn[1].skc.grfFlags = NOTIF_SOFTKEY_FLAGS_HIDE;
sn.pszTodaySK = L"Run Calc";
sn.pszTodayExec = L"\windows\calc.exe";

//Add the notification to the tray
SHNotificationAdd(&sn);
}
Under WM 5.0, you can customize how your notification will appear when displayed for the user:

and on the Today screen:

Shortly speaking, both User or Shell Notifications API are intuitive enough; hence it isn't worth spending too much time on it now. There are a lot of samples all over the Web in C/C++ or C# or VB. That's not a point here. Real troubles start when a device gets turned off. And, here is when Power management can help us.

Involving Power Management

The Windows Mobile OS has a dozen functions that allow applications to control the power policy and query various information. Once again, I won't discuss them too much, but move on to the situation described in the preface.
When a device has been suspended and after any notification gets activated, the system turns to a "resuming" power state. In such a mode, the CPU is running, but the display is not powered to save the battery. Moreover, some of the PDA's features may be inactivated as well; for example, the GPRS modem. "Resuming" the power state continues for 15 seconds, and then, if nothing happens, a device will be suspended once again. Thus, you face the situation when your application is honestly called, but it can't interact with the external world or gain the user's attention. For background operations, it works like a charm, but for notifications, that is not the case. Thus, you need a way to turn on the system. The obvious answer is to call:
SetSystemPowerState(
LPCWSTR pwsSystemState,
DWORD StateFlags,
DWORD Options
);
as follows:
SetSystemPowerState(NULL, POWER_STATE_ON, 0);
In other words, such a call simply wakes up the device and gets it to its full live state. That is exactly what you need in many cases. Later on, you also can call:
SetPowerRequirement(
PVOID pvDevice,
CEDEVICE_POWER_STATE DeviceState,
ULONG DeviceFlags,
PVOID pvSystemState,
ULONG StateFlags
);
to require an 'always on' state while doing some lengthly operation; for example, communications. And with that said, this story has its "happy ending."
Thứ Bảy, 15 tháng 10, 2011 01:28 Đọc tiếp >>

Porting Your Mobile Applications to the VS 2005 Environment

MS Visual Studio 2005: Why Be Bothered with It?

With the release of MS Visual Studio 2005 last November, Windows Mobile 5.0 at the very end of its beta cycle, and a proliferation of WinCE 5.0-powered devices, it is time to commence considering to move your C/C++ mobile applications from eMbedded Visual C++ to the new development environment. You can reasonably ask why you should do it at all and battle new headaches if you still can continue to use existing developing tools and libraries. In my opinion, there are serveral reasons that could cause you to think it over seriously right now. I will leave aside the features of the IDE itself and discuss the pros and cons with a developer's vision.

Porting Possibilities

If you have an existing eVC project and want to import it into VS 2005, you have two options. One is to use eVC Upgrade Wizard add-on for VS 2005, which is available for download from Microsoft's site here. If you take a look at the bottom part of this page, you will see a notice that this is an unsupported addon, so you have a good chance to experience some problems with it. Nevertheless, it may help you migrate your project easily enough. You might be required to adjust some of the project settings—for example, a way of MFC usage—but usually they are really minor ones.
The second way is to create a brand new solution and projects and then manually add all files. It looks more a more difficult method, but in some cases this is the only thing to do because you can get the standard header files and project settings. This allows you to avoid some weird warnings and problems during solution compilation and linkage. Links at the end of this article may help you get more details.
Whichever way you use, now you have your application available under the MS Visual Studio 2005 IDE.

Benefits and Issues

C/C++ projects support and emulators

First of all, VS 2005 comes with support for native C/C++ projects and new emulators for smart devices. If you have had the chance to code really large mobile projects with millions of code lines, you will agree that it was almost impossible to use SDK emulators from eVC 3.X or 4.X. They are slow, they are not robust, they are... This left only one alternative to a developer: to use the old Palm-Size 2.11 emulator. It obviously made a serious impact on such applications. With new emulators, you can get rid of the old dragon. Not only that it is fast enough, but also is able to execute the code compiled for real devices, which is a nice capability. Thus, your application will look and behave more like its real instance on the handheld.


Native device C/C++ projects support hasn't came for free. Microsoft made many additions to the C++ compiler ever since VS 2003 in comparison with eVC++, and the new Studio also keeps pace. It results in many tiny but annoying compiler errors like the following case:
//
for (int i = 0; i < nCount; i++)
{
...
}
...
for (i = 0; i < nCount2; i++)
{
...
}
The second for statement will generate an 'undeclared variable' error. I haven't yet seen any C++ programmer who would write the above code in C-style.
int i = 0;
...
for (i = 0; i < nCount; i++)
{
...
}
...
for (i = 0; i < nCount2; i++)
{
...
}
so you may evaluate a number of possible changes here. You will find additional info regarding new C/C++ compiler features among the links at the end of the article.

Moving Forward to MFC 8.0

If your application uses the MFC library for Windows CE, you can expect many surprises as well, and they are not always pleasant. Version 8 of MFC and ATL were significantly changed since previous MFC 3.0 times. Some changes were expected, for instance, new string classes, but other ones I honestly can't get. Just take a look at the following list of unsupported classes (you can get full info here):
  • CSplitterWnd
  • CDialogBar
  • CReBar
  • CColorDialog
  • CFindReplaceDialog
  • CFontDialog
  • CPrintDialog
  • COlePropertyPage
  • CEditView
  • CBitmapButton
  • CReBarCtrl
  • CSocketFile
  • CInternetFile
  • CHttpFile
  • CLongBinary
  • CInternetSession
  • CInternetConnection
  • CHttpConnection
  • COleSafeArray
  • CPrintInfo
  • COleCmdUI
  • CDAOFieldExchange
  • CDBVariant
  • CFieldExchange
  • COleDataObject
  • CRecentFileList
  • COleCurrency
No doubt, classes such as CPrintDialog weren't useful under Windows CE, but CBitmapButton or CDialogBar did their jobs very well. A sad conclusion from those library changes is that you should hurry up and look for equivalent replacements for unsupported classes as soon as possible.
But this is not the end of the story. Far from it! If you will examine the MFC headers, you can find a lot of code similar to the following snippet:
class CFont : public CGdiObject
{
DECLARE_DYNAMIC(CFont)

public:
static CFont* PASCAL FromHandle(HFONT hFont);

// Constructors
CFont();
BOOL CreateFontIndirect(const LOGFONT* lpLogFont);
#ifndef _WIN32_WCE // Unsupported Win32 API call
BOOL CreateFont(int nHeight, int nWidth, int nEscapement,
int nOrientation, int nWeight, BYTE bItalic,
BYTE bUnderline, BYTE cStrikeOut, BYTE nCharSet,
BYTE nOutPrecision, BYTE nClipPrecision,
BYTE nQuality, BYTE nPitchAndFamily,
LPCTSTR lpszFacename);
#endif // !_WIN32_WCE
...
};
Once again, I appreciate the new MFC version. It required improvements, but this and similar differences may hurt your application badly. As the best case, you can inherit your own class—say, CMyFont—that implements a lack of functions:
class CMyFont : public CFont
{
public:

// Constructors
CMyFont();
BOOL CreateFont(int nHeight, int nWidth, int nEscapement,
int nOrientation, int nWeight, BYTE bItalic,
BYTE bUnderline, BYTE cStrikeOut, BYTE nCharSet,
BYTE nOutPrecision, BYTE nClipPrecision,
BYTE nQuality, BYTE nPitchAndFamily,
LPCTSTR lpszFacename)
{
LOGFONT lfFont;
memset(<lfFont,0,sizeof(lfFont));

lfFont.lfHeight = nHeight;
lfFont.lfWidth = nWidth;
lfFont.lfWeight = nWeight;
lfFont.lfEscapement = nEscapement;
lfFont.lfOrientation = nOrientation;
lfFont.lfWeight = nWeight;
lfFont.lfItalic = bItalic;
lfFont.lfUnderline = bUnderline;
lfFont.lfStrikeOut = cStrikeOut;
lfFont.lfCharSet = nCharSet;
lfFont.lfOutPrecision = nOutPrecision;
lfFont.lfClipPrecision = nClipPrecision;
lfFont.lfQuality = nQuality;
lfFont.lfPitchAndFamily = nPitchAndFamily;
_tcscpy(lfFont.lfFaceName,lpszFacename);

return CreateFontIndirect(&lfFont);
}
but this is not always feasible. Be ready for the black box job, folks!

Windows Mobile 5.0

The last, but not the least, thing is that VS 2005 is the only way now to develop for Windows Mobile 5.0. Handhelds with Windows Mobile 2003 OS or CE.NET 4.X are at the end of their lifetime. I guess it will take up to one or two years to wipe out any of them. Hence, the development for a new OS version becomes important 'today'—quite literarily. With many exciting features, Windows Mobile 5.0 will pass over its birthright issues and rise an applications development process to the next level, for our common happiness.

Related Links

Thứ Bảy, 15 tháng 10, 2011 01:26 Đọc tiếp >>

An Introduction To PowerShell

Overview

Windows PowerShell is a new command-line shell and scripting language created by Microsoft. Why yet another shell, you ask? Well, PowerShell is different. Of course, every new shell claims to be "different." However, few, if any, live up to this claim, but PowerShell has some features that truly distinguish it from other shells. In this article, you will look at some of the PowerShell scripting language features and create a PowerShell script from scratch.

A Brief History of the Windows Command-Line Shell

Since the introduction of Windows NT, CMD.EXE has been the command-line shell for Windows. Although CMD.EXE provided an improved command-line experience over its DOS predecessor, COMMAND.COM, it still relied on a relatively primitive scripting language, Windows Command (.CMD and .BAT) files. The later addition of Windows Scripting Host, and the VBScript and JScript languages, greatly improved the scripting capabilities of the shell.
These technologies combined to form a fairly comprehensive command-line shell and scripting environment. There is not really a question of how much you can accomplish with CMD.EXE, .CMD files, and Windows Scripting Host. Rather, the primary complaint is the proverbial "hoops to jump through" to accomplish some seemingly simple task.
Using this "framework" of command-line and scripting tools, any moderately complex script requires a mix of batch commands, Windows Scripting Host, and stand-alone executables. Each of these, in turn, use different conventions for execution and requesting, parsing, and returning data.
Weak variable support in CMD.EXE, inconsistent interfaces, and limited access to Windows settings combined with one other weakness make command-line scripting more difficult than it has to be. What is the one other weakness, you ask? Text. With these technologies, everything is text. The output of one command or script is text and must be parsed and re-formatted to work as input for the next command. This is where PowerShell makes a radical departure from all traditional shells.

PowerShell Scripts == Batch Files on Steroids


PowerShell itself is written in a .NET language and relies heavily on the .NET Framework. Because of this, PowerShell was designed from the ground up as an object-oriented shell and scripting language. Everything in PowerShell is an object and has the full capabilities of the .NET Framework. A command returns a set of objects that can then utilized by using the properties and methods of that type of object. When you want to pipe the output of one command into another command, PowerShell actually passes the objects, not just the textual output of the first command. This gives the next command in the pipeline full access to all of the objects properties and methods.
The treatment of everything as an object, and the ability to pass objects between commands is a major shift of philosophy for command-line shells. That said, PowerShell still functions much like a traditional shell. Commands, scripts, and executables can be typed and ran from the command-line and the results are displayed in text. Windows .CMD and .BAT files, VBScripts, JScripts, and executables that work in CMD.EXE all still run in PowerShell. However, because they are not object-oriented, they do not have full access to the objects created and used in PowerShell. These legacy scripts and executables will still treat everything as text, but you can intermingle PowerShell with these technologies. This is very important if you want to start using PowerShell, but have a complex set of existing scripts that you are not able to convert all at once.

A PowerShell Script

Reading about great new technology is one thing, but seeing it and using it makes comprehension easier. In the rest of this article, you will develop a PowerShell script as a demonstration of PowerShell's capabilities and ease of use.
DIR is one of the most-used command in CMD.EXE. It lists the files and folders contained in a folder, as shown in Figure 1. Along with the names of each, it shows the last modified date and time, and the size of each file. DIR also shows the combined size of all the files in the specified folder, as well as the total number of files and the total number of sub-folders.

(Full Size Image)
Running DIR in PowerShell also produces a directory listing. However, as Figure 2 shows, it looks a little different. PowerShell does not have a native command called DIR, but it does have one called Get-ChildItem, which performs a similar function. In PowerShell, DIR is an alias for Get-ChildItem; I am not going to cover aliases in this article, but you can think of DIR in PowerShell as a shortcut for Get-ChildItem.
DIR in PowerShell provides much of the same information: a file and folder listing, the last modified date and time, and the size of each file. However, it is missing the summary information that DIR in CMD.EXE provides: the total size of all the files in the folder, the total number of files, and the total number of sub-folders.

(Full Size Image)
For your script, you will create a PowerShell script that will mimic the CMD.EXE DIR command. In the next section, I will explain the key parts of the script.

DIR.PS1: The Header

A PowerShell script consists of PowerShell commands in a plain text file with a .PS1 extension. For your DIR replacement, you will use a text file called DIR.PS1.
To run the script, type the following at a PowerShell prompt:
.\DIR.PS1 X:\Folder
where X is a drive letter and Folder is the name of a folder.
The first part of your script will display the same header information that the CMD.EXE DIR command produces. You need to determine the drive letter of the path that was passed into the script. Arguments to scripts are stored in an array called $args (all PowerShell variables begin with a $). To keep things simple for now, you are only going to deal with the first argument that was passed into your script and ignore the rest. Therefore, you will create a variable called $drive and set it equal to $args[0] (0 is the first element of all arrays in PowerShell).
$drive = $args[0].SubString(0, 1).ToUpper()
To get some of the information you need about the drive, you will have to utilize Windows Management Instrumentation (WMI). The details of WMI is outside of the scope of this article, but the following PowerShell code is pretty easy to understand. You create a variable, $filter, to use with the Get-WmiObject command. The filter you have created tells the command that you only want information about a particular disk. The results of the Get-WmiObject command are stored in a variable called $volInfo. Remember, in PowerShell everything is an object; $volInfo is now an object returned from Get-WmiObject.
$filter = "DeviceID = '" + $drive + ":'"
$volInfo = Get-WmiObject -Class Win32_LogicalDisk -Filter $filter
You now have access to all of the properties and methods associated with this object. The serial number of the drive can be accessed via the VolumeSerialNumber property. The serial number is returned as an 8-character string, but you want to format it as the first 4 characters followed by a dash, and then the last 4 characters. In the line below, the backtick character at the end of the first line is the PowerShell line continuation character. Basically, it just tells PowerShell that the line continues on the next line. Splitting the line is not required, but I did it here to decrease the width of the line and to improve the readability of the script.
$serial = $volInfo.VolumeSerialNumber.SubString(0, 4) + "-" + `
$volInfo.VolumeSerialNumber.SubString(4, 4)
Now that you have the $volInfo object, you can write the DIR header information to the screen. If a volume has no label, the text written to the screen is slightly different than if the volume does have a label. A simple If-Else statement is used to determine whether the VolumeName property is equal to an empty string. The Write-Host command is used to write each line to the screen.
If ($volInfo.VolumeName -eq "")
{ Write-Host (" Volume in drive " + $drive + " has no label") }
Else
{ Write-Host (" Volume in drive " + $drive + " is " +
$volInfo.VolumeName) }
Write-Host (" Volume Serial Number is " + $serial)
Write-Host ("`n Directory of " + $args[0] + "`n")
The "`n" at the beginning and end of the last Write-Host command is used to insert a newline before and after the text. The Write-Host command adds a newline at the end of each line itself, so the effect of the "`n" is to make a blank line before and after that line of text.
Did you notice the "-eq" in the If statement? That is the equality comparison operator. The table below shows all of the comparison operators:
-eq, -ieq Equals
-ne, -ine Not equals
-gt, -igt Greater than
-ge, -ige Greater than or equal
-lt, -ilt Less than
-le, -ile Less than or equal
The -i versions of the comparison operators are the case-insensitive versions.
Figure 3 shows the output of the script you have so far.

DIR.PS1: The File/Folder Listing

Now, you are ready to display the contents, and their properties, of this folder. The first thing you will do is call the PowerShell Get-ChildItem command with the folder name passed into the script as a parameter. The Get-ChildItem command will get the collection of file and folder objects, not just names, and then pipe those objects directly into the Sort-Object command to sort them. By default, the Sort-Object command will sort based on the Name property of the objects, so you do not need to specify any additional parameters. The sorted collection of objects will then be stored in the variable named $items.
$items = Get-ChildItem $args[0] | Sort-Object
Once you have a collection of file and folder objects, you need to loop through them and display the appropriate properties. To loop through the objects, you use the ForEach command. For each file or folder in your $items collection, you will get the last modified date and time, the name, and the length or size file. The strange looking strings inside the curly brackets are .NET string formatting codes. I use them to easily right- or left-align fields and format dates, times, and numbers. Understanding the string formatting code is not crucial to understanding this script.
The If statement is where you determine if an item is a directory. If the first character of the Mode property equals "d", the item is a directory. You need to check because what you write to the screen for directories is different than what you write for files.
Notice the $totalDirs++ line inside the If statement. It is the counter that keeps track of the number of directories in this directory. Similarly, there is a $totalFiles variable that is used to track the number of files and a $totalSize variable that tracks the total size of all of the files. These values are computed now, but you will not display them until the end of the file listing.

ForEach ($i In $items)
{
$date = "{0, -20:MM/dd/yyyy hh:mm tt}" -f $i.LastWriteTime
$file = $i.Name
If ($i.Mode.SubString(0, 1) -eq "d")
{
$totalDirs++
$list = $date + " {0, -15}" -f "
" + " " + $file
}
Else
{
$totalFiles++
$size = "{0, 18:N0}" -f $i.Length
$list = $date + $size + " " + $file
}
$totalSize += $i.Length
Write-Host $list
}
Figure 4 shows the output of the script of the updated script.

(Full Size Image)

DIR.PS1: The Footer

The only thing left to do is write to the screen the total count of files and directories, the total size of the files, and the available free space on this drive. To do this, you will utilize the counter variables ($totalFiles, $totalDirs, $totalSize) that you created in the previous section of the script and you can get the available free space from the $volInfo variable that you created back at the beginning of the script.
Write-Host ("{0, 16:N0}" -f $totalFiles + " File(s)" + `
"{0, 15:N0}" -f $totalSize + " bytes")
Write-Host ("{0, 16:N0}" -f $totalDirs + " Dir(s)" + `
"{0, 16:N0}" -f $volInfo.FreeSpace + " bytes free`n")
Figure 5 shows the complete output of the script.

(Full Size Image)

Caveats and Possible Improvements

Although the script you created produces nearly identical output to the CMD.EXE DIR command, there are a few caveats to be aware of and some possible improvements you could make.
  • This script does not perform any error checking.
  • If a valid path is not passed into the script, the script will fail with a PowerShell error message.
  • The directory count displayed by the script is 2 less than the CMD.EXE DIR command because the Get-ChildItem command does not include the "." and the ".." directories like the CMD.EXE DIR does.
  • Your script sorts by file/folder name by default and does not offer any way to sort by any other attribute.
  • Your script does not have the ability to display the contents for a folder and all of the sub-folders.

Conclusion

Although PowerShell is a powerful shell and scripting language, it can take a little time to really grasp it, especially if you are not already familiar with the .NET Framework. I hope that this article and script will be useful to anyone trying to learn about PowerShell. Even though the script that you created is fairly simple, I believe it can serve as a good foundation for building upon.

Thứ Bảy, 15 tháng 10, 2011 01:25 Đọc tiếp >>

Porting Mobile Applications Between Windows Mobile and Symbian OS

Why May You Ever Need to Port Your Mobile Applications?

The recent state of the mobile market is quietly challenging from a developer's perspective. A competition among Symbian OS, Linux, Windows Mobilem and few others (Palm, BREW, Apple, and proprietary OSes, just to mention a few) demands some degree of flexibility from your product. It means that you need to keep in mind how to design your system to be able to support multiple operating systems with minimal headaches while porting. Obviously, you might choose not to bother with porting at all to make your developer's life easier, but more often than not you simply have no choice because your competitors do it. I don't mention such a motive as covering wider markets and so forth. Having said this, one needs to make a decision (and not always a simple one); is it worth it to port existing application to a new platform? In many cases, the answer is "YES;" you may choose to port it instead of re-writing it from scratch. It will require some additional work, of course, but the outcome may benefit you a lot. The porting assumes that you may re-use your code and even make it much more robust.

What Effort Will It Require?

There are several well-established patterns for cross-platform development. You can choose to use any of them if you designed your application recently. When you consider the possibility of porting an existing application, the answer may be not so encouraging. In the case of Symbian OS and Windows Mobile, the differences in the platform API are significant, so it is pretty possible that you will have to re-develop all from scratch. Nevertheless, there are many similar concepts and functional API/classes that may be easily replace each other. On the bright side, it may be possible to re-use your existing application design. You still have to create appropriate implementations, but at least the main application structure and control flow remain the same.
The main idea behind porting techniques in regard to the discussion may be expressed as follows: a separate GUI and engine for your application. Most recent frameworks use this paradigm in some form. Symbian OS applications have it naturally due to various GUIs built upon the same Core OS and multiple target platforms. MFC comes with a similar approach for SDI architecture (or WTL classes if you don't like MFC). Hence, if you followed the guidance and have an engine and the GUI separated, you're quite lucky. Most of the platform-independent code may be re-used with some modifications. If your application utilizes STL, that helps you too, because both platforms have STL support. POSIX-compliant applications are in the best position because they require minimal porting effort. So, generally speaking, the more platform-neutral code you have, the easier porting will go.
Obviously, the real situation is usually far from ideal. More often than not, you may have the GUI and engine mixing up, GUI handlers keeping some knowledge about the data, and so forth. Well, if you are already facing the need to port, maybe it is a good time to make the code cleaner. The minimal price you have to pay is to re-develop all GUI parts of the application because it will be certainly different between various OSes. As I said earlier, in case of using standard frameworks, it should not be a big issue, though. You still will be able to have the Application object, Document, and View objects in C++ code or use suitable classes in C# for the majority of the situations.
Another aspect of the porting process to consider will be some 'common type system.' Symbian OS C++ applications use (or at least are encouraged to use) prefix-based type names, such as 'T', 'C', 'M' and 'R' classes. T-classes may be easily #define-ed and mapped to standard C++ types; for example, Tint becomes int and vice versa, BOOL matches TBool, and so forth. Just keep in mind the size of the given type when doing such remapping to avoid any problems with using sizeof(); for example, sizeof(BOOL) and sizeof(bool) are different. For more complicated classes, #define directives also may help where possible. Nevertheless, usually you re-implement particular missing methods for either platform. Having such 'neutral' functions makes all the process much easier.

The Differences You Ought to Remember


There are a few basic differences between Symbian OS and Windows Mobile OS you will come across first. I will outline them as the following:
  • CBase class in Symbian OS
  • Two-phase construction in Symbian OS
  • Leaves in Symbian OS vs. Exceptions in Windows Mobile
  • Descriptors in Symbian OS vs. C-style strings or BSTR in Windows Mobile
Those are not the only differences you spot during the porting, but rather the most obvious ones. Let me talk about them one by one.
The CBase class in Symbian OS, being a base class for all heap-based 'C' classes, ensures that all class members are zeroed. This fact should be taken into account when you port in either direction to avoid unexpected or unpredictable behavior during code execution. If you port from Symbian OS to Windows Mobile, be sure that all class members are initialized properly. I would say that it is a good practice in general terms.
The next thing is a two-phase construction mechanism that is extensively employed in Symbian applications. It is a robust solution to prevent memory leaks during object initialization. Windows developers often allocate memory directly in constructors. I personally think that this is bad practice and should be avoided where possible because it is pretty hard to control the initialization process if something goes wrong. Imagine that you just declared a member of some class or even a variable on the stack. If a constructor may, for example, throw exceptions, it is quite possible that you will observe very strange behavior under stress conditions. Two-phase construction allows you to avoid such situations and proposes that your class has protected constructor (which only initializes class data members, no allocations there) to prevent direct instantiation of the class instances, static NewL() method to act as a class factory, and a protected Construct() method that performs all required allocations and other tasks. For the Symbian component, you will be forced to follow this coding style; for Windows Mobile applications, you may easily implement similar initialization scheme. So, you can swing from Symbian OS code:
// Typical Symbian OS class sample
EXPORT_C CYourClass* CYourClass::NewL()
{
CYourClass* self = new (ELeave) CYourClass;
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}

EXPORT_C void CYourClass::ConstructL()
{
// Put your implementation here
}

EXPORT_C CYourClass::CYourClass()
{
// Put your implementation here
}
to something like the following snippet in Windows Mobile:
// Windows Mobile implementation
CYourClass* CYourClass::NewL()
{
CYourClass* self = new CYourClass;
if (self == 0)
throw ("Memory allocation error for CYourClass");

//pass ownership to an auto_ptr
std::auto_ptr<CYourClass> aptrSelf(self);
aptrSelf->ConstructL();

// release self - if we did not, self is deleted when the
// auto_ptr goes out of scope
self = aptrSelf.release();
return self;
}

void CYourClass::ConstructL()
{
// Put your implementation here
}

CYourClass::CYourClass()
{
// Put your implementation here
}
The sample above shows also what a 'Symbian'-style for object's initialization is.
Once you have isolated your Engine code into a DLL, for Windows Mobile implementation you can provide simple C-style methods for creation, deletion, and other operations upon objects in a given library. Such an approach is convenient when you plan to use the component—for example, from C# code. The Symbian OS uses the method's index rather than name to get access to the code within the DLL, so you will be able to use exported classes directly from your Symbian application and don't need to bother about additional exported functions.
If you code for Symbian OS, you know what "Leave" means. For Windows developers, it should be treated as an alternative to an exception handling. Many people may blame Symbian for not supporting exceptions, but what's done is done, so you can't help but accept it. According to Symbian's coding convention, all functions with names ending with 'L' may leave. Hence, you should implement the same in your Windows Mobile code. And vice versa, in your Symbian code make the method leave when the original function throws an exception.
And finally, descriptors and strings. The former may be considered as an analogue to BSTR under Windows and can hold both string and binary data. Descriptor manipulation in Symbian OS is painful, no doubt, but with the Carbide.c++ IDE coming onto the scene, you will be able to see their values during debugging at the least. If you can afford using STL port for Symbian OS, it will be a bit easier. Thus, in many cases, std::wstring will be a sufficient replacement for various descriptor classes. With MFC/WTL, you may use CString class as well.

Conclusion

In this article, I discussed a few general topics that may help you when porting various applications between Symbian OS and Windows Mobile OS. As you have seen, such porting is not always possible and often requires too much effort. Nevertheless, you still can use some parts of your existing code, perhaps adopted to new environment. To get some initial feeling of the whole process, you might apply it to one of the samples coming with each SDK; for instance, with WM50 or S60 SDK. Enjoy!
Thứ Bảy, 15 tháng 10, 2011 01:22 Đọc tiếp >>

Visual C++ Smart Device Primer

Many developers shy away from embedded development for a number of reasons—difficulty in understanding the wide array of Windows CE/ Windows Mobile configurations, uncertainty about how to get started with an embedded project, and perceived difficulties in device debugging. This article aims to address all these issues, and get C++ developers familiar with the great opportunities that exist in life outside the desktop/ server environment.
Before digging into the mobile C++ development world, it is worth briefly looking at the managed alternatives. As with the desktop world, managed development is possible in the embedded world by using a cut-down version of the .NET Framework officially titled the Microsoft .NET Compact Framework. The .NET Compact Framework has been notoriously lacking in many of the features that exist in the main .NET Framework, and an old joke circa .NET Compact Framework 1 is that the Compact Framework is a wrapper around the System.NotImplementedException (and the fact that earlier versions of the Compact Framework did not include the NotImplementedException type highlighted how 'compact' it truly was).
Although the functionality available in the .NET Framework has significantly increased with each new version, and .NET Compact Framework 3.5 has some great features from the full version—like LINQ—included, two significant issues will continue to exist with the .NET Compact Framework for the foreseeable future. The first problem is the lag between the release of a Compact Framework version and its inclusion in the ROM image that a particular embedded device ships with. Windows Mobile 6 is the latest release of the CE/Mobile family, and it includes version 2 of the Compact Framework. When version 3.5 ships shortly, any application that uses it will need to ensure that target device has the 3.5 Framework installed; this chews up valuable memory on the device that could otherwise be used by other applications. For the majority of devices in production that are running Windows Mobile 5 or older, the situation is worse, because they are likely to ship only with the feature-poor version 1 of the Compact Framework. The second issue with the Compact Framework is a small range of features for interacting with the actual device on which the application is running. As with the main Windows version of the Framework, .NET is great for writing code for applications that run on top of the operating system, but for applications that want to have significant interaction with the newer and more esoteric features of the host OS, C# and Visual Basic.NET are poor alternatives to C++.
For many years, C++ developers producing server and desktop applications for Windows only had to worry about a single processor instruction set (x86) and a single SDK (the Win32 SDK), and although the advent of two distinct 64-bit processor architectures has slightly complicated the picture, life is still relatively simple for the developer. In contrast, the embedded world is markedly more complicated, with a great variety of processors, devices, and operating system builds that could potentially be targeted by a single code-base. Sitting on top of the wide variety of device form-factors is the Windows CE operating system, which has been officially renamed "Windows Embedded CE" in the recent 6.0 release. Windows CE consists of an operating system kernel and an array of optional components that a device OEM can configure to include in a particular build. Because of the wide variety of devices that Windows CE can support, an application developer will typically target a pre-defined build of Windows CE rather than attempting to provide support for all possible device configurations.
Windows Embedded CE 6.0, which was released in November 2006, has three Microsoft-defined platforms that a device OEM can choose to license for installation onto a particular device: Windows Mobile 6 Standard (which is the latest version of the platform formally known as Windows Mobile for Smartphone), Windows Mobile 6 Professional (formally known as Windows Mobile for Pocket PC Phone Edition), and Windows Mobile 6 Classic (formally known as Windows Mobile for Pocket PC). Windows Mobile Classic is customized for PDA devices that don't have any telephony functionality, such as the HP iPAQ. Windows Mobile Standard is for Windows phone devices that have a traditional phone-form factor that consists primarily of a non-touch screen and numeric keypad, and Windows Mobile Professional is for hybrid devices that have both phone and PDA functionality.

Although it may seem like a tedious exercise in nomenclature trudging through the previous and current versions of Windows CE platforms, understanding the various CE platforms is critical from a developer's perspective because there is an SDK for each corresponding platform. Each different platform has subtly different components and features that are available, and the correct SDK must be installed to target the appropriate device. For Windows Mobile 6, two separate SDKs are available—the Windows Mobile 6 Standard SDK that targets Windows Mobile Standard and the Windows Mobile 6 Professional SDK that targets Windows Mobile 6 Classic and Windows Mobile 6 Professional. So, thankfully, the choice of which SDK to use for which Windows Mobile 6 devices comes down to a simple decision point: Does the target device have a touch-screen? Both SDKs can be downloaded from the Microsoft Download Center, and will install with either Visual Studio 2005 or 2008.
Now that the groundwork has finally been laid, it's time to have a look at the C++ developer experience for a mobile application. The first task is to ensure that the Visual C++ Smart Device Programmability option is selected when Visual Studio is installed; without this, the SDKs will not be able to install the full range of C++ options. The next step is to download and install the required SDK, which will integrate with Visual C++ and add a number of new options to various Smart Device project templates.
There are a number of different project types available for mobile development; the three main options are Win32, MFC, and ATL. The options have the same pros and cons as their desktop equivalents—Win32 provides the leanest executable with the easiest deployment requirements but comes at the expense of a more tedious developer experience. ATL is a lightweight application framework optimized for COM development and allows both DLL and EXE development for CE-based devices, and MFC provides the richest framework for application development at the expense of a heavier runtime. MFC has separate projects for executables, ActiveX controls, and DLLs.
Once the appropriate project type has been selected, the supported platforms for the project need to be selected, as shown in Figure 1. Each additional supported platform adds a separate build configuration to the project in much the same way as having different 32- and 64-bit build configurations for a desktop application. It is also possible to add new configurations to support different processor architectures and different compile options.

(Full Size Image)
Figure 1: Supported Windows Mobile Platforms
With desktop development, pressing the F5 key launches the application and attaches the debugger, but for smart device applications, they need to be run in an environment that simulates the real-world device that they will run on. The Windows Mobile SDKs ship with a number of emulators that correspond to a variety of device form factors that exist, and these can be selected from a drop-down on the Visual Studio Devices toolbar, as shown in Figure 2.


Figure 2: Device Emulators Available with Windows Mobile 6
When F5 is pressed inside Visual Studio for a Smart Device project, the nominated emulator will launch, Visual Studio will deploy the application to the device, and it will be launched with the debugger attached. Figure 3 shows a 'Hello World' MFC application running on the Windows Mobile 6 Classic Emulator.

Figure 3: MFC Hello World on Windows Mobile 6 Classic Emulator

Conclusion

Hopefully, this article has lifted some of the mystery surrounding mobile-device development. Once the confusing array of terminologies has been peeled back, mobile development is not as complex as it initially appears, and Visual Studio offers tremendous support for development and debugging of mobile applications. With the basics out of the way, you'll dig deeper into the various subtleties of MFC, ATL, and Win32 Mobile Development in the next article.
Thứ Bảy, 15 tháng 10, 2011 01:20 Đọc tiếp >>

Windows Mobile Development with MFC

Building Windows Mobile applications opens new development and business opportunities for a C++ developer, and given the issues with managed development on mobile devices that you covered in last month's article, C++ remains by far the best tool to take advantage over the wide range of development possibilities that Windows Mobile offers. This article examines how the frameworks and supported platforms for a Mobile Application (also referred to as a Smart Device application in the Visual C++ documentation) should be chosen, and then looks at the development process for a MFC Application.
With mobile development in C++, there are two important decisions to make before creating the project—which application framework (if any) will be used to build the application, and which Mobile SDKs will the application target. The type of functionality that the application offers will go a long way to deciding the appropriate application framework to use and SDK to target—for generic line-of-business applications such as an accounting application, the use of the MFC Smart Device Application that supports Pocket PC 2003 and above will be the best option. In contrast, the development of a plug-in for the Today screen of a Windows Mobile 6 Professional device obviously requires the corresponding SDK, and given that the plug-in will be loaded all of the time, the minimalist Win32 Smart Device Project option makes the most sense. In general, targeting the oldest SDK that contains the feature-set that will be used in a given application with the lightest application framework (Win32 followed by ATL followed by MFC) will be the best option. ATL sits between the more heavy-weight MFC option and the minimalistic Win32 option, and provides a wealth of support for COM development.
As with desktop development, it is difficult to anticipate all the features that an application will require when the application skeleton is first being developed, and as with development on the desktop and server, maintaining loose coupling at a source-code level between the various functional areas of an application is the best defence against the possibility that the targeted SDK or chosen application framework needs to change. In addition, rather than take a dependency on MFC just to use a few classes, it is preferable to use features in the C Runtime Library (CRT) and Standard C++ Library for utility types like strings and collections.
The final point worth making on choosing the appropriate starting point for a project is on the best technique for starting specialised applications that have a high degree of interaction with specific features of Windows Mobile such as the Today/Home screen, Internet Explorer Mobile, or a specific piece of hardware. For these specialized applications, it is often easier to start with a sample for the SDK that shows the basics of the task, strip the sample down so it is essentially a skeleton application, and then build on top of this skeleton. The alternative of starting with an App Wizard-generated project and then trying to add the configuration and set-up items to integrate the project with the device typically will be much harder. If it is likely that the skeleton application will need to be re-used as the basis for a number of applications, it is worth the effort to strip out all project-specific strings and make the skeleton into a Visual Studio project-type. It is a relatively easy undertaking, and will generate a positive return on investment with only a few uses.

MFC Smart Device Applications

Rather than provide a dry description of the application frameworks for Mobile Devices, the remainder of the article will follow the development of a MFC Smart Device Application that allows a user to check the number of hours that are booked on a particular date with appointments. All personal information manager (PIM) functionality provided on a Mobile device should be built on top of Pocket Outlook (see the Designed for Windows Mobile Software Application Handbook for other development guidance of a similar nature), and this sample will show how that can be achieved. The application offers reasonably rich functionality (at least with the scope of a demonstration application), so the use of MFC makes sense because it greatly simplifies the task of hooking together UI elements.

After the decision to use MFC has been made, the next decision is the range of devices the application will support. An inspection of the documentation related to the PIM functionality on Windows Mobile reveals that information on the calendar is available through the IPOutlookApp COM interface that has been part of Windows Mobile for a very long time (Pocket PC 2000 and above, according to the MSDN documentation for the interface), so targeting an old SDK like Pocket PC 2003 make sense. Most applications developed against older SDKs will work without modification on newer devices, and the range of emulators that are available with the various Windows Mobile SDK versions makes forward-compatibility checks simple to complete.
The code to implement the application is stock-standard MFC, with very little differences from standard MFC desktop development. The sample application is dialog- rather than document-based, so the Dialog option needs to be selected when the project is created, as shown in Figure 1. As with the desktop version of MFC, a dialog editor is present in Visual Studio to allow controls to be positioned with a WYSIWYG editor, and these controls then can be bound to a member variable in a particular C++ class. Data exchange between the control and member variable is achieved using the same Dialog Data Exchange (DDX) architecture as the desktop version of MFC.

(Full Size Image)
Figure 1: Creating the MFC Application

Downloads

CalendarInfo.zip

For the sample application, two controls are required—a date picker to allow the user to select the date for which Outlook information will be retrieved, and a button to begin the search. Once the results have been retrieved, a message box to show the total number of appointments on the nominated day will be displayed.
The actual code to retrieve data from Pocket Outlook is relatively straightforward. The first task is to initialise COM and create the root Outlook COM object (error handling has been stripped for readability, but is present in the sample code that accompanies the article):
#include <initguid.h>
#include <pimstore.h>

//inside button click handler
CoInitializeEx(NULL, 0);
IPOutlookApp * polApp;
CoCreateInstance(CLSID_Application, NULL,
CLSCTX_INPROC_SERVER, IID_IPOutlookApp, (LPVOID*)&polApp)
polApp->Logon(NULL);
Once Outlook has been logged in, the items in the calendar folder can be retrieved and searched:
IPOutlookItemCollection* pItems;
IFolder* pFolder;
polApp->GetDefaultFolder(olFolderCalendar, &pFolder);
pFolder->get_Items(&pItems);

IAppointment* pAppt;
CComBSTR query;
//populate query using date selected by user -- see sample for
//this code
//Sample query string:
//[Start] >=11/30/2007 00:00 AND [End] < 12/ 1/2007 00:00
pItems->Find(query, (IDispatch**)&pAppt);
The Find function is a general-purpose PIM querying tool, and works across all the different folder types such as Calendar, Contacts, and Tasks. If Find brings back any appointments for the selected date, the code simply loops through them and keeps a count of the total of minutes in appointments for display to the user:
long totalApptLength = 0;
long apptLength = 0;

if (pAppt){
pAppt->get_Duration(&apptLength);
totalApptLength += apptLength;
while(S_OK == pItems->FindNext((IDispatch**)&pAppt)){
pAppt->get_Duration(&apptLength);
totalApptLength += apptLength;
}
}
Figure 2 shows the end form of the sample, with a Message Box displaying the total booked minutes for a particular day.

Figure 2: Final version of the sample running in PocketPC 2003 Emulator
Although displaying the total number of minutes booked for a particular day isn't overly useful, it is easy to imagine the sample application extended to a more graphical presentation that could display some type of heat-map of the busyness of a particular day or week within the calendar to allow end-users to identify when they are heavily booked.

Conclusion

The developer experience in C++ with Windows Mobile is excellent, and moving from the desktop to the mobile device doesn't involve giving up a heap of functionality. The debug experience for an application is excellent—hitting F5 launches the emulator, copies the application across, and starts the application ready to debug. All the normal debug features work—breakpoints, tracing, and variable inspection all work fine. As the sample application shows, the MFC features such as the WYSIWYG editor and DDX that make development much quicker compared to the tedious construction of Win32 GUI apps are all present. C++ has the added advantage over its managed contemporaries with the richness of the libraries available for mobile development. Although C# and VB.NET rely heavily on the .NET Framework libraries to provide the helper classes needed to build an application, C++ developers have the freedom to bring in header and source code files from any location and compile them as part of their application.
Next month, you'll round out the tour of Windows Mobile with a look at ATL and COM development in the embedded world.
Thứ Bảy, 15 tháng 10, 2011 01:19 Đọc tiếp >>

Going Mobile with the Active Template Library

Outside of the Windows CE kernel where the C-style DLL prevails, COM is the most common technology used to expose key technology elements on embedded Windows devices. Many of the every-day activities that end-users perform with their Windows Mobile device are based on the COM architecture—ActiveSync, Pocket Outlook, Internet Explorer Mobile, the Soft Input Panel (SIP), and Windows Media Player all rely on COM as the primary integration technology. The C++ developer is uniquely placed to take advantage of these COM-based technologies, and the Active Template Library (ATL) is the best toolkit available for COM development.
COM and ATL are both huge topics, and have filled many previous books and articles. Rather than duplicate the already substantial body of literature that introduces COM and ATL, this article assumes some familiarity with COM and ATL development for the desktop and server environment, and primarily focuses on the subtle differences between the full version of COM and ATL and the Smart Device version.
Before drilling into the use of ATL to write COM components for Windows CE, it is worth briefly mentioning that ATL also simplifies COM programming when consuming components. COM relies on reference counts to determine when the memory associated with a component should be freed. The process of incrementing and decrementing the reference count of a COM object is a tedious and error-prone exercise, and ATL addresses this problem with the use of smart pointers. In a previous article, a Smart Device MFC project was shown that used Pocket Outlook to retrieve information about the time that was booked with appointments on a particular day. The project used standard interface pointers that required a call to Release to each interface before the interface pointer went out of scope.
To add ATL support to an existing MFC or Win32 project, simply bring up the project properties as shown in Figure 1, and select to statically or dynamically link to ATL. Static linking simplifies deployment, and is the recommended strategy for Smart Device projects. Once ATL support has been added, the raw interface pointers can be converted to ATL smart pointers by using the CComPtr template, so for the sample application, IPOutlookApp*, is replaced with CComPtr<IPOutlookApp>, and the call to Release can be removed.

(Full Size Image)
Figure 1: Adding ATL Support to Existing Projects

Smart Device ATL for Component Authoring

For experienced ATL developers moving from the desktop world, the first thing that they will notice about the Smart Device ATL Project Wizard is the lack of Attribute support. Attributes have been part of the desktop version on ATL since Visual Studio 2002, and allows developers to concentrate of defining classes and interfaces directly in C++ rather than the COM-specific Interface Definition Language (IDL). In the absence of attributes, Visual Studio support for adding controls and classes reduces the burden of developers needing to gain a deep knowledge of IDL, and the addition of a COM object to a project inside Visual Studio adds the required IDL code in addition to the generation of the C++ class skeleton. However, like any code generation technique that adds code to a number of separate files, the real challenge comes when a control needs to be renamed or moved to a different project. In this case, using the IDE to generate the skeleton of the new class and interfaces is recommended, after which the method bodies can be moved across using cut-and-paste techniques.
Many of the difference between the desktop and mobile versions of ATL reflect underlying differences in the supported COM features on these platforms. Windows Mobile does not support the un-registration of COM components; theref0re, the code generated by the ATL application wizard is different for a Smart Device Project. A call to CAtlDllModuleT:DllUnregisterServer still exists in the generated code, but an extra parameter is passed to the method to instruct the ATL framework to ignore the call.
One of the critical differences between ATL objects on the desktop and device is how threading models work. As a brief background, the COM infrastructure allows a COM object to nominate one of a number of different threading models via a Registry setting. COM components that are not thread-safe or have strong thread affinity could elect to live in a single-threaded apartment (STA), and COM would use windows queues to synchronize the delivery of calls to the object. COM components that handled their own thread safety needs could elect to live in the multi-threaded apartment (MTA), and these components typically had better performance and greater scalability characteristics compared to STA-residing components. The problem for MTA components was that they still exhibited a performance-hit due to marshalling of calls to components living in STAs, and this gave rise to free-threaded components that could move from the MTA to STAs and back again. Free-threaded components are implemented using a technique known as aggregating the free-threaded marshaller, and in addition to the thread-safety requirements of free-threading, special techniques need to be used when holding interface pointers to COM objects (the COM global interface table and the ATL helper class CComGITPtr greatly simplify the work of dealing with member variable interface pointers—see the MSDN documentation on CComGITPtr for further details.)
The critical point for ATL developers is that a Smart Device Project for most builds of the Windows CE operating system does not ship with a full COM implementation, and this includes all Windows Mobile builds. According to the documentation, the slimmed-down version of COM "provides a midrange implementation of COM and OLE automation that supports only in-process free-threaded objects and requires about 100-200 KB of memory." When using Visual Studio 2005 or Visual Studio 2008 to add a new ATL object to a project, a similar dialog to the full version of ATL is displayed, as shown in Figure 2. The main difference between the Smart Device and desktop version of the dialog is the hyperlink to documentation, and following this hyperlink explains that the options related to threading models available don't apply to most CE platforms, including Windows Mobile. Regardless of the threading model selected in the dialog shown in Figure 2, a free-threaded component will be generated.

(Full Size Image)
Figure 2: Adding a STL Simple Object to a Smart Device Project
Although the prospect of implementing a free-threaded component may not appear attractive to developers who have struggled with understanding the COM global interface table, it is worth noting that the complexities of needing to go between multiple STAs and the MTA do not exist in Windows Mobile because apartments are not present in the slimmed-down COM plumbing. The other point worth noting is that the primary use of COM on Windows Mobile is to integrate with and extend user interface elements such as the Soft Input Panel, Internet Explorer, and Media Player. In these scenarios, a COM component will be called on the user-interface thread, and will not be subject to the same level of multi-threading stress as a COM component in a server environment.
ATL simplifies the consumption and production of COM components, and the version of ATL available for Smart Device projects offers the bulk of functionality from the full ATL version. The COM implementation that ships with most builds of Windows CE, including all Windows Mobile builds, lacks many of COM's advanced features like apartments, and this simplifies the programming experience for C++ developers using ATL. For the C++ developer with some experience with templates and COM, Smart Device ATL offers a fast track for integrating with a range of Windows CE technologies
Thứ Bảy, 15 tháng 10, 2011 01:16 Đọc tiếp >>

Memory-Mapped Files for Qualcomm Brew

Although today's wireless handsets have far more memory than just a few short years ago, memory remains one of those things where more is simply better. A frequent pattern in application development is to load something into main memory, manipulate it (such as parse or display) it in some way, and then dispose of the memory you used in the first place. Not only is this a hassle, but it can fragment the heap, leading to the inability to allocate large blocks later on. Fortunately, in some cases there's a better way—simply map the desired file to memory using Qualcomm Brew's IFILE_Map API.
Before I show you how to do this, I should tell you the limitations of this API (as of this writing, anyway). First, the interface was introduced in BREW 3.1, so it doesn't exist on older handsets. Secondly, the file must be read-only, and you can read only from the memory mapped region, not write to the region to update the file. Finally, it only works for certain kinds of files: specifically, constant files placed on the handset by the OEM. These restrictions mean that the API is best-suited for developers of embedded Brew applications, such as device manufacturers and their partners.

Mapping a File to Memory with IFILE_Map

When you map a file to memory using IFILE_Map, you're creating a pointer in memory that can be used to read the contents of the file as if it were loaded on the heap. The idea is the same as with the BSD mmap and munmap functions, but given the limitations of the BREW platform, it's understandably less flexible.
The actual process to use IFILE_Map is quite simple:
  1. Create your desired data file and embed it in the handset's production environment as a constant (read-only) file.
  2. In your application, open the file using an instance of IFILEMGR_OpenFile, passing the _OFM_READ flag to indicate read-only access to the file.
  3. Determine the part (perhaps all) of the file you'd like to map into a memory region, obtaining the size of the file as a guideline using IFILE_GetInfo.
  4. Invoke IFILE_Map to obtain a pointer to the file's contents.
  5. Read from the pointer in the normal way (say, pass it to a parser to parse what's needed from the file).
  6. When you're done, close the file using IFILE_Release.
How you do Step 1 is documented in the documentation that Qualcomm provides OEMs, so take a closer look at Steps 2–6. Here's some pseudocode that illustrates what you need to do:
{
IFileMgr *pifm;
ISHELL_CreateInstance( pMe->m_pIShell, AEECLSID_FILEMGR,
(void **)&pifm );
if ( pifm )
{
IFile *pif = IFILEMGR_OpenFile(
pifm, THE_FILE_NAME, _OFM_READ );
if ( pif )
{
FileInfo fi = { 0 };
int err;
char *p;
IFILE_GetInfo( pif, &fi );
p = IFILE_Map( pif,
NULL,
fi.dwSize,
AEE_FMAP_PROT_READ,
AEE_FMAP_SHARED,
0 );

if ( p )
{
// Do stuff with the contents.
Parse( pMe, p );
}
else
{
// Handle the error
}
IFILE_Release( pif );
}
IFILEMGR_Release( pifm );
}
}
Opening the file with IFILEMGR is straightforward; so is mapping the file, once you know the arguments. IFILE_Map returns a pointer to the mapped region in memory, given:
  1. A pointer to an open file.
  2. The starting point in memory at which to map the file, which should be NULL.
  3. The number of bytes to map from the file starting at the current seek position for the file.
  4. How the file should be mapped (read-only, writable, or executable). At present, only AEE_FMAP_PROT_READ is supported.
  5. Indicates how shared memory should be handled. The region can be shared between callers using the AEE_FMAP_SHARED flag.
  6. The offset from the start of the file.

Why Memory Map Files?

There are two reasons to map files into memory. I've already hinted at the first: Mapping files into memory can reduce the amount of memory your application consumes, and potentially reduce heap fragmentation as well. It can also lead to clearer code, by eliminating the need to write record-handling and record-parsing code that reads and parses chunks of your data file. Although the first reason may be less important in today's world of handsets with multiple megabytes of heap, the second reason remains important no matter how much memory the device has.
Areas of your application where mapping files to memory may help include:
  • Dynamic user interfaces, in which the look and feel of your application (including widget placement) is specified indirectly through configuration files at run-time.
  • Parsing of large files in XML or other formats (potentially for the aforementioned purpose), eliminating the need to construct a parser that can handle tags split across read buffer boundaries.
  • Managing read-only data in non-serialized forms (in other words, direct memory dumps) from disk files.
Note that I don't claim that memory mapping files really helps for managing application resources. That's because Brew has a good resource manager through the shell, and the tools in the SDK lets you efficiently manage your application resources using an XML file to describe image resources and specify text resources. Using separate resource files for different languages and the existing ISHELL_LoadResImage and ISHELL_LoadResString interfaces leads to an application that can be easily localized for a particular region, whereas mapping images to save the RAM they might occupy would result in littering the filesystem with images or the need to write a facility similar to Brew's resource management tools in the first place.
One other area of dubious applicability I should mention is media: The Brew IMedia interface can read from both memory and files on the file system, so there's little need to map a media file on the file system to a memory region and invoke the IMedia interfaces using the resulting mapped region.

Conclusion

Mapping files to memory is a valuable trick to reduce memory use, prevent heap fragmentation, and simplify some kinds of large-file handling code. You can use IFILE_Map to do this for read-only files compiled on to the BREW file system at handset manufacturing time, a valuable trick for handset manufacturers.
Thứ Bảy, 15 tháng 10, 2011 01:15 Đọc tiếp >>

Touchscreen Support in Qualcomm Brew

Although the Apple iPhone was not the first touchscreen cell phone on the market (think back to Windows Mobile and Treo devices), it's certainly caused quite a fuss for carriers and manufacturers, all of whom have been in quite a rush to launch their own touchscreen devices. Many of these devices run Qualcomm Brew, and it's perhaps not surprising that Brew has had support for touchscreens for a long time—since BREW 2.x, in fact. In this article, I show you how to receive touchscreen events so you can add touchscreen support to your own applications. Everything I describe works in the simulator, so you can do your development normally, test in the simulator, and as you receive hardware for testing, be ready to deploy your application.

The IControl Interface and Touchscreen Events

The good news is that if you're one of the relatively few developers who are happy using Brew's IControl interface hierarchy, you get touchscreen support essentially for free. Text controls and menus accept touch input, so all you need to do is handle control selection by touch.
To make sure your IControl-based application is ready for touch support, you need to do two things:
  1. Ensure your application passes touch events to the controls.
  2. Be sure that when the user touches outside a control and on another control that you transfer focus to the touched control.
The first is relatively easy: Just be sure you pass all events to the underlying active control using ICONTROL_HandleEvent. Generally, it's best to do this at the beginning of your event handler, like this:
static boolean HandleEvent( CApp *pMe, AEEEvent ec, uint16 w,
uint32 dw ) { boolean result = FALSE;

if ( pMe->pIActiveCtl ) {
result = ICONTROL_HandleEvent( pMe->pIActiveCtl, ec, w, dw );
}

if ( !result ) switch( ec ) {
// Handle event cases here.
}
return result;
}
The second is easy, too, as long as you can do hit testing to determine where the user touched the screen. Once you do this—the subject of the next section—you should defocus the current control and give focus to the new control, doing something like this:
if ( pMe->pIActiveCtl ) {
ICONTROL_SetActive( pMe->pIActiveCtl, FALSE );
}
ICONTROL_SetActive( pINewFocusedCtl, TRUE );
pMe->pIActiveCtl = pINewFocusedCtl;

Accepting touchscreen Events

Under the hood, BREW defines the following events for touchscreens:
  • EVT_PEN_DOWN when the user touches the display
  • EVT_PEN_MOVE while the user moves along the display while touching the display
  • EVT_PEN_UP when the user stops touching the display
  • EVT_PEN_STALE_MOVE if the user has moved along the display while touching the display and there are newer EVT_PEN_MOVE events in the queue
Thus, the general sequence of events when the user touches the display is one of EVT_PEN_DOWN, EVT_PEN_UP (for quick taps) or EVT_PEN_DOWN, a series of EVT_PEN_MOVE (perhaps with one or more EVT_PEN_STALE_MOVE events). The coordinates (x and y) of the event are delivered to you as a set of packed integers in the uint32 that accompanies the event; you can get just the x- or y-coordinate from the packed integer using the BREW helper functions AEE_GET_X and AEE_GET_Y.
Consequently, hit-testing—detecting which item is touched—in your event handler is easy, especially if you keep a list of objects that can be touched by the user. This is especially important if your application is a game or another application that doesn't use the BREW IControl hierarchy of controls. The basic algorithm is:
// On EVT_PEN_UP
int x0 = AEE_GET_X( dw );
int y0 = AEE_GET_Y( dw );
while( there are more objects in the list ) {
int x = current object in list's x coordinate
int y = current object in list's y coordinate
int dx = current object in list's width
int dy = current object in list's height
if ( x0 > x && x0 < x + dx && y0 > y && y0 < y + dy ) {
// the current object is one hit by the touch event
// focus it, activate it, or what have you.
}
You want to do the hit testing on the EVT_PEN_UP event, not the EVT_PEN_DOWN event, because it gives the user a chance to cancel a selection by touching something, moving away from the item they touched while still touching the screen, and then releasing the screen. This is analogous to how buttons work in a desktop user interface: Try clicking down on the OK button of a dialog and then dragging the mouse away from the button; when you release the mouse, the OK action is only taken if the pointer is over the screen.
Handling EVT_PEN_MOVE is a different story; if you want to implement dragging, you must be prepared to do whatever additional work on each EVT_PEN_MOVE event that's required. Whatever work your application performs here should take as little time as possible because your application can receive a lot of EVT_PEN_MOVE events.

A Bit of Advice...

When implementing touch support, you should remember that touch positions are approximate. This doesn't so much reflect inaccuracies in the hardware as it reflects the inability of a user to precisely position their fingertip or a pen tip on exactly one spot of the screen. The user may be in motion (walking, riding a bus, or heaven forbid, driving), and both pointer and device will be in lateral motion, effectively adding noise to the input your application is trying to obtain.
To work with this, make your hit areas large. Some carriers may mandate hit area size on some phones, especially given the small dot pitch of today's screens. It's nearly impossible to hit a 16x16 rectangle when that's only two-tenths of an inch on a side! Controls should be properly sized—a line of text may not be tall enough to be a single control, so consider using the extra screen real estate these devices have to provide big fat touchable areas for your users. Some carriers may mandate a minimum hit size (probably around forty pixels on a side, but you should check with your carrier partners!) for specific devices, and you may fail carrier certification if you don't meet those requirements. This is especially true for devices directly competing with the iPhone, where users are expected to use their finger, not a stylus, to touch the display.

Conclusion

Adding touch support to your application isn't hard, especially if you're already leveraging Brew's IControl hierarchy of interfaces. Just be sure to send the pen events to the active control, and add hit testing to your application to determine which control should be activated. If you've created your own controls, it's a little more work: Be prepared to handle the trio of EVT_PEN_DOWN, EVT_PEN_MOVE, and EVT_PEN_UP events; most of your work is likely in handling EVT_PEN_UP, because that's what confirms what your user wants to do. Regardless, it's not difficult to be ready for the wave of touchscreen phones coming to market!
Thứ Bảy, 15 tháng 10, 2011 01:14 Đọc tiếp >>