Mobile SDK for Windows Apps2.0
Transforming Windows apps into Mobile apps
winform/takepicture/Form1.cs
// C# Take picture example using COM Interop with Citrix Mobility SDK
//
// Uses Citrix Mobility SDK to take a picture and transfer it to server.
//
// Copyright (c) 2012 Citrix Systems
//

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using CitrixMobility;
using System.IO;

namespace takepicture
{
    public partial class Form1 : Form
    {
        // <summary>
        // Initialise picture ID (unique to this application).
        // </summary>
        private const int pictureId = 0x12344321;

        // <summary>
        // Instance of CitrixMobile.
        // </summary>
        private CitrixMobile cmp = null;

        // <summary>
        // ICA session connected state.
        // </summary>
        private bool icaSessionConnected = false;

        // <summary>
        // Path to top level AppData path for MobilitySDK sample application.
        // e.g. C:\Users\username\AppData\Roaming\Citrix\MobilitySDK\Samples
        // </summary>
        private string appDataPath;

        // <summary>
        // Indicates whether picture processing is in progress.
        // </summary>
        private bool processingPicture = false;

        // <summary>
        // Lock object.
        // </summary>
        private object stateLock = new object();

        // <summary>
        // Check CMP return code for success.
        // </summary>
        public static bool CMP_SUCCESS(int rc)
        {
            // need to mask the result since the top half can have the component Id
            return ((rc & 0xffff) == (int)CMP_ERROR_ID.CMP_NO_ERROR);
        }

        // <summary>
        // Dispatch action to UI thread if necessary.
        // </summary>
        // <param name="action">The action.</param>
        private void UiDispatch(Action action)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(action);
            }
            else
            {
                action();
            }
        }

        // <summary>
        // Report CMP status.
        // </summary>
        // <param name="text">Status text.</param>
        // <param name="rc">CMP return code.</param>
        private void ReportStatus(string text, int rc)
        {
            // Only report status if something went wrong.
            if (!CMP_SUCCESS(rc))
            {
                string msg = string.Format("{0}, CMPResult: 0x{1:X}", text, rc);

                // Write to trace output.
                Helpers.Trace(msg);
                // Update status text.
                UpdateStatus(msg);
            }
        }

        public Form1()
        {
            InitializeComponent();

            // Initialises CMP framework.
            InitialiseCmp();
        }

        // <summary>
        // Initialise CMP framework.
        // </summary>
        private void InitialiseCmp()
        {
            int rc = (int)CMP_ERROR_ID.CMP_NO_ERROR;

            try
            {
                // Initialise application data path.
                appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                                "Citrix", "MobilitySDK", "Samples", "TakePicture");
                if (!Directory.Exists(appDataPath))
                {
                    Directory.CreateDirectory(appDataPath);
                    Helpers.Trace("Created AppData directory: {0}", appDataPath);
                }

                Helpers.Trace("Creating CitrixMobile object");
                // Create an instance of CitrixMobile object.
                cmp = new CitrixMobile();

                Helpers.Trace("Register for ICA session state changed events");
                // Register for ICA session events.
                cmp.SessionStateChanged += new ICMPEvents_SessionStateChangedEventHandler(cmp_SessionStateChanged);

                Helpers.Trace("Calling OpenSession");
                // Open CMP session.
                rc = cmp.OpenSession();

                if (CMP_SUCCESS(rc))
                {
                    icaSessionConnected = true;

                    Helpers.Trace("Register for PictureTaken event");
        // Register for PictureTaken event.
        cmp.PictureTaken += new ICMPEvents_PictureTakenEventHandler(cmp_PictureTaken);
                }
                else
                {
                    string msg = string.Format("OpenSession failed rc={0:X}", rc);
                    UpdateStatus(msg);
                    Helpers.Trace(msg);
                }
            }
            catch (System.Exception ex)
            {
                UpdateStatus(ex.Message);
                Helpers.Trace(ex.Message);
                Helpers.Trace(ex.StackTrace);
            }
        }

        // <summary>
        // Tear down CMP connection when closed.
        // </summary>
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (null != cmp)
            {
                // Close CMP session.
                cmp.CloseSession();
                cmp = null;
            }
        }

        // <summary>
        // Session state change handler.
        // </summary>
        // <remarks>Update the ICA session state upon connect/disconnect.</remarks>
        // <param name="SessState">Session state</param>
        void cmp_SessionStateChanged(CMP_SESSION_STATE SessState)
        {
            switch (SessState)
            {
                case CMP_SESSION_STATE.CMP_SESSION_STATE_CONNECTED:
                    icaSessionConnected = true;
                    break;
                case CMP_SESSION_STATE.CMP_SESSION_STATE_DISCONNECTED:
                    icaSessionConnected = false;
                    break;
                default:
                    break;
            }
        }

        // <summary>
        // Display the specified status text.
        // </summary>
        // <param name="pathToPicture">Status text.</param>
        private void UpdateStatus(string statusText)
        {
            UiDispatch(() => status.Text = statusText);
        }

        // <summary>
        // Display the specified picture file.
        // </summary>
        // <param name="pathToPicture">Path to the picture file.</param>
        private void DisplayPicture(string pathToPicture)
        {
            UiDispatch(() => pictureBox1.Load(pathToPicture));
        }

        private delegate void InvokeDelegate(string pathToPicture);

        // <summary>
        // PictureTaken event handler.
        // </summary>
        // <param name="rc">Return code.</param>
        // <param name="PictureID">Picture identifier associated with this event.</param>
        // <param name="Format">Picture format.</param>
        // <param name="PictureSize">Picture size.</param>
        // <param name="Filename">Picture file name. This is an UNC path corresponding to the client drive mapping
        // where the picture is stored on the device.</param>
        private void cmp_PictureTaken(int rc, int PictureID, CMP_IMAGE_FORMAT Format, int PictureSize, string Filename)
        {
            Helpers.Trace("PictureTaken: rc:{0:X}, PictureID:{1:X}, Format:{2:X}, PictureSize:{3:X}, Filename{4}",
                rc, PictureID, Format, PictureSize, Filename);

            if (CMP_SUCCESS(rc))
            {
                // Only process the picture if it is one of ours.
                if (PictureID == pictureId)
                {
                    try
                    {
                        lock (stateLock)
                        {
                            processingPicture = true;
                        }

                        string pictureFile = "picture.jpg";
                        int pos = Filename.LastIndexOf("\\");
                        if (pos >= 0)
                        {
                            pictureFile = Filename.Substring(pos + 1);
                        }
                        UpdateStatus(string.Format("Picture received: {0}", pictureFile));

                        string pathToPicture = Path.Combine(appDataPath, pictureFile);
                        UpdateStatus(string.Format("Saving picture to: {0}", pathToPicture));

                        // Wait for the source picture file to be ready.
                        int loop = 0;
                        while (!File.Exists(Filename))
                        {
                            UpdateStatus(string.Format("Waiting ({0}) for picture: {1}", ++loop, pathToPicture));
                            System.Threading.Thread.Sleep(1000);
                        }

                        // Copy picture to output directory.
                        File.Copy(Filename, pathToPicture);

                        // Display the picture. Note that this is invoked in the UI thread.
                        DisplayPicture(pathToPicture);
                        UpdateStatus(string.Format("Picture saved: {0}", pathToPicture));

                        lock (stateLock)
                        {
                            processingPicture = false;
                        }
                    }
                    catch (Exception ex)
                    {
                        UpdateStatus(ex.Message);
                        Helpers.Trace(ex.Message);
                        Helpers.Trace(ex.StackTrace);
                    }
                }
            }
        }

        // <summary>
        // Picture box click handler.
        // </summary>
        // <remarks>Initiate picture taking on the device when the button is clicked.</remarks>
        // <param name="sender"></param>
        // <param name="e"></param>
        private void pictureBox1_Click(object sender, EventArgs e)
        {
            if ((null != cmp) && icaSessionConnected && !processingPicture)
            {
                try
                {
                    UpdateStatus("Sending request to take picture");
                    Helpers.Trace("Sending request to take picture");

        // Request a JPEG picture to be taken.
        int rc = cmp.TakePicture(CMP_IMAGE_FORMAT.CMP_IMAGE_FORMAT_JPEG, pictureId);

                    if (CMP_SUCCESS(rc))
                    {
                        UpdateStatus("Take picture request sent successfully");
                        Helpers.Trace("Take picture request sent successfully");
                    }
                    else
                    {
                        string msg = string.Format("Failed to send take picture request: rc:{0:X}", rc);
                        if ((int)CMP_ERROR_ID.CMP_ERROR_CLIENT_DRIVE_UNAVAILABLE == rc)
                        {
                            // Client Drive Mapping not enabled is a common setting and is required
                            // for writing the picture file to the storage of the device, e.g. SD card.
                            msg += Environment.NewLine + "Please ensure Client Drive Mapping is enabled.";
                        }
                        UpdateStatus(msg);
                        Helpers.Trace(msg);
                    }
                }
                catch (Exception ex)
                {
                    UpdateStatus(ex.Message);
                    Helpers.Trace(ex.Message);
                    Helpers.Trace(ex.StackTrace);
                }
            }
        }
    }
}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Events Defines