Windows Mobile v.5.0 New Features for Developers Larry Lieberman Program Manager Mobile & Embedded Devices Microsoft Corporation Agenda What is Windows Mobile version 5.0? What is new for developers? What is the new developer toolset? Windows Mobile 5.0 Focus Increased productivity Integrated multimedia More opportunities for differentiation Windows Mobile 5.0 Devices HTC Universal Samsung Flextronics Developer Focus Increased developer productivity Multimedia support for applications Opportunities for application developer differentiation Powerful developer tools & new Emulator! Unified Installer State & Notification Broker Improved Emulators Camera & Picture API DirectDraw, DirectShow, D3D Media Player 10 OCX Integrated CF 1v3 Exposed Core Functionality Managed WM APIs Mobile DirectX Native port from Windows DirectX API Fast API ramp-up Large existing support base .NET CF v2 subset of managed D3D, use: Microsoft.WindowsMobile.DirectX.Direct3D Fast and easy 3D development with no plumbing Requires Windows Mobile v5 Samples in Windows Mobile 5 SDK & in Visual Studio documentation. Most run in the emulator Mobile DirectX support is required in Windows Mobile 5 hardware OutlookSession Properties return appropriate folder value OutlookSession os = new OutlookSession(); Folder contactFolder = os.Contacts; Folders and Collections Items properties return appropriate PimItemCollection OutlookSession os = new OutlookSession(); int contactCount = os.Contacts.Items.Count; Appointments, Contacts, & Tasks OutlookSession os = new OutlookSession(); Contact c = new Contact(); c.FullName = “Larry Lieberman”; o.Contacts.Items.Add(c); c.JobTitle = “Program Manager”; c.Update(); Appointments & Tasks: Recurrence t = (Task)this.comboBox1.SelectedItem; label2.Text = Convert.ToString(t.IsRecurring); if (t.IsRecurring) { label4.Text = Convert.ToString(t.RecurrencePattern.RecurrenceType); } Custom PIM Properties Contact myCustomer; // ... if(!myCustomer.Properties.Contains(“Employee ID”)) { myCustomer.Properties.Add("Employee ID",typeof(string)); } myCustomer.Properties["Employee ID"] = "ABC1234"; NOTE: will not sync with Exchange accounts Initiate Calls with Phone.Talk Dim phone As New Phone phone.Talk(“425-555-0101”,False) Sending E-mail & SMS SmsMessage msg; msg.To.Add(new Recipient(“5555309")); msg.Body = “Hello World!"; msg.Send(); Contacts Are Not Recipients Contact myCustomer; // ... EmailMessage msg = new EmailMessage(); msg.To.Add(myCustomer); // This won’t compile! msg.To.Add(new Recipient(myCustomer.Email2Address)); Attach Files to E-mail Messages OutlookSession os = new OutlookSession(); EmailMessage msg = new EmailMessage(); Attachment at = new Attachment(“\Stuff.doc"); msg.Attachments.Add(at); Leverage Outlook Mobile “cards” Appointment appt = new Appointment(); appt.Subject = "Launch Windows Mobile 5.0!"; appt.AllDayEvent = true; appt.Start = new DateTime(2005, 5, 10); outlook.Appointments.Items.Add(appt); appt.ShowDialog(); ChooseContact Dialog ChooseContactDialog cChooser = new ChooseContactDialog(); If (cChooser.ShowDialog() == DialogResult.OK) { // Specify what happens on a // successful return here } SelectPicture Dialog SelectPictureDialog pChooser = new SelectPictureDialog(); If (pChooser.ShowDialog() == DialogResult.OK) { // Specify what happens on a // successful return here } CameraCapture Dialog CameraCaptureDialog cam = new CameraCaptureDialog(); If (cam.ShowDialog() == DialogResult.OK) { // Specify what happens on a // successful return here } Managed Configuration Manager Accepts any standard DMProcessConfig XML for any CSP XmlDocument configDoc = new XmlDocument(); configDoc.LoadXml( "<wap-provisioningdoc>"+ "<characteristic type=\"BrowserFavorite\">"+ "<characteristic type=\"Microsoft\">"+ "<parm name=\"URL\" value=\"http://www.microsoft.com\"/>"+ "</characteristic>"+ "</characteristic>"+ "</wap-provisioningdoc>" ); ConfigurationManager.ProcessConfiguration(configDoc, false); Control the Messaging Application Initiate synchronization Display the inbox Display the compose form public static void DisplayComposeForm( string accountName, string toAddresses, string ccAddresses, string bccAddresses, string subject, string body, string[] attachments ); Intercept SMS Messages in Native Code //====================================================================== // MonitorThread - Monitors event for timer notification // DWORD WINAPI MonitorThread (PVOID pArg) { TEXT_PROVIDER_SPECIFIC_DATA tpsd; SMS_HANDLE smshHandle = (SMS_HANDLE)pArg; PMYMSG_STRUCT pNextMsg; BYTE bBuffer[MAXMESSAGELEN]; PBYTE pIn; SYSTEMTIME st; HANDLE hWait[2]; HRESULT hr; int rc; DWORD dwInSize, dwSize, dwRead = 0; hWait[0] = g_hReadEvent; hWait[1] = g_hQuitEvent; if (hr == ERROR_SUCCESS) { // Convert GMT message time to local time FILETIME ft, ftLocal; SystemTimeToFileTime (&st, &ft); FileTimeToLocalFileTime (&ft, &ftLocal); FileTimeToSystemTime (&ftLocal, &pNextMsg>stMsg); // If using alt buffer, copy to std buff if ((DWORD)pIn == (DWORD)pNextMsg>wcMessage) { pNextMsg->nSize = (int) dwRead; } else { memset (pNextMsg->wcMessage, 0, sizeof(pNextMsg->wcMessage)); memcpy (pNextMsg->wcMessage, pIn, sizeof(pNextMsg->wcMessage)-2); pNextMsg->nSize = sizeof(pNextMsg>wcMessage); } // Increment message count if (g_pMsgDB->nMsgCnt < MAX_MSGS-1) { if (g_hMain) PostMessage (g_hMain, MYMSG_TELLNOTIFY, 1, g_pMsgDB->nMsgCnt); g_pMsgDB->nMsgCnt++; } } else { ErrorBox (g_hMain, TEXT("Error %x (%d) reading msg"), hr, GetLastError()); break; } // Need two events since it isn't // allowed for us to signal SMS event. while (g_fContinue) { rc = WaitForMultipleObjects (2, hWait, FALSE, INFINITE); if (!g_fContinue || (rc != WAIT_OBJECT_0)) break; // Point to the next free entry in the array pNextMsg = &g_pMsgDB->pMsgs[g_pMsgDB->nMsgCnt]; // Get the message size hr = SmsGetMessageSize (smshHandle, &dwSize); if (hr != ERROR_SUCCESS) continue; // Check for message larger than std buffer if (dwSize > sizeof (pNextMsg->wcMessage)) { if (dwSize > MAXMESSAGELEN) continue; pIn = bBuffer; dwInSize = MAXMESSAGELEN; } else { pIn = (PBYTE)pNextMsg->wcMessage; dwInSize = sizeof (pNextMsg->wcMessage); } // Set up provider specific data tpsd.dwMessageOptions = PS_MESSAGE_OPTION_NONE; tpsd.psMessageClass = PS_MESSAGE_CLASS0; tpsd.psReplaceOption = PSRO_NONE; tpsd.dwHeaderDataSize = 0; // Read the message hr = SmsReadMessage (smshHandle, NULL, &pNextMsg->smsAddr, &st, (PBYTE)pIn, dwInSize, (PBYTE)&tpsd, sizeof(TEXT_PROVIDER_SPECIFIC_DATA), &dwRead); } } SmsClose (smshHandle); return 0; Intercept SMS Messages in Managed Code MessageInterceptor sms; void Form_Load( ... ) { sms = new MessageInterceptor(); //... Optional: set interception condition here sms.MessageReceived += new EventHandler(sms_MessageReceived); } void sms_MessageReceived(...) { //... Handle incoming message } Create Smart Mobile Apps with the State & Notification Broker Gathering state information previously was difficult Problems: Different APIs for querying different properties Different change notification mechanisms for different properties Many properties not exposed (especially in .NET CF) No standard way for OEMs and developers to expose their own properties State & Notification Broker Strategy Placement of useful information in documented locations Native APIs to get notified of changes to any registry value Managed wrapper around native APIs State & Notification Broker Architecture Microsoft.WindowsMobile.Status RegExt.h SNAPI.h Interesting Values Registry There Are Over 100 System Properties Power & Battery Appointments Media Player Connectivity ActiveSync Messaging Telephony Hardware Tasks Shell Two Ways to Query for Current Values 1. Dynamic SystemState callerId = new SystemState( SystemProperty.PhoneIncomingCallerContact); Contact c = (Contact)callerId.CurrentValue; 2. Static Contact c = SystemState.PhoneIncomingCallerContact; Get Change Notifications 1. 2. Create a SystemState object Attach an event handler SystemState callerId = new SystemState( SystemProperty.PhoneIncomingCallerContact); callerId.Changed += new ChangeEventHandler(callerId_Changed); void callerId_Changed(object sender, ChangeEventArgs args) { // ... } NEW: Volatile Registry Keys Problem: IM client publishes a “number of online contacts” value in the registry. User logs in and this gets set to 15. Device is reset so user is no longer logged in. Value in the registry (15) is no longer accurate. Solution: Volatile registry keys Just like regular registry keys except they die when the device turns off Better performance Always in RAM Never flushed to persistent storage Extensibility! Publish your own state Get notified of changes to any registry value public class MyClass { RegistryState state; // defined globally to class private void Form1_Load(object sender, EventArgs e) { // RegistryState state; // This instance will go out of scope if defined here! RegistryState state = new RegistryState("HKEY_LOCAL_MACHINE\\MyKey", "MyValue"); state.Changed += new ChangeEventHandler(state_Changed); } } Get Notified While Your Application Is Not Running Can be used for SMS interception State & notification broker When a change occurs Windows Mobile launches the application Application hooks up an event hander Event is fired Get Notified While Your Application Is Not Running (cont’d) SystemState missedCall; void Form_Load( … ) { // if(!SystemState.IsApplicationLauncherEnabled(“MyApp.MissedCall”)) TODO: Initialize missedCall { // ... Initialize missedCall missedCall.EnableApplicationLauncher( “MyApp.MissedCall” ); } else { SystemState missedCall = new SystemState(“MyApp.MissedCall”); } missedCall.Changed += new EventHandler( missedCall_Changed ); } Persisted Notifications MyApp.LostPhoneSMS AnotherApp.IncommingCall AnotherApp.LowBattery MyApp.MissedCall … Conditions Prevent Unnecessary Notifications SystemState missedCall; void Form_Load( … ) { if(!SystemState.IsApplicationLauncherEnabled(“MyApp.MissedCall”)) { // ... Initialize missedCall missedCall.EnableApplicationLauncher( “MyApp.MissedCall” ); } else { SystemState missedCall = new SystemState(“MyApp.MissedCall”); missedCall.ComparisonType = StatusComparisonType.Equal; missedCall.ComparisonValue = true; } missedCall.Changed += new EventHandler( missedCall_Changed ); } New Tool Chain Integrated, uniform toolset for native & managed development Improved user interface designers Improved data design tools Multiplatform development Improved debugger New ARM device emulator engine New device CAB project type Call to Action Install Visual Studio 2005 Install Windows Mobile 5.0 SDKs Start developing for mobile devices today! © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.