Mobile SDK for Windows Apps2.0
Transforming Windows apps into Mobile apps
native/capturepicture/capturepicture.cpp
// C++ Capture picture example using Citrix Mobility Pack SDK
//
// Uses Citrix Mobility Pack SDK to take a picture.
//
// Copyright (c) 2013 Citrix Systems
//


#include <stdio.h>
#include <windows.h>
#include <fstream>
#include <tchar.h>

// Citrix Mobility Pack include files
#include <cmp.h>

// Local functions
void ReportStatus(LPCSTR text, CMPRESULT rc);
CMPRESULT RegisterForEvent(HANDLE hCMP);
CMPRESULT CapturePicture(HANDLE hCMP, const CMP_CAPTURE_PICTURE_OPTIONS *options, CMP_UNIQUE_LONG_ID *uniqueId);
void CMPCALL CapturedPicture(HANDLE hCMP, CMPRESULT result, CMP_UNIQUE_LONG_ID uniqueId, UTF8_STRING pictureMetadata, UTF8_STRING filename, UTF8_STRING thumbnail, UINT32 pictureSize, const CMP_CAPTURE_PICTURE_OPTIONS *options);
CMPRESULT RemoveCapturedData(HANDLE hCMP, CMP_UNIQUE_LONG_ID uniqueId);
void LoadFileLocally(UTF8_STRING clientFilename);

// Local structure
struct PICTURE_DATA
{
    CMPRESULT result;
    CMP_UNIQUE_LONG_ID uniqueId;
    UTF8_STRING pictureMetadata;
    UTF8_STRING filename;
    UTF8_STRING thumbnail;
    UINT32 pictureSize;
    const CMP_CAPTURE_PICTURE_OPTIONS *options;
};

// local variables
HANDLE hCaptureEvent = NULL; // local picture event
PICTURE_DATA g_PictureData = { CMP_NO_ERROR, 0, NULL, NULL, NULL, 0, NULL }; // event data
CMP_UNIQUE_LONG_ID uniqueId;

int __cdecl main(int argc, char **argv)
{
    CMPRESULT rc;
    DWORD winrc;

    // create an event that is not manual reset with initial state set to non-signaled
    hCaptureEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    // initialize Citrix Mobility Pack for MultiThreadApartment(TRUE)
    rc = CMPInitialize(TRUE);

    ReportStatus("CMPInitialize", rc);

    if(CMP_SUCCESS(rc))
    {
        HANDLE hCMP;

        // open the Citrix Mobility Pack handle
        rc = CMPOpen(&hCMP);

        // report if failure
        ReportStatus("CMPOpen", rc);

        if(CMP_SUCCESS(rc))
        {
            // establish a connection between XenApp and Receiver (virtual channel)
            rc = CMPOpenSession(hCMP);

            // report if failure
            ReportStatus("CMPOpenSession", rc);

            if(CMP_SUCCESS(rc))
            {
                // register for the picture capture event
                rc = RegisterForEvent(hCMP);

                if(CMP_SUCCESS(rc))
                {
                    CMP_CAPTURE_PICTURE_OPTIONS options;
                    memset(&options, 0, sizeof(CMP_CAPTURE_PICTURE_OPTIONS));
                    
                    options.Quality = CMP_CAPTURE_QUALITY_MEDIUM; //Picture quality (low, medium, high, maximum, or default)
                    options.CameraSelection = CMP_CAPTURE_CAMERA_DEFAULT; //Camera selection (front, back or default)
                    options.Encoding = CMP_IMAGE_FORMAT_JPEG; //Encoding of data (JPEG, PNG)
                    options.DesiredWidth = 1024; //Desired pixel width (0 = no desired width)
                    options.DesiredHeight = 768; //Desired pixel height (0 = no desired height)
                    options.ThumbnailType = CMP_THUMBNAIL_CUSTOM; //Type of thumbnail included (SMALL, MEDIUM, LARGE, CUSTOM or NONE)
                    options.ThumbnailHeight = 256; //If CMP_THUMBNAIL_TYPE is CUSTOM, this is the desired width
                    options.ThumbnailWidth = 192; //If CMP_THUMBNAIL_TYPE is CUSTOM, this is the desired height

                    //Request that a picture be taken with the above options
                    rc = CapturePicture(hCMP, &options, &uniqueId);

                    if(CMP_SUCCESS(rc))
                    {
                        DWORD waitTime = 60000;
                        printf("Waiting for the picture to be taken within the next 60 seconds.\n");

                        while(waitTime > 0)
                        {
                            winrc = WaitForSingleObject(hCaptureEvent, 1000); //Wait for one second for the picture to be captured

                            if(winrc == WAIT_OBJECT_0)
                            {
                                // Capture event caught within the time limit.
                                
                                // only process picture if it is one of ours
                                if(uniqueId == g_PictureData.uniqueId)
                                {
                                    if(CMP_SUCCESS(g_PictureData.result))
                                    {
                                        //Show the capture data
                                        printf("CapturePicture success\nresult(0x%X)\nid(0x%I64X)\nmetadata(%s)\nfilename(%s)\nthumbnail(%s)\npictureSize(%u)\n",
                                            g_PictureData.result, g_PictureData.uniqueId, g_PictureData.pictureMetadata, g_PictureData.filename, g_PictureData.thumbnail, g_PictureData.pictureSize);

                                    } else {
                                        //User cancelled the capture
                                        ReportStatus("CapturePicture event", g_PictureData.result);
                                    }

                                    break;
                                }
                            }
                            else
                            {
                                waitTime -= 1000;
                                printf("Waiting for capture... (%u)\n", waitTime/1000);
                            }
                        }
                    }
                }

                printf("\nCapture complete! Closing in 10 seconds...\n");
                Sleep(10000);

                rc = CMPCloseSession(hCMP); 

                ReportStatus("CMPCloseSession", rc);

            }
        }

        rc = CMPClose(hCMP); 

        ReportStatus("CMPClose", rc);

        rc = CMPUninitialize(); 

        ReportStatus("CMPUninitialize", rc);
    }

}

void ReportStatus(LPCSTR text, CMPRESULT rc)
{
    if(CMP_FAILURE(rc))
    {
        printf("%s CMPResult(%08X)\n", text, rc);
        switch (rc) {
            case CMP_ERROR_CLIENT_DRIVE_UNAVAILABLE: printf("Client Drive unavailable. Check session options on Receiver.\n"); break;
            case CMP_ERROR_CAPABILITY_NOT_SUPPORTED: printf("This device does not support picture capture.\n"); break;
            case CMP_ERROR_CAPTURE_CANCEL: printf("Capture was cancelled by user.\n"); break;
        }
    }

    return;
}

// <summary>
// PictureCaptured event handler.
// </summary>
// <param name="hCMP">CMP handler.</param>
// <param name="result">Capture result.</param>
// <param name="uniqueId">Capture identifier.</param>
// <param name="pictureMetadata">Capture metadata.</param>
// <param name="filename">Capture filename.</param>
// <param name="thumbnail">Thumbnail filename.</param>
// <param name="pictureSize">Size of capture.</param>
// <param name="options">Capture options.</param>
void CMPCALL CapturedPicture(
    HANDLE hCMP, 
    CMPRESULT result, 
    CMP_UNIQUE_LONG_ID uniqueId,
    UTF8_STRING pictureMetadata,
    UTF8_STRING filename,
    UTF8_STRING thumbnail,
    UINT32 pictureSize,
    const CMP_CAPTURE_PICTURE_OPTIONS *options)
{
    printf("PictureCaptured event\n");

    memset(&g_PictureData, 0, sizeof(PICTURE_DATA));

    // Copy the relevant data and then signal the event
    g_PictureData.result = result;
    g_PictureData.uniqueId = uniqueId;

    if (CMP_SUCCESS(result)){
        g_PictureData.pictureSize = pictureSize;
        g_PictureData.options = options;
        if (pictureMetadata)
            g_PictureData.pictureMetadata = _strdup(pictureMetadata);
        if (thumbnail)
            g_PictureData.thumbnail = _strdup(thumbnail);
        if (filename) {
            g_PictureData.filename = _strdup(filename);
            LoadFileLocally(g_PictureData.filename);
        }
    }

    SetEvent(hCaptureEvent);
}


CMPRESULT RegisterForEvent(HANDLE hCMP)
{
    CMPRESULT rc;

    // Subscribe to PictureCaptured event.
    rc = CMPRegisterForEvent(hCMP, CMP_EVENT_PICTURE_CAPTURED, (CMP_EVENT_CALLBACK)CapturedPicture);

    // report if failure
    ReportStatus("CMPRegisterForEvent", rc);

    return(rc);
}

CMPRESULT CapturePicture(HANDLE hCMP, const CMP_CAPTURE_PICTURE_OPTIONS *options, CMP_UNIQUE_LONG_ID *uniqueId)
{
    CMPRESULT rc;

    // Request that a picture be taken.
    rc = CMPCapturePicture(hCMP, options, uniqueId);

    // report if failure
    ReportStatus("CMPCapturePicture", rc);

    return(rc);
}

CMPRESULT RemoveCapturedData(HANDLE hCMP, CMP_UNIQUE_LONG_ID uniqueId)
{
    CMPRESULT rc;

    // Request the picture be removed.
    rc = CMPRemoveCapturedData(hCMP, uniqueId);

    ReportStatus("CMPRemoveCapturedData", rc);

    return(rc);
}

// <param name="clientFilename">Client capture filename.</param>
void LoadFileLocally (UTF8_STRING clientFilename)
{
    TCHAR tempPath[MAX_PATH];

    GetTempPath(MAX_PATH, tempPath);

    char filename [MAX_PATH];
    char ext [5];

    _splitpath_s(clientFilename, NULL, 0 , NULL, 0, filename, MAX_PATH, ext, 5);

    _tcscat_s(tempPath, filename); 
    _tcscat_s(tempPath, ext); 

    CopyFile(clientFilename, tempPath, false);
    ShellExecute(NULL, NULL, tempPath, NULL, NULL, SW_SHOW );
}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Events Defines