New Managed Messaging, State, And Notification APIs In Windows Mobile 2005 Gaurav Khanna Developer Evangelist Microsoft India
M anagement T ools C ommunications & M essaging Device Update Agent Software Update Services Live Communications Server Exchange Server Internet Security and Acceleration Server Speech Server Image Update L ocation S ervices M ultimedia MapPoint DirectX Windows Media Visual Studio 2005 D evelopment T ools MFC 8.0, ATL 8.0 Win32 N ative M anaged S erver S ide L ightweight R elational SQL Server 2005 Express EditionEDB D ata P rogramming M odel D evice B uilding T ools D evice B uilding T ools H ardware/ D rivers Windows XP DDK Windows Embedded Studio Platform Builder OEM/IHV Supplied BSP (ARM, SH4, MIPS) OEM Hardware and Standard Drivers Standard PC Hardware and Drivers SQL Server 2005SQL Server 2005 Mobile Edition ASP.NET Mobile ControlsASP.NET.NET Compact Framework.NET Framework Microsoft Operations Manager Systems Management Server
Here’s What We’ll Cover Lots of Brand New Managed APIs Only for Windows Mobile 5.0.NET Compact Framework 1.0 or 2.0 CapabilitiesUsage Common mistakes Lots of code snippets
Initiate Calls With Phone.Talk Get properties and events through the State & Notification Broker Dim phone As New Phone phone.Talk( “ ” )
Let’s Talk
Microsoft.WindowsMobile Namespace Summary WindowsMobile.PocketOutlook Edit Contacts, Appointments, and Tasks Control the Messaging application Send SMS & messages Intercept incoming SMS messages WindowsMobile.Status Query 100+ system properties Get notified of changes WindowsMobile.Configuration Configuration Manager WindowsMobile.Telephony Initiate phone calls WindowsMobile.Forms Contact Picker Dialog Picture Picker Dialog Camera Capture Dialog
Integrating With Outlook Mobile
It All Starts At OutlookSession OutlookSession outlook = new OutlookSession(); int contactCount = outlook.Contacts.Items.Count;
Folders And Collections One folder per type Each has a collection Enumerate items Check capabilities Sort & Filter Add & Remove ListChanged event
Appointments, Contacts, And Tasks Lots of properties and events Don’t forget Update() OutlookSession outlook = new OutlookSession(); Contact me = new Contact(); me.FullName = “Gaurav”; outlook.Contacts.Items.Add( me ); // <-- Saved me.JobTitle = “DE”; me.Update(); // <-- Saved
Managed POOM: Working with Contacts
Appointment And Task Can Be Recurring Recurrence Type Properties to Use Example DailyInterval Every 4 days Weekly Interval DaysOfWeekMask Every Monday and Tuesday Monthly Interval DayOfMonth Every 3 months MonthlyByNumber Interval DaysOfWeekMask Instance Second Friday of each month Yearly DayOfMonth MonthOfYear May 10 th of each year YearlyByNumber DaysOfWeekMask Instance MonthOfYear Second Tuesday in May of each year (All) PatternStartDate PatternEndDate NoEndDate
Items Can Be Shown In Outlook Mobile With ShowDialog 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();
Add Your Own Properties To PIM Items Contact myCustomer; //... if(!myCustomer.Properties.Contains(“Employee ID”)) { myCustomer.Properties.Add("Employee ID", typeof(string)); } myCustomer.Properties["Employee ID"] = "ABC1234"; 1. See if the property has been defined 2. If not, define it 3. Use it
Working With Item IDs string idString; // … Read idString from a file, registry, or database int idNumber = Int32.Parse( idString ); ItemID id = new ItemID( idNumber ); Contact c = new Contact( id ); Store references to items by their ID Retrieve items by their ID Contact c; // … string idString = c.ItemID.ToString();
Sending And SMS SmsMessage msg = new SmsMessage(); msg.To.Add( new Recipient(“ ")); msg.Body = “Hello World!"; msg.Send();
Contacts Are Not Recipients Contact myCustomer; //... Message msg = new Message(); msg.To.Add( myCustomer ); // Won’t compile! msg.To.Add( new Recipient( myCustomer. 2Address ) ); // OK
Managed POOM: Working with Messaging
Control The Messaging Application Display the compose form Display the inbox Initiate synchronization
Create rich mobile apps by intercepting SMS messages
Intercept SMS Messages In Managed Code MessageInterceptor sms; void Form_Load(... ) { sms = new MessageInterceptor(); //... Set optional properties here sms.MessageReceived += new EventHandler(sms_MessageReceived); } void sms_MessageReceived(...) { //... Handle incoming message }
Specify What Happens to Intercepted Messages MessageInterceptor sms; void Form_Load(... ) { sms = new MessageInterceptor(); sms.InterceptionAction = InterceptionAction.NotifyAndDelete; sms.MessageReceived += new EventHandler(sms_MessageReceived); } void sms_MessageReceived(...) { //... Handle incoming message }
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; // Need two events since it isn't hWait[1] = g_hQuitEvent; // 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); 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; } SmsClose (smshHandle); return 0; }
Making use of SMS interception
Create smart mobile apps with the State & Notification Broker
Why Is This So Hard? 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 ISVs to expose their own properties
State And Notification Broker Strategy 1. Placement of useful information in documented registry locations 2. Native APIs to get notified of changes to any registry value 3. Managed wrapper around native APIs
State And Notification Broker Design Registry Interesting Values SNAPI.hRegExt.h Microsoft.WindowsMobile.Status
There Are Over 100 System Properties Power & Battery Appointments Media Player ConnectivityActiveSyncMessagingTelephonyHardwareTasksShell
Get Change Notifications 1. Create a SystemState object 2. Attach an event handler SystemState callerId = new SystemState( SystemProperty.PhoneIncomingCallerContact); callerId.Changed += new EventHandler(callerId_Changed); void callerId_Changed(object sender, ChangeEventArgs e) { Contact caller = (Contact)callerId.CurrentValue; //... }
Two Ways To Query For Current Values 1. Static Strongly typed, quick and easy 2. Dynamic Contact c = SystemState.PhoneIncomingCallerContact; SystemState.PhoneIncomingCallerContact; SystemState callerId = new SystemState( SystemProperty.PhoneIncomingCallerContact); SystemProperty.PhoneIncomingCallerContact); Contact c = (Contact)callerId.CurrentValue;
The State And Notification Broker Is Extensible Publish your own state Get notified of changes to any registry value
Get Notified While Your Application Is Not Running Can be used for SMS Interception State and Notification Broker When a change occurs 1. Windows Mobile launches the application 2. Application hooks up an event hander 3. Event is fired
SystemState missedCall; void Form_Load( … ) { if(!SystemState.IsApplicationLauncherEnabled(“MyApp.MissedCall”)) { missedCall = new SystemState( SystemProperty.PhoneMissedCall ); missedCall.EnableApplicationLauncher( “MyApp.MissedCall” ); } else { SystemState missedCall = new SystemState(“MyApp.MissedCall”); } missedCall.Changed += new EventHandler( missedCall_Changed ); } App Launching With The State & Notification Broker
MessageInterceptor sms; void Form_Load( … ) { if(!MessageInterceptor.IsApplicationLauncherEnabled(“MyApp.SMS”)) { sms = new MessageInterceptor(); sms.EnableApplicationLauncher( “MyApp.SMS” ); } else { MessageInterceptor sms = new SystemState(“MyApp.SMS”); } sms.MessageReceived += new EventHandler( sms_MessageReceived ); } App Launching With The SMS Interception
Conditions Prevent Unnecessary Notifications Very important for app-launching notifications! Comparison Types: String Equal, NotEqual, StartsWith, EndsWith, Contains Integer Equal, NotEqual, Greater, GreaterOrEqual, Less, LessOrEqual Binary Not supported
Setting Conditions With The State & Notification Broker SystemState missedCall; void Form_Load( … ) { // … missedCall = new SystemState( SystemProperty.PhoneMissedCall ); missedCall.ComparisonType = StatusComparisonType.Equal; missedCall.ComparisonValue = true; missedCall.Changed += new EventHandler( missedCall_Changed ); }
Other Resources Windows Mobile 5.0 SDK Windows Mobile Team Blog Migration FAQ for Developers us/dnppcgen/html/migration_developers_faq.asp us/dnppcgen/html/migration_developers_faq.aspWinToolZone Insights
Tools & Resources msdn.microsoft.com/ embedded microsoft.public. windowsxp.embedded windowsce.platbuilder windowsce.platbuilder windowsce.embedded.vc windowsce.embedded.vc blogs.msdn.com/ mikehall Windows CE 5.0 Eval Kit Windows XP Embedded Eval Kit msdn.microsoft.com/ mobility microsoft.public. pocketpc.developer smartphone.developer dotnet.framework.compactframework blogs.msdn.com/ windowsmobile vsdteam netcfteam Windows Mobile 5.0 Eval Kit Websites Newsgroups Blogs Tools Build Develop
© 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
Your Feedback is Important! Please Fill Out the feedback form
© 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.