Commit 88b558be by Neo Turing

init

parents
################################################################################
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
################################################################################
/.vs
/EDSDKLib/Src/bin/Debug
/EDSDKLib/Src/obj/Debug
/Src/bin/Debug
/Src/obj/Debug
using System;
using System.IO;
using System.Threading;
using EOSDigital.SDK;
using FileAccess = EOSDigital.SDK.FileAccess;
using System.Collections.Generic;
using System.Linq;
namespace EOSDigital.API
{
/// <summary>
/// Represents a physical camera and provides methods to control it
/// </summary>
public class Camera : IDisposable
{
#region Events
/// <summary>
/// The SDK object event
/// </summary>
protected event SDKObjectEventHandler SDKObjectEvent;
/// <summary>
/// The SDK progress event
/// </summary>
protected event SDKProgressCallback SDKProgressCallbackEvent;
/// <summary>
/// The SDK property event
/// </summary>
protected event SDKPropertyEventHandler SDKPropertyEvent;
/// <summary>
/// The SDK state event
/// </summary>
protected event SDKStateEventHandler SDKStateEvent;
/// <summary>
/// Fires if any process reports progress
/// </summary>
public event ProgressHandler ProgressChanged;
/// <summary>
/// Fires if the live view image is updated
/// </summary>
public event LiveViewUpdate LiveViewUpdated;
/// <summary>
/// Fires if an image is ready for download.
/// Call the <see cref="DownloadFile(DownloadInfo,string)"/> or <see cref="DownloadFile(DownloadInfo)"/> method to get the image or <see cref="CancelDownload"/> to cancel.
/// </summary>
public event DownloadHandler DownloadReady;
/// <summary>
/// Fires if a property has changed
/// </summary>
public event PropertyChangeHandler PropertyChanged;
/// <summary>
/// Fires if a state has changed
/// </summary>
public event StateChangeHandler StateChanged;
/// <summary>
/// Fires if an object has changed
/// </summary>
public event ObjectChangeHandler ObjectChanged;
/// <summary>
/// This event fires if the camera is disconnected or has shut down
/// </summary>
public event CameraUpdateHandler CameraHasShutdown;
/// <summary>
/// This event fires when the live view loop has ended
/// </summary>
public event CameraUpdateHandler LiveViewStopped;
#endregion
#region Variables
/// <summary>
/// Info about this camera (can be retrieved without an open session)
/// </summary>
protected DeviceInfo Info;
/// <summary>
/// Thread for executing SDK commands
/// </summary>
protected STAThread MainThread;
/// <summary>
/// Pointer to the SDKs camera object
/// </summary>
public IntPtr Reference
{
get { return CamRef; }
}
/// <summary>
/// An ID for the camera object in this session. It's essentially the pointer of the Canon SDK camera object
/// </summary>
public long ID
{
get { return CamRef.ToInt64(); }
}
/// <summary>
/// States if a session with this camera is open
/// </summary>
public bool SessionOpen
{
get { return _SessionOpen; }
protected set { _SessionOpen = value; }
}
/// <summary>
/// States if the camera is disposed. If true, it can't be used anymore
/// </summary>
public bool IsDisposed
{
get { return _IsDisposed; }
}
/// <summary>
/// The name of the camera (can be retrieved without an open session)
/// </summary>
public string DeviceName
{
get { return Info.DeviceDescription; }
}
/// <summary>
/// The name of the port the camera is connected to (can be retrieved without an open session)
/// </summary>
public string PortName
{
get { return Info.PortName; }
}
/// <summary>
/// States if the live view is running on the computer or not
/// </summary>
public bool IsLiveViewOn
{
get { return _IsLiveViewOn; }
protected set { _IsLiveViewOn = value; }
}
/// <summary>
/// States if Record property is available for this camera
/// </summary>
public bool IsRecordAvailable
{
get { return _IsRecordAvailable; }
}
/// <summary>
/// Pointer to the camera object
/// </summary>
private IntPtr CamRef;
/// <summary>
/// Variable to let the live view download loop continue or stop
/// </summary>
private bool KeepLVAlive = false;
/// <summary>
/// Thread for the live view download routine
/// </summary>
private Thread LVThread;
/// <summary>
/// Field for the public <see cref="IsLiveViewOn"/> property
/// </summary>
private bool _IsLiveViewOn;
/// <summary>
/// Field for the public <see cref="IsDisposed"/> property
/// </summary>
private bool _IsDisposed;
/// <summary>
/// Field for the public <see cref="SessionOpen"/> property
/// </summary>
private bool _SessionOpen;
/// <summary>
/// Field for the public <see cref="IsRecordAvailable"/> property
/// </summary>
private bool _IsRecordAvailable;
/// <summary>
/// Object to set a lock around starting/stopping the live view thread
/// </summary>
private readonly object lvThreadLockObj = new object();
/// <summary>
/// States if a film should be downloaded after filming or not
/// </summary>
private bool saveFilm;
/// <summary>
/// States if the live view should be shown on the PC while filming
/// </summary>
private bool useFilmingPcLv = false;
#endregion
#region Init/Open/Close/Dispose
/// <summary>
/// Constructor
/// </summary>
/// <param name="camRef">Reference to the camera object</param>
/// <exception cref="ArgumentNullException">Pointer to camera is zero</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
internal protected Camera(IntPtr camRef)
{
if (camRef == IntPtr.Zero) throw new ArgumentNullException(nameof(camRef));
CamRef = camRef;
MainThread = new STAThread();
MainThread.Start();
MainThread.Invoke(() => ErrorHandler.CheckError(this, CanonSDK.EdsGetDeviceInfo(CamRef, out Info)));
}
/// <summary>
/// Destructor
/// </summary>
~Camera()
{
Dispose(false);
}
/// <summary>
/// Open a new session with camera
/// </summary>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void OpenSession()
{
CheckState(false);
if (!SessionOpen)
{
MainThread.Invoke(() =>
{
ErrorHandler.CheckError(this, CanonSDK.EdsOpenSession(CamRef));
//Check if Record is available
int property;
_IsRecordAvailable = CanonSDK.GetPropertyData(CamRef, PropertyID.Record, 0, out property) == ErrorCode.OK;
//Subscribe to events
SDKStateEvent += new SDKStateEventHandler(Camera_SDKStateEvent);
SDKPropertyEvent += new SDKPropertyEventHandler(Camera_SDKPropertyEvent);
SDKProgressCallbackEvent += new SDKProgressCallback(Camera_SDKProgressCallbackEvent);
SDKObjectEvent += new SDKObjectEventHandler(Camera_SDKObjectEvent);
ErrorHandler.CheckError(this, CanonSDK.EdsSetCameraStateEventHandler(CamRef, StateEventID.All, SDKStateEvent, CamRef));
ErrorHandler.CheckError(this, CanonSDK.EdsSetObjectEventHandler(CamRef, ObjectEventID.All, SDKObjectEvent, CamRef));
ErrorHandler.CheckError(this, CanonSDK.EdsSetPropertyEventHandler(CamRef, PropertyEventID.All, SDKPropertyEvent, CamRef));
SessionOpen = true;
});
}
}
/// <summary>
/// Close session with camera
/// </summary>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void CloseSession()
{
CheckState(false);
if (SessionOpen)
{
//Unsubscribe from all events
UnsubscribeEvents();
//If the live view is on, stop it
if (IsLiveViewOn)
{
KeepLVAlive = false;
LVThread.Join(5000);
}
MainThread.Invoke(() =>
{
//Close the session with the camera
ErrorHandler.CheckError(this, CanonSDK.EdsCloseSession(CamRef));
SessionOpen = false;
});
}
}
/// <summary>
/// Releases all data and closes session
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases all data and closes session
/// </summary>
/// <param name="managed">True if called from Dispose, false if called from the finalizer/destructor</param>
protected virtual void Dispose(bool managed)
{
if (!IsDisposed)
{
//Unsubscribe from all events
UnsubscribeEvents();
//If the live view is on, stop it
if (IsLiveViewOn)
{
KeepLVAlive = false;
LVThread.Join();
}
IsLiveViewOn = false;
MainThread.Invoke(() =>
{
if (CanonAPI.IsSDKInitialized)
{
//If it's open, close the session
if (SessionOpen) CanonSDK.EdsCloseSession(CamRef);
//Release the camera
CanonSDK.EdsRelease(CamRef);
}
_IsDisposed = true;
});
//Shutdown the main camera thread
MainThread.Shutdown();
}
}
/// <summary>
/// Unsubscribes all camera events from this class and the SDK
/// </summary>
private void UnsubscribeEvents()
{
SDKStateEvent -= Camera_SDKStateEvent;
SDKPropertyEvent -= Camera_SDKPropertyEvent;
SDKProgressCallbackEvent -= Camera_SDKProgressCallbackEvent;
SDKObjectEvent -= Camera_SDKObjectEvent;
if (CanonAPI.IsSDKInitialized)
{
MainThread.Invoke(() =>
{
//Clear callbacks from Canon SDK
CanonSDK.EdsSetCameraStateEventHandler(CamRef, StateEventID.All, null, CamRef);
CanonSDK.EdsSetObjectEventHandler(CamRef, ObjectEventID.All, null, CamRef);
CanonSDK.EdsSetPropertyEventHandler(CamRef, PropertyEventID.All, null, CamRef);
});
}
}
#endregion
#region SDK Eventhandling
private ErrorCode Camera_SDKObjectEvent(ObjectEventID inEvent, IntPtr inRef, IntPtr inContext)
{
ThreadPool.QueueUserWorkItem((state) =>
{
try
{
var DownloadReadyEvent = DownloadReady;
if (inEvent == ObjectEventID.DirItemRequestTransfer && DownloadReadyEvent != null)
{
DownloadReadyEvent(this, new DownloadInfo(inRef));
}
else if (inEvent == ObjectEventID.DirItemCreated && saveFilm && DownloadReadyEvent != null)
{
saveFilm = false;
DownloadReadyEvent(this, new DownloadInfo(inRef));
}
}
catch (Exception ex) { if (!IsDisposed && !ErrorHandler.ReportError(this, ex)) throw; }
ObjectChanged?.Invoke(this, inEvent, inRef);
});
return ErrorCode.OK;
}
private ErrorCode Camera_SDKProgressCallbackEvent(int inPercent, IntPtr inContext, ref bool outCancel)
{
ThreadPool.QueueUserWorkItem((state) =>
{
try { ProgressChanged?.Invoke(this, inPercent); }
catch (Exception ex) { if (!IsDisposed && !ErrorHandler.ReportError(this, ex)) throw; }
});
return ErrorCode.OK;
}
private ErrorCode Camera_SDKPropertyEvent(PropertyEventID inEvent, PropertyID inPropertyID, int inParameter, IntPtr inContext)
{
ThreadPool.QueueUserWorkItem((state) =>
{
try
{
if (inPropertyID == PropertyID.Evf_OutputDevice || inPropertyID == PropertyID.Record)
{
lock (lvThreadLockObj)
{
EvfOutputDevice outDevice = GetEvf_OutputDevice();
Recording recordState = IsRecordAvailable ? ((Recording)GetInt32Setting(PropertyID.Record)) : Recording.Off;
if (outDevice == EvfOutputDevice.PC || (recordState == Recording.Ready && outDevice == EvfOutputDevice.Filming) ||
(useFilmingPcLv && recordState == Recording.On && (outDevice == EvfOutputDevice.Filming || outDevice == EvfOutputDevice.Camera)))
{
if (!KeepLVAlive)
{
KeepLVAlive = true;
LVThread = STAThread.CreateThread(DownloadEvf);
LVThread.Start();
}
}
else if (KeepLVAlive) { KeepLVAlive = false; }
}
}
}
catch (Exception ex) { if (!IsDisposed && !ErrorHandler.ReportError(this, ex)) throw; }
PropertyChanged?.Invoke(this, inEvent, inPropertyID, inParameter);
});
return ErrorCode.OK;
}
private ErrorCode Camera_SDKStateEvent(StateEventID inEvent, int inParameter, IntPtr inContext)
{
ThreadPool.QueueUserWorkItem((state) =>
{
try
{
if (inEvent == StateEventID.Shutdown)
{
SessionOpen = false;
Dispose(true);
CameraHasShutdown?.Invoke(this);
}
}
catch (Exception ex) { if (!IsDisposed && !ErrorHandler.ReportError(this, ex)) throw; }
StateChanged?.Invoke(this, inEvent, inParameter);
});
return ErrorCode.OK;
}
#endregion
#region Methods
#region Take Photo
/// <summary>
/// Takes a photo with the current camera settings with the TakePicture command
/// </summary>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
public void TakePhoto()
{
CheckState();
SendCommand(CameraCommand.TakePicture);
}
/// <summary>
/// Takes a photo with the current camera settings asynchronously with the TakePicture command
/// </summary>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
public void TakePhotoAsync()
{
CheckState();
ThreadPool.QueueUserWorkItem((state) =>
{
try { SendCommand(CameraCommand.TakePicture); }
catch (Exception ex) { if (!ErrorHandler.ReportError(this, ex)) throw; }
});
}
/// <summary>
/// Takes a photo with the current camera settings with the PressShutterButton command
/// </summary>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
public void TakePhotoShutter()
{
CheckState();
MainThread.Invoke(() =>
{
SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.Completely);
SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.OFF);
});
}
/// <summary>
/// Takes a photo with the current camera settings asynchronously with the PressShutterButton command
/// </summary>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
public void TakePhotoShutterAsync()
{
CheckState();
ThreadPool.QueueUserWorkItem((state) =>
{
try
{
MainThread.Invoke(() =>
{
SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.Completely);
SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.OFF);
});
}
catch (Exception ex) { if (!ErrorHandler.ReportError(this, ex)) throw; }
});
}
/// <summary>
/// Takes a bulb photo with the current camera settings.
/// The Tv camera value must be set to Bulb before calling this
/// </summary>
/// <param name="bulbTime">The time in ms for how long the shutter will be open</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
public void TakePhotoBulb(int bulbTime)
{
CheckState();
SendCommand(CameraCommand.BulbStart);
Thread.Sleep(bulbTime);
SendCommand(CameraCommand.BulbEnd);
}
/// <summary>
/// Takes a bulb photo with the current camera settings asynchronously.
/// The Tv camera value must be set to Bulb before calling this
/// </summary>
/// <param name="bulbTime">The time in ms for how long the shutter will be open</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
public void TakePhotoBulbAsync(int bulbTime)
{
CheckState();
ThreadPool.QueueUserWorkItem((state) =>
{
try
{
SendCommand(CameraCommand.BulbStart);
Thread.Sleep(bulbTime);
SendCommand(CameraCommand.BulbEnd);
}
catch (Exception ex) { if (!ErrorHandler.ReportError(this, ex)) throw; }
});
}
#endregion
#region File Handling
/// <summary>
/// Downloads a file to given directory with the filename in the <see cref="DownloadInfo"/>
/// </summary>
/// <param name="Info">The <see cref="DownloadInfo"/> that is provided by the <see cref="DownloadReady"/> event</param>
/// <param name="directory">The directory where the file will be saved to</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="ArgumentNullException">The DownloadInfo is null</exception>
public void DownloadFile(DownloadInfo Info, string directory)
{
CheckState();
if (Info == null) throw new ArgumentNullException(nameof(Info));
if (directory == null || string.IsNullOrEmpty(directory.Trim())) directory = ".";
string currentFile = Path.Combine(directory, Info.FileName);
if (!Directory.Exists(directory)) Directory.CreateDirectory(directory);
DownloadToFile(Info, currentFile);
}
/// <summary>
/// Downloads a file into a stream
/// </summary>
/// <param name="Info">The <see cref="DownloadInfo"/> that is provided by the <see cref="DownloadReady"/> event</param>
/// <returns>The stream containing the file data</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="ArgumentNullException">The DownloadInfo is null</exception>
public Stream DownloadFile(DownloadInfo Info)
{
CheckState();
if (Info == null) throw new ArgumentNullException(nameof(Info));
return DownloadToStream(Info);
}
/// <summary>
/// Cancels the download of an image
/// </summary>
/// <param name="Info">The DownloadInfo that is provided by the "<see cref="DownloadReady"/>" event</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="ArgumentNullException">The DownloadInfo is null</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void CancelDownload(DownloadInfo Info)
{
CheckState();
if (Info == null) throw new ArgumentNullException(nameof(Info));
MainThread.Invoke(() =>
{
ErrorHandler.CheckError(this, CanonSDK.EdsDownloadCancel(Info.Reference));
ErrorHandler.CheckError(this, CanonSDK.EdsRelease(Info.Reference));
});
}
/// <summary>
/// Gets all volumes available on the camera
/// </summary>
/// <returns>An array of CameraFileEntries that are the volumes</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
public CameraFileEntry[] GetAllVolumes()
{
CheckState();
return GetAllVolumesSub();
}
/// <summary>
/// Gets all volumes, folders and files existing on the camera
/// </summary>
/// <returns>A <see cref="CameraFileEntry"/> that contains all the information</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
public CameraFileEntry GetAllEntries()
{
CheckState();
return GetAllEntriesSub();
}
/// <summary>
/// Gets all images saved on the cameras memory card(s)
/// </summary>
/// <returns>An array of CameraFileEntries that are the images</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
public CameraFileEntry[] GetAllImages()
{
CheckState();
return GetAllImagesSub();
}
/// <summary>
/// Formats a given camera volume. Get the available volumes with <see cref="GetAllVolumes"/>
/// <para>Warning: All data on this volume will be lost!</para>
/// </summary>
/// <param name="volume">The volume that will get formatted</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="ArgumentException">CameraFileEntry is not a volume</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void FormatVolume(CameraFileEntry volume)
{
CheckState();
if (!volume.IsVolume) throw new ArgumentException("CameraFileEntry must be a volume");
MainThread.Invoke(() => ErrorHandler.CheckError(this, CanonSDK.EdsFormatVolume(volume.Reference)));
}
/// <summary>
/// Downloads all given files into a folder. To get all images on the camera, use
/// <see cref="GetAllImages"/> or for all files <see cref="GetAllEntries"/>
/// <para>
/// Note: All given CameraFileEntries will be disposed after this.
/// Call <see cref="GetAllImages"/> or <see cref="GetAllEntries"/> to get valid entries again.
/// </para>
/// </summary>
/// <param name="folderpath">The path to the folder where the files will be saved to</param>
/// <param name="files">The files that will be downloaded</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
public void DownloadFiles(string folderpath, CameraFileEntry[] files)
{
CheckState();
if (files == null) return;
if (folderpath == null || string.IsNullOrEmpty(folderpath.Trim())) folderpath = ".";
if (!Directory.Exists(folderpath)) Directory.CreateDirectory(folderpath);
for (int i = 0; i < files.Length; i++)
{
if (!files[i].IsFolder && !files[i].IsDisposed)
{
var info = new DownloadInfo(files[i].Reference);
string CurrentFile = Path.Combine(folderpath, info.FileName);
DownloadToFile(info, CurrentFile);
}
}
}
/// <summary>
/// Deletes all given files on the camera.
/// To get all images on the camera, use <see cref="GetAllImages"/> or for all files <see cref="GetAllEntries"/>
/// <para>Warning: All given files will be lost!</para>
/// </summary>
/// <param name="files">The images that will be deleted</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
public void DeleteFiles(CameraFileEntry[] files)
{
CheckState();
if (files == null || files.Length == 0) return;
for (int i = 0; i < files.Length; i++)
{
if (!files[i].IsFolder && !files[i].IsDisposed)
{
ErrorHandler.CheckError(this, CanonSDK.EdsDeleteDirectoryItem(files[i].Reference));
files[i].IsDisposed = true;
}
}
}
#endregion
#region Other
/// <summary>
/// Tells the camera how much space is available on the host PC
/// </summary>
/// <param name="bytesPerSector">Bytes per HD sector</param>
/// <param name="numberOfFreeClusters">Number of free clusters on the HD</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void SetCapacity(int bytesPerSector, int numberOfFreeClusters)
{
CheckState();
MainThread.Invoke(() =>
{
Capacity capacity = new Capacity(numberOfFreeClusters, bytesPerSector, true);
ErrorHandler.CheckError(this, CanonSDK.EdsSetCapacity(CamRef, capacity));
});
}
/// <summary>
/// Locks or unlocks the camera UI
/// </summary>
/// <param name="lockState">True to lock, false to unlock</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void UILock(bool lockState)
{
if (lockState) SendStatusCommand(CameraStatusCommand.UILock);
else SendStatusCommand(CameraStatusCommand.UIUnLock);
}
/// <summary>
/// Gets the list of possible values for the current camera to set.
/// Only the PropertyIDs "AEModeSelect", "ISO", "Av", "Tv", "MeteringMode" and "ExposureCompensation" are allowed.
/// </summary>
/// <param name="propId">The property ID</param>
/// <returns>A list of available values for the given property ID</returns>
public CameraValue[] GetSettingsList(PropertyID propId)
{
CheckState();
if (propId == PropertyID.AEModeSelect || propId == PropertyID.ISO || propId == PropertyID.Av || propId == PropertyID.Tv
|| propId == PropertyID.MeteringMode || propId == PropertyID.ExposureCompensation)
{
CameraValue[] vals = null;
PropertyDesc des = default(PropertyDesc);
MainThread.Invoke(() => ErrorHandler.CheckError(this, CanonSDK.EdsGetPropertyDesc(CamRef, propId, out des)));
vals = new CameraValue[des.NumElements];
for (int i = 0; i < vals.Length; i++) vals[i] = new CameraValue(des.PropDesc[i], propId);
return vals;
}
else throw new ArgumentException($"Method cannot be used with Property ID {propId}");
}
/// <summary>
/// Sends a command safely to the camera
/// </summary>
/// <param name="command">The command</param>
/// <param name="inParam">Additional parameter</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void SendCommand(CameraCommand command, int inParam = 0)
{
CheckState();
MainThread.Invoke(() => ErrorHandler.CheckError(this, CanonSDK.EdsSendCommand(CamRef, command, inParam)));
}
/// <summary>
/// Sends a Status Command to the camera
/// </summary>
/// <param name="command">The command</param>
/// <param name="inParam">Additional parameter</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void SendStatusCommand(CameraStatusCommand command, int inParam = 0)
{
CheckState();
MainThread.Invoke(() => ErrorHandler.CheckError(this, CanonSDK.EdsSendStatusCommand(CamRef, command, inParam)));
}
/// <summary>
/// Starts the live view
/// </summary>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void StartLiveView()
{
CheckState();
if (!IsLiveViewOn) SetSetting(PropertyID.Evf_OutputDevice, (int)EvfOutputDevice.PC);
}
/// <summary>
/// Stops the live view
/// </summary>
/// <param name="LVOff">If true, the live view is shut off, if false, the live view will be shown on the cameras screen</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void StopLiveView(bool LVOff = true)
{
CheckState();
if (LVOff) SetSetting(PropertyID.Evf_OutputDevice, (int)EvfOutputDevice.Off);
else SetSetting(PropertyID.Evf_OutputDevice, (int)EvfOutputDevice.Camera);
}
/// <summary>
/// Starts recording a video
/// <para>Note: The camera has to be set into filming mode before using this (usually a physical switch on the camera)</para>
/// <para>This works only on cameras that support filming</para>
/// </summary>
/// <param name="PCLiveview">If true, the live view will be transferred to the computer otherwise it's shown on the camera</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="InvalidOperationException">The camera is not in film mode</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void StartFilming(bool PCLiveview)
{
CheckState();
Recording state = (Recording)GetInt32Setting(PropertyID.Record);
if (state != Recording.On)
{
if (state != Recording.Ready) throw new InvalidOperationException("The camera is not ready to film. The Record property has to be Recording.Ready");
useFilmingPcLv = PCLiveview;
//When recording videos, it has to be saved on the camera internal memory
SetSetting(PropertyID.SaveTo, (int)SaveTo.Camera);
//Start the video recording
SetSetting(PropertyID.Record, (int)Recording.On);
}
}
/// <summary>
/// Stops recording a video
/// </summary>
/// <param name="saveFilm">If true, the <see cref="DownloadReady"/> event will fire as soon as the video file is created on the camera</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void StopFilming(bool saveFilm)
{
StopFilming(saveFilm, true);
}
/// <summary>
/// Stops recording a video
/// </summary>
/// <param name="saveFilm">If true, the <see cref="DownloadReady"/> event will fire as soon as the video file is created on the camera</param>
/// <param name="stopLiveView">If true, the PC live view will stop and will only be shown on the camera</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void StopFilming(bool saveFilm, bool stopLiveView)
{
CheckState();
Recording state = (Recording)GetInt32Setting(PropertyID.Record);
if (state == Recording.On)
{
this.saveFilm = saveFilm;
//Stop video recording
SetSetting(PropertyID.Record, (int)Recording.Off);
useFilmingPcLv = false;
if (IsLiveViewOn && stopLiveView) StopLiveView(false);
}
}
#endregion
#region Set Settings
/// <summary>
/// Sets a value for the given property ID
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="value">The value which will be set</param>
/// <param name="inParam">Additional property information</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void SetSetting(PropertyID propID, object value, int inParam = 0)
{
CheckState();
MainThread.Invoke(() =>
{
int propsize;
DataType proptype;
ErrorHandler.CheckError(this, CanonSDK.EdsGetPropertySize(CamRef, propID, inParam, out proptype, out propsize));
ErrorHandler.CheckError(this, CanonSDK.EdsSetPropertyData(CamRef, propID, inParam, propsize, value));
});
}
/// <summary>
/// Sets a string value for the given property ID
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="value">The value which will be set</param>
/// <param name="inParam">Additional property information</param>
/// <param name="MAX">The maximum length of the string</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public void SetSetting(PropertyID propID, string value, int inParam = 0, int MAX = 32)
{
CheckState();
if (value == null) value = string.Empty;
if (value.Length > MAX - 1) value = value.Substring(0, MAX - 1);
byte[] propBytes = System.Text.Encoding.ASCII.GetBytes(value + '\0');
MainThread.Invoke(() =>
{
ErrorHandler.CheckError(this, CanonSDK.EdsSetPropertyData(CamRef,
propID, inParam, propBytes.Length, propBytes));
});
}
/// <summary>
/// Sets a struct value for the given property ID
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="value">The value which will be set</param>
/// <param name="inParam">Additional property information</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
[Obsolete("Use SetSetting directly because internally it does the same")]
public void SetStructSetting<T>(PropertyID propID, T value, int inParam = 0) where T : struct
{
SetSetting(propID, value, inParam);
}
#endregion
#region Get Settings
/// <summary>
/// Gets the current setting of given property ID
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public bool GetBoolSetting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
bool property;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out property));
return property;
});
}
/// <summary>
/// Gets the current setting of given property ID
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public byte GetByteSetting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
byte property;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out property));
return property;
});
}
/// <summary>
/// Gets the current setting of given property ID
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public short GetInt16Setting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
short property;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out property));
return property;
});
}
/// <summary>
/// Gets the current setting of given property ID
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
[CLSCompliant(false)]
public ushort GetUInt16Setting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
ushort property;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out property));
return property;
});
}
/// <summary>
/// Gets the current setting of given property ID
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
[CLSCompliant(false)]
public uint GetUInt32Setting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
uint property;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out property));
return property;
});
}
/// <summary>
/// Gets the current setting of given property ID
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public int GetInt32Setting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
int property;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out property));
return property;
});
}
/// <summary>
/// Gets the current setting of given property ID as a string
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public string GetStringSetting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
string property;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out property));
return property;
});
}
/// <summary>
/// Gets the current setting of given property ID as a integer array
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public bool[] GetBoolArrSetting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
bool[] data;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out data));
return data;
});
}
/// <summary>
/// Gets the current setting of given property ID as a integer array
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public short[] GetInt16ArrSetting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
short[] data;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out data));
return data;
});
}
/// <summary>
/// Gets the current setting of given property ID as a integer array
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public int[] GetInt32ArrSetting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
int[] data;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out data));
return data;
});
}
/// <summary>
/// Gets the current setting of given property ID as a integer array
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public byte[] GetByteArrSetting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
byte[] data;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out data));
return data;
});
}
/// <summary>
/// Gets the current setting of given property ID as a unsigned integer array
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
[CLSCompliant(false)]
public uint[] GetUInt32ArrSetting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
uint[] data;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out data));
return data;
});
}
/// <summary>
/// Gets the current setting of given property ID as a rational array
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public Rational[] GetRationalArrSetting(PropertyID propID, int inParam = 0)
{
CheckState();
return MainThread.Invoke(() =>
{
Rational[] data;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData(CamRef, propID, inParam, out data));
return data;
});
}
/// <summary>
/// Gets the current setting of given property ID as a struct
/// </summary>
/// <param name="propID">The property ID</param>
/// <param name="inParam">Additional property information</param>
/// <typeparam name="T">One of the EDSDK structs</typeparam>
/// <returns>The current setting of the camera</returns>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public T GetStructSetting<T>(PropertyID propID, int inParam = 0) where T : struct
{
CheckState();
return MainThread.Invoke(() =>
{
T property;
ErrorHandler.CheckError(this, CanonSDK.GetPropertyData<T>(CamRef, propID, inParam, out property));
return property;
});
}
/// <summary>
/// There is an overflow bug in the SDK that messes up the Evf_OutputDevice property.
/// With this method you can get the adjusted and correct value.
/// </summary>
/// <returns>The current output device of the live view</returns>
public EvfOutputDevice GetEvf_OutputDevice()
{
int value = GetInt32Setting(PropertyID.Evf_OutputDevice);
unchecked
{
if ((value > 2147483600 || value < -2147483640) && value != (int)0xFFFFFFFF) return (EvfOutputDevice)(int.MinValue + value);
else return (EvfOutputDevice)value;
};
}
#endregion
#region Subroutines
/// <summary>
/// Downloads live view images and the live view metadata continuously
/// </summary>
private void DownloadEvf()
{
if (IsLiveViewOn) return;
try
{
//Create variables
IntPtr evfImageRef = IntPtr.Zero;
ErrorCode err;
//Create stream
using (var stream = new SDKStream(0))
{
IsLiveViewOn = true;
//Run live view
while (KeepLVAlive)
{
//Get live view image
lock (STAThread.ExecLock)
{
err = CanonSDK.EdsCreateEvfImageRef(stream.Reference, out evfImageRef);
if (err == ErrorCode.OK) err = CanonSDK.EdsDownloadEvfImage(CamRef, evfImageRef);
}
//Check for errors
if (err == ErrorCode.OBJECT_NOTREADY) { continue; }
else if (err != ErrorCode.OK) { ErrorHandler.CheckError(err); continue; }
//Release current evf image
CanonSDK.EdsRelease(evfImageRef);
//Set stream position back to zero
stream.Position = 0;
//Update live view
LiveViewUpdated?.Invoke(this, stream);
}
}
}
catch (Exception ex) { if (ex is ThreadAbortException || !ErrorHandler.ReportError(this, ex)) throw; }
finally
{
IsLiveViewOn = false;
ThreadPool.QueueUserWorkItem((state) => LiveViewStopped?.Invoke(this));
}
}
/// <summary>
/// Downloads any data from the camera to the computer
/// </summary>
/// <param name="Info">The info about the object that will get downloaded</param>
/// <param name="stream">The pointer to the stream where the data will be loaded into</param>
/// <exception cref="SDKException">An SDK call failed</exception>
protected void DownloadData(DownloadInfo Info, IntPtr stream)
{
MainThread.Invoke(() =>
{
try
{
//Set the progress callback
ErrorHandler.CheckError(this, CanonSDK.EdsSetProgressCallback(stream, SDKProgressCallbackEvent, ProgressOption.Periodically, Info.Reference));
//Check which SDK version is used and download the data with the correct method
if (CanonSDK.IsVerGE34) ErrorHandler.CheckError(this, CanonSDK.EdsDownload(Info.Reference, Info.Size64, stream));
else ErrorHandler.CheckError(this, CanonSDK.EdsDownload(Info.Reference, Info.Size, stream));
}
finally
{
//Release all data
ErrorHandler.CheckError(this, CanonSDK.EdsDownloadComplete(Info.Reference));
ErrorHandler.CheckError(this, CanonSDK.EdsRelease(Info.Reference));
}
});
}
/// <summary>
/// Downloads any data from the camera to the computer in a file
/// </summary>
/// <param name="Info">The info about the object that will get downloaded</param>
/// <param name="filepath">The path with filename to where the data will be saved to</param>
/// <exception cref="SDKException">An SDK call failed</exception>
protected void DownloadToFile(DownloadInfo Info, string filepath)
{
using (var stream = new SDKStream(filepath, FileCreateDisposition.CreateAlways, FileAccess.ReadWrite))
{
DownloadData(Info, stream.Reference);
}
}
/// <summary>
/// Downloads any data from the camera to the computer into a <see cref="Stream"/>
/// </summary>
/// <param name="Info">The info about the object that will get downloaded</param>
/// <returns>A <see cref="Stream"/> containing the downloaded data</returns>
/// <exception cref="SDKException">An SDK call failed</exception>
protected Stream DownloadToStream(DownloadInfo Info)
{
SDKStream stream = new SDKStream(Info.Size64);
DownloadData(Info, stream.Reference);
stream.Position = 0;
return stream;
}
/// <summary>
/// Gets information about camera file entries recursively
/// </summary>
/// <param name="ptr">Pointer to the current file object</param>
/// <returns>An array of file entries</returns>
/// <exception cref="SDKException">An SDK call failed</exception>
protected CameraFileEntry[] GetChildren(IntPtr ptr)
{
int ChildCount;
lock (STAThread.ExecLock) { ErrorHandler.CheckError(this, CanonSDK.EdsGetChildCount(ptr, out ChildCount)); }
if (ChildCount > 0)
{
CameraFileEntry[] MainEntry = new CameraFileEntry[ChildCount];
for (int i = 0; i < ChildCount; i++)
{
MainEntry[i] = GetChild(ptr, i);
if (MainEntry[i].IsFolder)
{
CameraFileEntry[] retval = GetChildren(MainEntry[i].Reference);
if (retval != null) MainEntry[i].Entries = retval;
}
}
return MainEntry;
}
else return null;
}
/// <summary>
/// Gets information about children of a folder in the cameras file system
/// </summary>
/// <param name="ptr">Pointer to the folder</param>
/// <param name="index">Index of the child in the folder</param>
/// <returns>A camera file entry of this child</returns>
/// <exception cref="SDKException">An SDK call failed</exception>
protected CameraFileEntry GetChild(IntPtr ptr, int index)
{
return MainThread.Invoke(() =>
{
IntPtr ChildPtr;
DirectoryItemInfo ChildInfo;
ErrorHandler.CheckError(this, CanonSDK.EdsGetChildAtIndex(ptr, index, out ChildPtr));
ErrorHandler.CheckError(this, CanonSDK.GetDirectoryItemInfo(ChildPtr, out ChildInfo));
CameraFileEntry outEntry = new CameraFileEntry(ChildPtr, ChildInfo.FileName, ChildInfo.IsFolder, false);
if (!outEntry.IsFolder)
{
using (var stream = new SDKStream(0))
{
ErrorHandler.CheckError(this, CanonSDK.EdsDownloadThumbnail(ChildPtr, stream.Reference));
outEntry.SetThumb(stream.Reference);
}
}
return outEntry;
});
}
/// <summary>
/// Checks if the camera and SDK state is valid
/// </summary>
/// <param name="checkSession">If true, it checks if the session is open</param>
/// <exception cref="ObjectDisposedException">Camera is disposed</exception>
/// <exception cref="CameraSessionException">Session is closed</exception>
/// <exception cref="SDKStateException">Canon SDK is not initialized</exception>
protected void CheckState(bool checkSession = true)
{
if (IsDisposed) throw new ObjectDisposedException(nameof(Camera) + ID);
if (checkSession && !SessionOpen) throw new CameraSessionException("Session is closed");
if (!CanonAPI.IsSDKInitialized) throw new SDKStateException("Canon SDK is not initialized");
}
/// <summary>
/// Creates a bool value from an integer. 1 == true, else == false
/// </summary>
/// <param name="val">The integer value</param>
/// <returns>The bool value</returns>
protected bool GetBool(int val)
{
return val == 1;
}
/// <summary>
/// Gets all volumes, folders and files existing on the camera
/// </summary>
/// <returns>A <see cref="CameraFileEntry"/> that contains all the information</returns>
/// <exception cref="SDKException">An SDK call failed</exception>
protected CameraFileEntry GetAllEntriesSub()
{
CameraFileEntry MainEntry = new CameraFileEntry(IntPtr.Zero, DeviceName, true, false);
CameraFileEntry[] VolumeEntries = GetAllVolumesSub();
for (int i = 0; i < VolumeEntries.Length; i++) VolumeEntries[i].Entries = GetChildren(VolumeEntries[i].Reference);
MainEntry.Entries = VolumeEntries;
return MainEntry;
}
/// <summary>
/// Gets all images saved on the cameras memory card(s)
/// </summary>
/// <returns>An array of CameraFileEntries that are the images</returns>
/// <exception cref="SDKException">An SDK call failed</exception>
protected CameraFileEntry[] GetAllImagesSub()
{
CameraFileEntry[] volumes = GetAllVolumesSub();
List<CameraFileEntry> ImageList = new List<CameraFileEntry>();
for (int i = 0; i < volumes.Length; i++)
{
int ChildCount;
lock (STAThread.ExecLock) { ErrorHandler.CheckError(this, CanonSDK.EdsGetChildCount(volumes[i].Reference, out ChildCount)); }
CameraFileEntry[] ventries = new CameraFileEntry[0];
for (int j = 0; j < ChildCount; j++)
{
CameraFileEntry entry = GetChild(volumes[i].Reference, j);
if (entry.IsFolder && entry.Name == "DCIM") { ventries = GetChildren(entry.Reference); break; }
}
foreach (CameraFileEntry ve in ventries) { if (ve.IsFolder && ve.Entries != null) ImageList.AddRange(ve.Entries.Where(t => !t.IsFolder)); }
}
return ImageList.ToArray();
}
/// <summary>
/// Checks for all volumes available on the camera.
/// </summary>
/// <returns>An array of CameraFileEntries where each represents a volume (Note: content of volumes is not read)</returns>
/// <exception cref="SDKException">An SDK call failed</exception>
protected CameraFileEntry[] GetAllVolumesSub()
{
int VolumeCount;
IntPtr ChildPtr;
VolumeInfo vinfo;
List<CameraFileEntry> VolumeEntries = new List<CameraFileEntry>();
MainThread.Invoke(() =>
{
ErrorHandler.CheckError(this, CanonSDK.EdsGetChildCount(CamRef, out VolumeCount));
for (int i = 0; i < VolumeCount; i++)
{
ErrorHandler.CheckError(this, CanonSDK.EdsGetChildAtIndex(CamRef, i, out ChildPtr));
ErrorHandler.CheckError(this, CanonSDK.EdsGetVolumeInfo(ChildPtr, out vinfo));
if (vinfo.VolumeLabel != "HDD") VolumeEntries.Add(new CameraFileEntry(ChildPtr, "Volume" + i + "(" + vinfo.VolumeLabel + ")", true, true));
}
});
return VolumeEntries.ToArray();
}
#endregion
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading;
using EOSDigital.SDK;
using Size = EOSDigital.SDK.Size;
namespace EOSDigital.API
{
/// <summary>
/// Handles camera connections
/// </summary>
public class CanonAPI : IDisposable
{
#region Events
/// <summary>
/// Fires if a new camera is added
/// </summary>
public event CameraAddedHandler CameraAdded;
/// <summary>
/// The SDK camera added delegate
/// </summary>
protected static SDKCameraAddedHandler CameraAddedEvent;
private ErrorCode CanonAPI_CameraAddedEvent(IntPtr inContext)
{
ThreadPool.QueueUserWorkItem((state) => CameraAdded?.Invoke(this));
return ErrorCode.OK;
}
#endregion
#region Variables
/// <summary>
/// States if the SDK is initialized or not
/// </summary>
public static bool IsSDKInitialized
{
get { return _IsSDKInitialized; }
}
/// <summary>
/// The main SDK thread where the event loop runs
/// </summary>
protected static STAThread MainThread;
/// <summary>
/// Field for the public <see cref="IsSDKInitialized"/> property
/// </summary>
private static bool _IsSDKInitialized;
/// <summary>
/// States if the instance is disposed or not
/// </summary>
private bool IsDisposed;
/// <summary>
/// Number of instances of this class
/// </summary>
private static int RefCount = 0;
/// <summary>
/// Object to lock on to safely de- and increment the <see cref="RefCount"/> value
/// </summary>
private static readonly object InitLock = new object();
/// <summary>
/// List of currently connected cameras (since the last time GetCameraList got called)
/// </summary>
private static List<Camera> CurrentCameras = new List<Camera>();
/// <summary>
/// Object to lock on to safely add/remove cameras from the <see cref="CurrentCameras"/> list
/// </summary>
private static readonly object CameraLock = new object();
#endregion
#region Init/Dispose
/// <summary>
/// Initializes the SDK
/// </summary>
public CanonAPI()
: this(false)
{ }
/// <summary>
/// Initializes the SDK
/// </summary>
/// <param name="useCallingThread">If true, the calling thread will be used as SDK main thread;
/// if false, a separate thread will be created</param>
public CanonAPI(bool useCallingThread)
{
try
{
//Ensure that only one caller at a time can increase the counter
lock (InitLock)
{
//If no instance exists yet, initialize everything
if (RefCount == 0)
{
if (useCallingThread)
{
if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
throw new ThreadStateException("Calling thread must be in STA");
ErrorHandler.CheckError(this, CanonSDK.EdsInitializeSDK());
}
else
{
//Trying to trigger DllNotFoundException so it's not thrown
//in the event loop on a different thread:
CanonSDK.EdsRelease(IntPtr.Zero);
//Start the main thread where SDK will run on
MainThread = new ApiThread();
MainThread.Start();
//Initialize the SDK on the main thread
MainThread.Invoke(() => ErrorHandler.CheckError(this, CanonSDK.EdsInitializeSDK()));
}
CanonSDK.InitializeVersion();
//Subscribe to the CameraAdded event
CameraAddedEvent = new SDKCameraAddedHandler(CanonAPI_CameraAddedEvent);
ErrorHandler.CheckError(this, CanonSDK.EdsSetCameraAddedHandler(CameraAddedEvent, IntPtr.Zero));
_IsSDKInitialized = true;
}
RefCount++;
}
}
catch
{
IsDisposed = true;
if (MainThread?.IsRunning == true) MainThread.Shutdown();
throw;
}
}
/// <summary>
/// Destructor
/// </summary>
~CanonAPI()
{
Dispose(false);
}
/// <summary>
/// Terminates the SDK and disposes resources
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Terminates the SDK and disposes resources
/// </summary>
/// <param name="managed">True if called from Dispose, false if called from the finalizer/destructor</param>
protected virtual void Dispose(bool managed)
{
//Ensure that only one caller at a time can decrease the counter
lock (InitLock)
{
if (!IsDisposed)
{
//If it's the last instance, release everything
if (RefCount == 1)
{
_IsSDKInitialized = false;//Set beforehand because if an error happens, the SDK will be in an unstable state anyway
//Remove event handler for the CameraAdded event
ErrorCode err = CanonSDK.EdsSetCameraAddedHandler(null, IntPtr.Zero);
if (managed)
{
ErrorHandler.CheckError(this, err);
//Dispose all the connected cameras
CurrentCameras.ForEach(t => t.Dispose());
}
//Terminate the SDK
if (MainThread?.IsRunning == true) err = MainThread.Invoke(() => { return CanonSDK.EdsTerminateSDK(); });
//Close the main thread
if (MainThread?.IsRunning == true) MainThread.Shutdown();
if (managed) ErrorHandler.CheckError(this, err);
}
RefCount--;
IsDisposed = true;
}
}
}
#endregion
#region Methods
/// <summary>
/// Get a list of all cameras connected to the host.
/// <para>If a camera has been connected previously, the same instance of the class is returned.</para>
/// </summary>
/// <returns>A list of connected cameras</returns>
/// <exception cref="ObjectDisposedException">This instance has been disposed already</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
public List<Camera> GetCameraList()
{
if (IsDisposed) throw new ObjectDisposedException(nameof(CanonAPI));
//Ensure that only one caller at a time can access the camera list
lock (CameraLock)
{
//Get a list of camera pointers
IEnumerable<IntPtr> ptrList = GetCameraPointerList();
List<Camera> camList = new List<Camera>();
//Find cameras that were connected before and add new ones
foreach (var ptr in ptrList)
{
var oldCam = CurrentCameras.FirstOrDefault(t => t.Reference == ptr);
if (oldCam != null && !oldCam.IsDisposed) camList.Add(oldCam); //Pointer exists already so we reuse it
else camList.Add(new Camera(ptr)); //Pointer does not exists yet, so we add it
}
//Ensure that cameras not connected anymore are disposed properly
var oldCameras = CurrentCameras.Where(t => !ptrList.Any(u => u == t.Reference));
foreach (var cam in oldCameras) { if (!cam.IsDisposed) cam.Dispose(); }
CurrentCameras.Clear();
CurrentCameras.AddRange(camList);
return camList;
}
}
/// <summary>
/// Get a list of all pointer of the cameras connected to the host
/// </summary>
/// <returns>A list of connected cameras as pointer</returns>
/// <exception cref="ObjectDisposedException">This instance has been disposed already</exception>
/// <exception cref="SDKException">An SDK call failed</exception>
protected IEnumerable<IntPtr> GetCameraPointerList()
{
if (IsDisposed) throw new ObjectDisposedException(nameof(CanonAPI));
IntPtr camlist;
//Get camera list
ErrorHandler.CheckError(this, CanonSDK.EdsGetCameraList(out camlist));
//Get number of connected cameras
int camCount;
ErrorHandler.CheckError(this, CanonSDK.EdsGetChildCount(camlist, out camCount));
List<IntPtr> ptrList = new List<IntPtr>();
for (int i = 0; i < camCount; i++)
{
//Get camera pointer
IntPtr cptr;
ErrorHandler.CheckError(this, CanonSDK.EdsGetChildAtIndex(camlist, i, out cptr));
ptrList.Add(cptr);
}
//Release the list
ErrorHandler.CheckError(this, CanonSDK.EdsRelease(camlist));
return ptrList;
}
/// <summary>
/// Gets a thumbnail from a Raw or Jpg image
/// </summary>
/// <param name="filepath">Path to the image file</param>
/// <returns>A <see cref="Bitmap"/> thumbnail from the provided image file</returns>
public Bitmap GetFileThumb(string filepath)
{
//create a file stream to given file
using (var stream = new SDKStream(filepath, FileCreateDisposition.OpenExisting, FileAccess.Read))
{
//Create a thumbnail Bitmap from the stream
return GetImage(stream.Reference, ImageSource.Thumbnail);
}
}
/// <summary>
/// Gets a <see cref="Bitmap"/> from an EDSDK pointer to an image (Jpg or Raw)
/// </summary>
/// <param name="imgStream">Stream pointer to the image</param>
/// <param name="imageSource">The result image type</param>
/// <returns>A <see cref="Bitmap"/> image from the given stream pointer</returns>
protected Bitmap GetImage(IntPtr imgStream, ImageSource imageSource)
{
IntPtr imgRef = IntPtr.Zero;
IntPtr streamPointer = IntPtr.Zero;
ImageInfo imageInfo;
try
{
//create reference and get image info
ErrorHandler.CheckError(this, CanonSDK.EdsCreateImageRef(imgStream, out imgRef));
ErrorHandler.CheckError(this, CanonSDK.EdsGetImageInfo(imgRef, imageSource, out imageInfo));
Size outputSize = new Size();
outputSize.Width = imageInfo.EffectiveRect.Width;
outputSize.Height = imageInfo.EffectiveRect.Height;
//calculate amount of data
int datalength = outputSize.Height * outputSize.Width * 3;
//create buffer that stores the image
byte[] buffer = new byte[datalength];
//create a stream to the buffer
using (var stream = new SDKStream(buffer))
{
//load image into the buffer
ErrorHandler.CheckError(this, CanonSDK.EdsGetImage(imgRef, imageSource, TargetImageType.RGB, imageInfo.EffectiveRect, outputSize, stream.Reference));
//make BGR from RGB (System.Drawing (i.e. GDI+) uses BGR)
unsafe
{
byte tmp;
fixed (byte* pix = buffer)
{
for (long i = 0; i < datalength; i += 3)
{
tmp = pix[i]; //Save B value
pix[i] = pix[i + 2]; //Set B value with R value
pix[i + 2] = tmp; //Set R value with B value
}
}
}
//Get pointer to stream data
ErrorHandler.CheckError(this, CanonSDK.EdsGetPointer(stream.Reference, out streamPointer));
//Create bitmap with the data in the buffer
return new Bitmap(outputSize.Width, outputSize.Height, datalength, PixelFormat.Format24bppRgb, streamPointer);
}
}
finally
{
//Release all data
if (imgStream != IntPtr.Zero) ErrorHandler.CheckError(this, CanonSDK.EdsRelease(imgStream));
if (imgRef != IntPtr.Zero) ErrorHandler.CheckError(this, CanonSDK.EdsRelease(imgRef));
}
}
#endregion
}
}
\ No newline at end of file
using EOSDigital.SDK;
using System.Threading;
namespace EOSDigital.API
{
internal sealed class ApiThread : STAThread
{
protected override void WaitForNotification()
{
lock (threadLock1)
{
while (block1 && IsRunning)
{
Monitor.Wait(threadLock1, 0);
lock (ExecLock)
{
CanonSDK.EdsGetEvent();
Monitor.Wait(ExecLock, 40);
}
}
block1 = true;
}
}
}
}
using EOSDigital.SDK;
namespace EOSDigital.API
{
/// <summary>
/// Stores a camera value
/// </summary>
public class CameraValue
{
/// <summary>
/// The value as a string
/// </summary>
public string StringValue { get; protected set; }
/// <summary>
/// The value as an UInt
/// </summary>
public int IntValue { get; protected set; }
/// <summary>
/// The value as a double
/// </summary>
public double DoubleValue { get; protected set; }
/// <summary>
/// The property ID of this value
/// </summary>
public PropertyID ValueType { get; protected set; }
/// <summary>
/// Creates a new instance of the <see cref="CameraValue"/> class
/// </summary>
protected CameraValue()
{
ValueType = PropertyID.Unknown;
StringValue = "N/A";
IntValue = unchecked((int)0xFFFFFFFF);
DoubleValue = 0.0;
}
/// <summary>
/// Creates a new camera value
/// </summary>
/// <param name="Value">The value as a string</param>
/// <param name="ValueType">The property ID of the value</param>
public CameraValue(string Value, PropertyID ValueType)
: this()
{
this.ValueType = ValueType;
StringValue = Value;
switch (ValueType)
{
case PropertyID.Av:
IntValue = AvValues.GetValue(Value).IntValue;
DoubleValue = AvValues.GetValue(Value).DoubleValue;
break;
case PropertyID.Tv:
IntValue = TvValues.GetValue(Value).IntValue;
DoubleValue = TvValues.GetValue(Value).DoubleValue;
break;
case PropertyID.ISO:
IntValue = ISOValues.GetValue(Value).IntValue;
DoubleValue = ISOValues.GetValue(Value).DoubleValue;
break;
case PropertyID.ColorTemperature:
int utmp;
IntValue = (int.TryParse(Value, out utmp)) ? utmp : 5600;
DoubleValue = utmp;
break;
case PropertyID.AEMode:
IntValue = AEModeValues.GetValue(Value).IntValue;
DoubleValue = AEModeValues.GetValue(Value).DoubleValue;
break;
case PropertyID.MeteringMode:
IntValue = MeteringModeValues.GetValue(Value).IntValue;
DoubleValue = MeteringModeValues.GetValue(Value).DoubleValue;
break;
case PropertyID.ExposureCompensation:
IntValue = ExpCompValues.GetValue(Value).IntValue;
DoubleValue = ExpCompValues.GetValue(Value).DoubleValue;
break;
}
}
/// <summary>
/// Creates a new camera value
/// </summary>
/// <param name="Value">The value as an uint</param>
/// <param name="ValueType">The property ID of the value</param>
public CameraValue(int Value, PropertyID ValueType)
: this()
{
this.ValueType = ValueType;
IntValue = Value;
switch (ValueType)
{
case PropertyID.Av:
StringValue = AvValues.GetValue(Value).StringValue;
DoubleValue = AvValues.GetValue(Value).DoubleValue;
break;
case PropertyID.Tv:
StringValue = TvValues.GetValue(Value).StringValue;
DoubleValue = TvValues.GetValue(Value).DoubleValue;
break;
case PropertyID.ISO:
StringValue = ISOValues.GetValue(Value).StringValue;
DoubleValue = ISOValues.GetValue(Value).DoubleValue;
break;
case PropertyID.ColorTemperature:
StringValue = Value.ToString();
DoubleValue = Value;
break;
case PropertyID.AEMode:
StringValue = AEModeValues.GetValue(Value).StringValue;
DoubleValue = AEModeValues.GetValue(Value).DoubleValue;
break;
case PropertyID.MeteringMode:
StringValue = MeteringModeValues.GetValue(Value).StringValue;
DoubleValue = MeteringModeValues.GetValue(Value).DoubleValue;
break;
case PropertyID.ExposureCompensation:
StringValue = ExpCompValues.GetValue(Value).StringValue;
DoubleValue = ExpCompValues.GetValue(Value).DoubleValue;
break;
}
}
/// <summary>
/// Creates a new camera value
/// </summary>
/// <param name="Value">The value as a double</param>
/// <param name="ValueType">The property ID of the value</param>
public CameraValue(double Value, PropertyID ValueType)
: this()
{
this.ValueType = ValueType;
DoubleValue = Value;
switch (ValueType)
{
case PropertyID.Av:
StringValue = AvValues.GetValue(Value).StringValue;
IntValue = AvValues.GetValue(Value).IntValue;
break;
case PropertyID.Tv:
StringValue = TvValues.GetValue(Value).StringValue;
IntValue = TvValues.GetValue(Value).IntValue;
break;
case PropertyID.ISO:
StringValue = ISOValues.GetValue(Value).StringValue;
IntValue = ISOValues.GetValue(Value).IntValue;
break;
case PropertyID.ColorTemperature:
StringValue = Value.ToString("F0");
IntValue = (int)Value;
break;
case PropertyID.AEMode:
StringValue = AEModeValues.GetValue(Value).StringValue;
IntValue = AEModeValues.GetValue(Value).IntValue;
break;
case PropertyID.MeteringMode:
StringValue = MeteringModeValues.GetValue(Value).StringValue;
IntValue = MeteringModeValues.GetValue(Value).IntValue;
break;
case PropertyID.ExposureCompensation:
StringValue = ExpCompValues.GetValue(Value).StringValue;
IntValue = ExpCompValues.GetValue(Value).IntValue;
break;
}
}
internal CameraValue(string SValue, int IValue, double DValue)
{
ValueType = PropertyID.Unknown;
StringValue = SValue;
IntValue = IValue;
DoubleValue = DValue;
}
internal CameraValue(string SValue, int IValue, double DValue, PropertyID ValueType)
{
this.ValueType = ValueType;
StringValue = SValue;
IntValue = IValue;
DoubleValue = DValue;
}
/// <summary>
/// Determines whether the specified <see cref="CameraValue"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="CameraValue"/></param>
/// <param name="y">The second <see cref="CameraValue"/></param>
/// <returns>True if the <see cref="CameraValue"/>s are equal; otherwise, false</returns>
public static bool operator ==(CameraValue x, CameraValue y)
{
// If both are null, or both are same instance, return true.
if (object.ReferenceEquals(x, y)) return true;
// If one is null, but not both, return false.
if ((object)x == null || (object)y == null) return false;
return x.IntValue == y.IntValue && x.ValueType == y.ValueType;
}
/// <summary>
/// Determines whether the specified <see cref="CameraValue"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="CameraValue"/></param>
/// <param name="y">The second <see cref="CameraValue"/></param>
/// <returns>True if the <see cref="CameraValue"/>s are unequal; otherwise, false</returns>
public static bool operator !=(CameraValue x, CameraValue y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="CameraValue"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="CameraValue"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="CameraValue"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
// If objects have different types, return false.
if (obj.GetType() != GetType()) return false;
// If both are null, or both are same instance, return true.
if (object.ReferenceEquals(this, obj)) return true;
CameraValue cv = obj as CameraValue;
if (cv == null) return false;
return IntValue == cv.IntValue && ValueType == cv.ValueType;
}
/// <summary>
/// Serves as a hash function for a <see cref="CameraValue"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="CameraValue"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ IntValue.GetHashCode();
hash *= 16777619 ^ ValueType.GetHashCode();
return hash;
}
}
/// <summary>
/// Implicitly converts the camera value to an int
/// </summary>
/// <param name="x">The camera value to convert</param>
/// <returns>The int representing the camera value</returns>
public static implicit operator int(CameraValue x)
{
return x.IntValue;
}
/// <summary>
/// Implicitly converts the camera value to a string
/// </summary>
/// <param name="x">The camera value to convert</param>
/// <returns>The string representing the camera value</returns>
public static implicit operator string(CameraValue x)
{
return x.StringValue;
}
/// <summary>
/// Implicitly converts the camera value to a double
/// </summary>
/// <param name="x">The camera value to convert</param>
/// <returns>The double representing the camera value</returns>
public static implicit operator double(CameraValue x)
{
return x.DoubleValue;
}
/// <summary>
/// Returns a string that represents the current <see cref="CameraValue"/>.
/// </summary>
/// <returns>A string that represents the current <see cref="CameraValue"/>.</returns>
public override string ToString()
{
return StringValue;
}
}
}
using System;
using System.IO;
using EOSDigital.SDK;
namespace EOSDigital.API
{
/// <summary>
/// A delegate for progress
/// </summary>
/// <param name="sender">The sender of this event</param>
/// <param name="progress">The progress. A value between 0 and 100</param>
public delegate void ProgressHandler(object sender, int progress);
/// <summary>
/// A delegate to pass a stream
/// </summary>
/// <param name="sender">The sender of this event</param>
/// <param name="img">An image embedded in a stream</param>
public delegate void LiveViewUpdate(Camera sender, Stream img);
/// <summary>
/// A delegate to report an available download
/// </summary>
/// <param name="sender">The sender of this event</param>
/// <param name="Info">The data for the download</param>
public delegate void DownloadHandler(Camera sender, DownloadInfo Info);
/// <summary>
/// A delegate for property changes
/// </summary>
/// <param name="sender">The sender of this event</param>
/// <param name="eventID">The property event ID</param>
/// <param name="propID">The property ID</param>
/// <param name="parameter">A parameter for additional information</param>
public delegate void PropertyChangeHandler(Camera sender, PropertyEventID eventID, PropertyID propID, int parameter);
/// <summary>
/// A delegate for camera state changes
/// </summary>
/// <param name="sender">The sender of this event</param>
/// <param name="eventID">The state event ID</param>
/// <param name="parameter">A parameter for additional information</param>
public delegate void StateChangeHandler(Camera sender, StateEventID eventID, int parameter);
/// <summary>
/// A delegate for property changes
/// </summary>
/// <param name="sender">The sender of this event</param>
/// <param name="eventID">The object event ID</param>
/// <param name="reference">A pointer to the object that has changed</param>
public delegate void ObjectChangeHandler(Camera sender, ObjectEventID eventID, IntPtr reference);
/// <summary>
/// A delegate to inform of an added camera
/// </summary>
/// <param name="sender">The sender of this event</param>
public delegate void CameraAddedHandler(CanonAPI sender);
/// <summary>
/// A delegate to inform of a change of a camera
/// </summary>
/// <param name="sender">The sender of this event</param>
public delegate void CameraUpdateHandler(Camera sender);
/// <summary>
/// A delegate to inform of SDK exceptions
/// </summary>
/// <param name="sender">The sender of this event</param>
/// <param name="ex">The SDK exception</param>
public delegate void SDKExceptionHandler(object sender, ErrorCode ex);
/// <summary>
/// A delegate to inform of exceptions
/// </summary>
/// <param name="sender">The sender of this event</param>
/// <param name="ex">The exception</param>
public delegate void GeneralExceptionHandler(object sender, Exception ex);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Serialization;
using System.Security.Permissions;
using EOSDigital.SDK;
namespace EOSDigital.API
{
/// <summary>
/// An Exception that happened while handling the Canon SDK
/// </summary>
[Serializable]
public sealed class SDKException : Exception
{
/// <summary>
/// The specific SDK error code that happened
/// </summary>
public ErrorCode Error { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="SDKException"/> class
/// </summary>
public SDKException()
{
Error = ErrorCode.INTERNAL_ERROR;
}
/// <summary>
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified error code
/// </summary>
/// <param name="Error">The SDK error code of the error that happened</param>
public SDKException(ErrorCode Error)
: base(Error.ToString())
{
this.Error = Error;
}
/// <summary>
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified error message
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
public SDKException(string message)
: base(message)
{
Error = ErrorCode.INTERNAL_ERROR;
}
/// <summary>
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified
/// error message and a reference to the inner exception that is the cause of
/// this exception
/// </summary>
/// <param name="message">The error message that explains the reason for the exception</param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
/// (Nothing in Visual Basic) if no inner exception is specified</param>
public SDKException(string message, Exception innerException)
: base(message, innerException)
{
Error = ErrorCode.INTERNAL_ERROR;
}
/// <summary>
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified error message and error code
/// </summary>
/// <param name="Error">The SDK error code of the error that happened</param>
/// <param name="message">The error message that explains the reason for the exception</param>
public SDKException(string message, ErrorCode Error)
: base(message)
{
this.Error = Error;
}
/// <summary>
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified
/// error message, error code and a reference to the inner exception that is the cause of
/// this exception
/// </summary>
/// <param name="message">The error message that explains the reason for the exception</param>
/// <param name="Error">The SDK error code of the error that happened</param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
/// (Nothing in Visual Basic) if no inner exception is specified.</param>
public SDKException(string message, ErrorCode Error, Exception innerException)
: base(message, innerException)
{
this.Error = Error;
}
/// <summary>
/// Initializes a new instance of the <see cref="SDKException"/> class with serialized data.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
/// object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
/// information about the source or destination.</param>
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
private SDKException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
Error = (ErrorCode)info.GetUInt32("Error");
}
/// <summary>
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
/// with information about the exception.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/>
/// that holds the serialized object data about the exception being thrown</param>
/// <param name="context">The <see cref="StreamingContext"/>
/// that contains contextual information about the source or destination.</param>
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null) throw new ArgumentNullException(nameof(info));
info.AddValue("Error", Error);
base.GetObjectData(info, context);
}
}
/// <summary>
/// An Exception that states a problem with the session state of the camera
/// </summary>
[Serializable]
public sealed class CameraSessionException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="CameraSessionException"/> class
/// </summary>
public CameraSessionException()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="CameraSessionException"/> class with a specified error message
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
public CameraSessionException(string message)
: base(message)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="CameraSessionException"/> class with a specified
/// error message and a reference to the inner exception that is the cause of
/// this exception
/// </summary>
/// <param name="message">The error message that explains the reason for the exception</param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
/// (Nothing in Visual Basic) if no inner exception is specified</param>
public CameraSessionException(string message, Exception innerException)
: base(message, innerException)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="CameraSessionException"/> class with serialized data.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
/// object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
/// information about the source or destination.</param>
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
private CameraSessionException(SerializationInfo info, StreamingContext context)
: base(info, context)
{ }
/// <summary>
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
/// with information about the exception.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/>
/// that holds the serialized object data about the exception being thrown</param>
/// <param name="context">The <see cref="StreamingContext"/>
/// that contains contextual information about the source or destination.</param>
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null) throw new ArgumentNullException(nameof(info));
base.GetObjectData(info, context);
}
}
/// <summary>
/// An Exception that states a problem with the state of the Canon SDK
/// </summary>
[Serializable]
public sealed class SDKStateException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="SDKStateException"/> class
/// </summary>
public SDKStateException()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="SDKStateException"/> class with a specified error message
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
public SDKStateException(string message)
: base(message)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="SDKStateException"/> class with a specified
/// error message and a reference to the inner exception that is the cause of
/// this exception
/// </summary>
/// <param name="message">The error message that explains the reason for the exception</param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
/// (Nothing in Visual Basic) if no inner exception is specified</param>
public SDKStateException(string message, Exception innerException)
: base(message, innerException)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="SDKStateException"/> class with serialized data.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
/// object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
/// information about the source or destination.</param>
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
private SDKStateException(SerializationInfo info, StreamingContext context)
: base(info, context)
{ }
/// <summary>
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
/// with information about the exception.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/>
/// that holds the serialized object data about the exception being thrown</param>
/// <param name="context">The <see cref="StreamingContext"/>
/// that contains contextual information about the source or destination.</param>
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null) throw new ArgumentNullException(nameof(info));
base.GetObjectData(info, context);
}
}
/// <summary>
/// An Exception that happened while executing on an STA thread
/// </summary>
[Serializable]
public sealed class ExecutionException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="ExecutionException"/> class with a specified error message
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
public ExecutionException(string message)
: base(message)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ExecutionException"/> class with a reference to
/// the inner exception that is the cause of this exception
/// </summary>
/// <param name="message">The error message that explains the reason for the exception</param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
/// (Nothing in Visual Basic) if no inner exception is specified</param>
public ExecutionException(string message, Exception innerException)
: base(message, innerException)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="ExecutionException"/> class with serialized data.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
/// object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
/// information about the source or destination.</param>
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
private ExecutionException(SerializationInfo info, StreamingContext context)
: base(info, context)
{ }
/// <summary>
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
/// with information about the exception.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/>
/// that holds the serialized object data about the exception being thrown</param>
/// <param name="context">The <see cref="StreamingContext"/>
/// that contains contextual information about the source or destination.</param>
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null) throw new ArgumentNullException(nameof(info));
base.GetObjectData(info, context);
}
}
/// <summary>
/// Handles errors and provides events for errors (e.g. focus problems or general exceptions)
/// </summary>
public static class ErrorHandler
{
/// <summary>
/// If an error happened, that does not break the program, this event is fired (e.g. a focus error)
/// </summary>
public static event SDKExceptionHandler NonSevereErrorHappened;
/// <summary>
/// If an error happened on a thread that does not fall into the non-severe category, this event is fired
/// </summary>
public static event GeneralExceptionHandler SevereErrorHappened;
/// <summary>
/// List of all non-severe errors. Items can be added or removed.
/// </summary>
public static List<ErrorCode> NonSevereErrors { get; private set; }
static ErrorHandler()
{
NonSevereErrors = new List<ErrorCode>()
{
ErrorCode.TAKE_PICTURE_AF_NG,
ErrorCode.TAKE_PICTURE_CARD_NG,
ErrorCode.TAKE_PICTURE_CARD_PROTECT_NG,
ErrorCode.TAKE_PICTURE_LV_REL_PROHIBIT_MODE_NG,
ErrorCode.TAKE_PICTURE_MIRROR_UP_NG,
ErrorCode.TAKE_PICTURE_MOVIE_CROP_NG,
ErrorCode.TAKE_PICTURE_NO_CARD_NG,
ErrorCode.TAKE_PICTURE_NO_LENS_NG,
ErrorCode.TAKE_PICTURE_SENSOR_CLEANING_NG,
ErrorCode.TAKE_PICTURE_SILENCE_NG,
ErrorCode.TAKE_PICTURE_SPECIAL_MOVIE_MODE_NG,
ErrorCode.TAKE_PICTURE_STROBO_CHARGE_NG,
ErrorCode.LENS_COVER_CLOSE,
ErrorCode.DEVICE_BUSY,
};
}
/// <summary>
/// Checks for an error in SDK calls and checks how to treat it
/// </summary>
/// <param name="sender">The sender object</param>
/// <param name="errorCode">The return code of the SDK call</param>
/// <exception cref="SDKException">If a severe error is recognized or the <see cref="NonSevereErrorHappened"/>
/// event is null with a non-severe error, it will be thrown as an exception</exception>
public static void CheckError(object sender, ErrorCode errorCode)
{
if (errorCode == ErrorCode.OK) return;
else
{
bool Severe = !NonSevereErrors.Any(t => t == errorCode);
var NonSevereErrorHappenedEvent = NonSevereErrorHappened;
if (!Severe) Severe = NonSevereErrorHappenedEvent == null;
if (Severe) throw new SDKException(errorCode);
else NonSevereErrorHappenedEvent.BeginInvoke(sender, errorCode, (a) =>
{
var ar = a as AsyncResult;
var invokedMethod = ar.AsyncDelegate as SDKExceptionHandler;
invokedMethod.EndInvoke(a);
}, null);
}
}
/// <summary>
/// Checks for an error in SDK calls and throws an exception if it's not <see cref="ErrorCode.OK"/>
/// </summary>
/// <param name="errorCode">The return code of the SDK call</param>
/// <exception cref="SDKException">If <paramref name="errorCode"/> is something other than <see cref="ErrorCode.OK"/></exception>
public static void CheckError(ErrorCode errorCode)
{
if (errorCode != ErrorCode.OK) throw new SDKException(errorCode);
}
/// <summary>
/// Checks for an error in <see cref="CanonSDK.EdsRetain"/> and <see cref="CanonSDK.EdsRelease"/> calls
/// and throws an exception if it's not valid
/// </summary>
/// <param name="countOrError">The return code of the SDK call</param>
/// <returns>The number of references for the pointer that was used for the SDK call</returns>
public static int CheckError(int countOrError)
{
if (countOrError == unchecked((int)0xFFFFFFFF)) throw new SDKException(ErrorCode.INVALID_HANDLE);
else return countOrError;
}
/// <summary>
/// Checks for an error in <see cref="CanonSDK.EdsRetain"/> and <see cref="CanonSDK.EdsRelease"/> calls
/// and throws an exception if it's not valid
/// </summary>
/// <param name="sender">The calling object instance. This is currently not used and is ignored.</param>
/// <param name="countOrError">The return code of the SDK call</param>
/// <returns>The number of references for the pointer that was used for the SDK call</returns>
public static int CheckError(object sender, int countOrError)
{
return CheckError(countOrError);
}
/// <summary>
/// Reports an error that happened in a threading environment
/// </summary>
/// <param name="sender">The sender object</param>
/// <param name="ex">The exception that happened</param>
/// <returns>True if the error could be passed on; false otherwise</returns>
public static bool ReportError(object sender, Exception ex)
{
var SevereErrorHappenedEvent = SevereErrorHappened;
if (SevereErrorHappenedEvent == null) return false;
else
{
SevereErrorHappenedEvent.BeginInvoke(sender, ex, (a) =>
{
var ar = a as AsyncResult;
var invokedMethod = ar.AsyncDelegate as GeneralExceptionHandler;
invokedMethod.EndInvoke(a);
}, null);
return true;
}
}
}
}
using System;
using System.IO;
using EOSDigital.SDK;
using SeekOrigin = System.IO.SeekOrigin;
using FileAccess = EOSDigital.SDK.FileAccess;
namespace EOSDigital.API
{
/// <summary>
/// Stores information to download data from the camera
/// </summary>
public class DownloadInfo
{
/// <summary>
/// Pointer to the downloadable object
/// </summary>
protected IntPtr inRef;
/// <summary>
/// Directory item info of the downloadable object
/// </summary>
protected DirectoryItemInfo dirInfo;
/// <summary>
/// Pointer to the downloadable object
/// </summary>
public IntPtr Reference { get { return inRef; } }
/// <summary>
/// The name of the file. You can change it before you pass it to the
/// <see cref="Camera.DownloadFile(DownloadInfo)"/> or
/// <see cref="Camera.DownloadFile(DownloadInfo, string)"/> method.
/// </summary>
public string FileName
{
get { return dirInfo.FileName; }
set { dirInfo.FileName = value; }
}
/// <summary>
/// The files size in bytes
/// </summary>
public int Size { get { return dirInfo.Size; } }
/// <summary>
/// The files size in bytes (as ulong)
/// </summary>
public long Size64 { get { return dirInfo.Size64; } }
/// <summary>
/// States if the file is a RAW file or not
/// </summary>
public bool IsRAW { get; protected set; }
/// <summary>
/// Creates a new instance of the <see cref="DownloadInfo"/> class
/// </summary>
/// <param name="inRef">Pointer to the downloadable object</param>
internal protected DownloadInfo(IntPtr inRef)
{
if (inRef == IntPtr.Zero) throw new ArgumentNullException(nameof(inRef));
this.inRef = inRef;
ErrorHandler.CheckError(this, CanonSDK.GetDirectoryItemInfo(inRef, out dirInfo));
string ext = Path.GetExtension(FileName).ToLower();
if (ext == ".crw" || ext == ".cr2") IsRAW = true;
else IsRAW = false;
}
}
/// <summary>
/// Stores information about a file or folder in a camera
/// </summary>
public partial class CameraFileEntry : IDisposable
{
/// <summary>
/// Pointer to the file entry
/// </summary>
public IntPtr Reference { get { return Ref; } }
/// <summary>
/// The name of the entry. (volume name, folder name or file name)
/// </summary>
public string Name { get; protected set; }
/// <summary>
/// States if the entry is a folder or not
/// </summary>
public bool IsFolder { get; protected set; }
/// <summary>
/// States if the entry is a volume or not
/// </summary>
public bool IsVolume { get; protected set; }
/// <summary>
/// If the entry is a volume or folder, these are the subentries it contains. It's null if no subentries are present.
/// </summary>
public CameraFileEntry[] Entries { get; internal protected set; }
/// <summary>
/// Pointer to the file entry
/// </summary>
protected IntPtr Ref;
/// <summary>
/// States if the entry is disposed or not
/// </summary>
internal protected bool IsDisposed;
/// <summary>
/// Creates a new instance of the <see cref="CameraFileEntry"/> class
/// </summary>
/// <param name="Ref"></param>
/// <param name="Name"></param>
/// <param name="IsFolder"></param>
/// <param name="IsVolume"></param>
internal protected CameraFileEntry(IntPtr Ref, string Name, bool IsFolder, bool IsVolume)
{
this.Ref = Ref;
this.Name = Name;
this.IsFolder = IsFolder;
this.IsVolume = IsVolume;
}
/// <summary>
/// Destructor
/// </summary>
~CameraFileEntry()
{
Dispose(false);
}
/// <summary>
/// Releases this entry but not the subentries
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases this entry and all the subentries
/// </summary>
public void DisposeAll()
{
Dispose();
if (Entries != null) for (int i = 0; i < Entries.Length; i++) Entries[i].DisposeAll();
}
/// <summary>
/// Releases this entry but not the subentries
/// </summary>
/// <param name="managed">True if called from Dispose, false if called from the finalizer/destructor</param>
protected virtual void Dispose(bool managed)
{
if (!IsDisposed)
{
if (managed) DisposeThumb();
if (Reference != IntPtr.Zero) CanonSDK.EdsRelease(Reference);
IsDisposed = true;
}
}
/// <summary>
/// Dispose the thumbnail in an extension
/// </summary>
partial void DisposeThumb();
/// <summary>
/// Set the thumbnail from a stream. The thumbnail depends on the image class you want to use.
/// </summary>
/// <param name="stream">The image stream</param>
internal protected virtual void SetThumb(IntPtr stream)
{
SetThumbSub(stream);
}
/// <summary>
/// Sets the thumbnail
/// </summary>
/// <param name="stream">The image stream</param>
partial void SetThumbSub(IntPtr stream);
/// <summary>
/// Determines whether the specified <see cref="CameraFileEntry"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="CameraFileEntry"/></param>
/// <param name="y">The second <see cref="CameraFileEntry"/></param>
/// <returns>True if the <see cref="CameraFileEntry"/>s are equal; otherwise, false</returns>
public static bool operator ==(CameraFileEntry x, CameraFileEntry y)
{
// If both are null, or both are same instance, return true.
if (object.ReferenceEquals(x, y)) return true;
// If one is null, but not both, return false.
if ((object)x == null || (object)y == null) return false;
return x.Reference == y.Reference;
}
/// <summary>
/// Determines whether the specified <see cref="CameraFileEntry"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="CameraFileEntry"/></param>
/// <param name="y">The second <see cref="CameraFileEntry"/></param>
/// <returns>True if the <see cref="CameraFileEntry"/>s are unequal; otherwise, false</returns>
public static bool operator !=(CameraFileEntry x, CameraFileEntry y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="CameraFileEntry"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="CameraFileEntry"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="CameraFileEntry"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
// If objects have different types, return false.
if (obj.GetType() != GetType()) return false;
// If both are null, or both are same instance, return true.
if (object.ReferenceEquals(this, obj)) return true;
CameraFileEntry cv = obj as CameraFileEntry;
if (cv == null) return false;
return Reference == cv.Reference;
}
/// <summary>
/// Serves as a hash function for a <see cref="CameraFileEntry"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="CameraFileEntry"/></returns>
public override int GetHashCode()
{
return Reference.ToInt64().GetHashCode();
}
}
/// <summary>
/// A Stream encapsulating an unmanaged SDK Stream.
/// This class can be used to overcome the differences between SDK versions
/// </summary>
public class SDKStream : Stream
{
/// <summary>
/// Gets a value indicating whether the current stream supports reading.
/// </summary>
public override bool CanRead
{
get { return true; }
}
/// <summary>
/// Gets a value indicating whether the current stream supports seeking.
/// </summary>
public override bool CanSeek
{
get { return true; }
}
/// <summary>
/// Gets a value indicating whether the current stream supports writing.
/// </summary>
public override bool CanWrite
{
get { return true; }
}
/// <summary>
/// Gets the length in bytes of the stream.
/// </summary>
public override long Length
{
get
{
if (CanonSDK.IsVerGE34)
{
long length;
CanonSDK.EdsGetLength(Reference, out length);
return length;
}
else
{
int length;
CanonSDK.EdsGetLength(Reference, out length);
return length;
}
}
}
/// <summary>
/// Gets or sets the position within the current stream.
/// </summary>
public override long Position
{
get
{
if (CanonSDK.IsVerGE34)
{
long position;
CanonSDK.EdsGetPosition(Reference, out position);
return position;
}
else
{
int position;
CanonSDK.EdsGetPosition(Reference, out position);
return position;
}
}
set { Seek(value, SeekOrigin.Begin); }
}
/// <summary>
/// Pointer to the underlying SDK stream
/// </summary>
public IntPtr Reference
{
get { return _Reference; }
protected set { _Reference = value; }
}
private IntPtr _Reference;
/// <summary>
/// Creates a new instance of the <see cref="SDKStream"/> class from an existing SDK stream
/// </summary>
/// <param name="sdkStream">Pointer to the SDK stream</param>
public SDKStream(IntPtr sdkStream)
{
if (sdkStream == IntPtr.Zero) throw new ArgumentNullException(nameof(sdkStream));
Reference = sdkStream;
}
/// <summary>
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK file stream
/// </summary>
/// <param name="filepath">Path to the file</param>
/// <param name="createDisposition">State how to create the stream</param>
/// <param name="access">File access type</param>
public SDKStream(string filepath, FileCreateDisposition createDisposition, FileAccess access)
{
if (filepath == null) throw new ArgumentNullException(nameof(filepath));
ErrorHandler.CheckError(CanonSDK.EdsCreateFileStreamEx(filepath, createDisposition, access, out _Reference));
}
/// <summary>
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
/// This stream will resize itself if the current length is exceeded
/// </summary>
/// <param name="length">Initial buffer size of the stream in bytes</param>
public SDKStream(long length)
{
ErrorCode err;
if (CanonSDK.IsVerGE34) err = CanonSDK.EdsCreateMemoryStream(length, out _Reference);
else err = CanonSDK.EdsCreateMemoryStream((int)length, out _Reference);
ErrorHandler.CheckError(err);
}
/// <summary>
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
/// Note that this stream will not resize itself
/// </summary>
/// <param name="buffer">The memory buffer to use for the stream</param>
public SDKStream(byte[] buffer)
{
if (buffer == null) throw new ArgumentNullException(nameof(buffer));
ErrorCode err;
if (CanonSDK.IsVerGE34) err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, buffer.LongLength, out _Reference);
else err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, (int)buffer.LongLength, out _Reference);
ErrorHandler.CheckError(err);
}
/// <summary>
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
/// Note that this stream will not resize itself
/// </summary>
/// <param name="buffer">Pointer to the memory buffer to use for the stream</param>
/// <param name="length">The size of the memory buffer in bytes</param>
public SDKStream(IntPtr buffer, long length)
{
if (buffer == IntPtr.Zero) throw new ArgumentNullException(nameof(buffer));
ErrorCode err;
if (CanonSDK.IsVerGE34) err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, length, out _Reference);
else err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, (int)length, out _Reference);
ErrorHandler.CheckError(err);
}
/// <summary>
/// Creates a new instance of the <see cref="SDKStream"/> class from an existing SDK stream.
/// Note that this calls <see cref="SDKStream(IntPtr)"/> internally and ignores all parameters but <paramref name="sdkStream"/>
/// </summary>
/// <param name="buffer">Pointer to the underlying SDK buffer. Ignored parameter</param>
/// <param name="sdkStream">Pointer to the SDK stream</param>
/// <param name="length">The size of the underlying SDK buffer in bytes. Ignored parameter</param>
[Obsolete("Not necessary anymore. Buffer and length is not used.")]
public SDKStream(IntPtr buffer, IntPtr sdkStream, long length)
: this(sdkStream)
{ }
/// <summary>
/// Clears all buffers for this stream and causes any buffered data to be
/// written to the underlying device.
/// This is not applicable to the SDK and therefore does nothing.
/// </summary>
public override void Flush()
{
//Nothing to do here
}
/// <summary>
/// Reads a sequence of bytes from the current stream and advances the position
/// within the stream by the number of bytes read.
/// </summary>
/// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified
/// byte array with the values between offset and (offset + count - 1) replaced by
/// the bytes read from the current source.</param>
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read
/// from the current stream.</param>
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
/// <returns>The total number of bytes read into the buffer. This can be less than the number
/// of bytes requested if that many bytes are not currently available, or zero (0)
/// if the end of the stream has been reached.</returns>
public override int Read(byte[] buffer, int offset, int count)
{
return (int)Read(buffer, offset, count);
}
/// <summary>
/// Reads a sequence of bytes from the current stream and advances the position
/// within the stream by the number of bytes read.
/// </summary>
/// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified
/// byte array with the values between offset and (offset + count - 1) replaced by
/// the bytes read from the current source.</param>
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read
/// from the current stream.</param>
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
/// <returns>The total number of bytes read into the buffer. This can be less than the number
/// of bytes requested if that many bytes are not currently available, or zero (0)
/// if the end of the stream has been reached.</returns>
public unsafe long Read(byte[] buffer, long offset, long count)
{
if (buffer.LongLength < offset + count) throw new ArgumentOutOfRangeException();
fixed (byte* bufferPtr = buffer)
{
byte* offsetBufferPtr = bufferPtr + offset;
if (CanonSDK.IsVerGE34)
{
long read;
ErrorHandler.CheckError(CanonSDK.EdsRead(_Reference, count, (IntPtr)offsetBufferPtr, out read));
return read;
}
else
{
int read;
ErrorHandler.CheckError(CanonSDK.EdsRead(_Reference, (int)count, (IntPtr)offsetBufferPtr, out read));
return read;
}
}
}
/// <summary>
/// Sets the position within the current stream.
/// </summary>
/// <param name="offset">A byte offset relative to the origin parameter.</param>
/// <param name="origin">A value of type <see cref="SeekOrigin"/> indicating the
/// reference point used to obtain the new position.</param>
/// <returns>The new position within the current stream.</returns>
public override long Seek(long offset, SeekOrigin origin)
{
SDK.SeekOrigin sdkOrigin;
switch (origin)
{
case SeekOrigin.Begin:
sdkOrigin = SDK.SeekOrigin.Begin;
break;
case SeekOrigin.Current:
sdkOrigin = SDK.SeekOrigin.Current;
break;
case SeekOrigin.End:
sdkOrigin = SDK.SeekOrigin.End;
break;
default:
throw new ArgumentException("Not a valid enum value", nameof(origin));
}
if (CanonSDK.IsVerGE34) ErrorHandler.CheckError(CanonSDK.EdsSeek(_Reference, offset, sdkOrigin));
else ErrorHandler.CheckError(CanonSDK.EdsSeek(_Reference, (int)offset, sdkOrigin));
return Position;
}
/// <summary>
/// Always throws a <see cref="NotSupportedException"/>
/// </summary>
/// <param name="value">The desired length of the current stream in bytes.</param>
public override void SetLength(long value)
{
throw new NotSupportedException();
}
/// <summary>
/// Writes a sequence of bytes to the current stream and advances
/// the current position within this stream by the number of bytes written.
/// </summary>
/// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
/// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
/// <param name="count">The number of bytes to be written to the current stream.</param>
public override void Write(byte[] buffer, int offset, int count)
{
Write(buffer, (long)offset, count);
}
/// <summary>
/// Writes a sequence of bytes to the current stream and advances
/// the current position within this stream by the number of bytes written.
/// </summary>
/// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
/// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
/// <param name="count">The number of bytes to be written to the current stream.</param>
public unsafe void Write(byte[] buffer, long offset, long count)
{
if (buffer.LongLength < offset + count) throw new ArgumentOutOfRangeException();
fixed (byte* bufferPtr = buffer)
{
byte* offsetBufferPtr = bufferPtr + offset;
if (CanonSDK.IsVerGE34)
{
long written;
ErrorHandler.CheckError(CanonSDK.EdsWrite(_Reference, count, (IntPtr)offsetBufferPtr, out written));
}
else
{
int written;
ErrorHandler.CheckError(CanonSDK.EdsWrite(_Reference, (int)count, (IntPtr)offsetBufferPtr, out written));
}
}
}
/// <summary>
/// Releases the unmanaged resources used by the <see cref="SDKStream"/> and optionally
/// releases the managed resources.
/// </summary>
/// <param name="disposing">true to release both managed and unmanaged resources;
/// false to release only unmanaged</param>
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (_Reference != IntPtr.Zero)
{
int err = CanonSDK.EdsRelease(_Reference);
Reference = IntPtr.Zero;
if (disposing) ErrorHandler.CheckError(err);
}
}
}
}
using System;
using System.Threading;
namespace EOSDigital.API
{
/// <summary>
/// This static class executes things on an STA thread and provides a method to create an STA thread
/// </summary>
public class STAThread
{
#region Variables
/// <summary>
/// Object that is used for the lock keyword to ensure only one SDK command is executed at a time
/// </summary>
public static readonly object ExecLock = new object();
/// <summary>
/// States if the calling thread is in a Single Threaded Apartment or not
/// </summary>
public static bool IsSTAThread
{
get { return Thread.CurrentThread.GetApartmentState() == ApartmentState.STA; }
}
/// <summary>
/// States if this thread is currently running
/// </summary>
public bool IsRunning
{
get { return isRunning; }
}
/// <summary>
/// ID of the associated thread
/// </summary>
public int ThreadID
{
get { return mainThread.ManagedThreadId; }
}
/// <summary>
/// The main thread where everything will be executed on
/// </summary>
private Thread mainThread;
/// <summary>
/// States if the execution thread is currently running
/// </summary>
private bool isRunning = false;
/// <summary>
/// Lock object to make sure only one command at a time is executed
/// </summary>
private object runLock = new object();
/// <summary>
/// Lock object to ensure that an action executed on the thread does not invoke on itself
/// </summary>
private object cmdLock = new object();
/// <summary>
/// Lock object to synchronize between execution and calling thread
/// </summary>
protected object threadLock1 = new object();
/// <summary>
/// Lock object to synchronize between execution and calling thread
/// </summary>
private object threadLock2 = new object();
/// <summary>
/// States if the first lock is currently blocking or not
/// </summary>
protected bool block1 = true;
/// <summary>
/// States if the second lock is currently blocking or not
/// </summary>
private bool block2 = true;
/// <summary>
/// The action to be executed
/// </summary>
private Action runAction;
/// <summary>
/// Storage for an exception that might have happened on the execution thread
/// </summary>
private Exception runException;
#endregion
/// <summary>
/// Creates a new instance of the <see cref="STAThread"/> class
/// </summary>
internal STAThread()
{ }
#region Public Methods
/// <summary>
/// Starts the execution loop
/// </summary>
public void Start()
{
lock (runLock)
{
if (!isRunning)
{
mainThread = CreateThread(ExecutionLoop);
isRunning = true;
mainThread.Start();
WaitForThread();
}
}
}
/// <summary>
/// Shuts down the execution loop and waits for it to finish
/// </summary>
public void Shutdown()
{
lock (runLock)
{
if (isRunning)
{
isRunning = false;
NotifyThread();
mainThread.Join();
}
}
}
/// <summary>
/// Executes an action on this STA thread
/// </summary>
/// <param name="action">The action to execute</param>
/// <exception cref="ArgumentNullException">will be thrown if action is null</exception>
/// <exception cref="ExecutionException">if an exception is thrown on the thread,
/// it will be rethrown as inner exception of this exception</exception>
public void Invoke(Action action)
{
if (action == null) throw new ArgumentNullException(nameof(action));
//If the method is called from the execution thread, directly execute it.
//This prevents possible deadlocks when trying to acquire the runLock while waiting within for the thread to finish.
if (Monitor.TryEnter(cmdLock))
{
try { action(); }
finally { Monitor.Exit(cmdLock); }
}
else
{
lock (runLock)
{
if (!isRunning) throw new InvalidOperationException("Thread is not running");
runAction = action;
NotifyThread();
WaitForThread();
if (runException != null) throw new ExecutionException(runException.Message, runException);
}
}
}
/// <summary>
/// Executes a function on this STA thread
/// </summary>
/// <param name="func">The function to execute</param>
/// <returns>the return value of the function</returns>
/// <exception cref="ArgumentNullException">will be thrown if func is null</exception>
/// <exception cref="ExecutionException">if an exception is thrown on the thread,
/// it will be rethrown as inner exception of this exception</exception>
public T Invoke<T>(Func<T> func)
{
if (func == null) throw new ArgumentNullException(nameof(func));
T result = default(T);
Invoke(delegate { result = func(); });
return result;
}
#endregion
#region Static Methods
/// <summary>
/// Creates a thread in a Single Threaded Apartment
/// </summary>
/// <param name="action">The command to run on this thread</param>
/// <returns>An STA thread</returns>
public static Thread CreateThread(Action action)
{
var thread = new Thread(new ThreadStart(action));
thread.SetApartmentState(ApartmentState.STA);
return thread;
}
/// <summary>
/// Executes an action on a newly created STA Thread
/// and optionally waits for it to finish executing
/// </summary>
/// <param name="action">The action to execute</param>
/// <param name="wait">If true, the action is executed synchronously or if false, asynchronously.</param>
public static void ExecuteThread(Action action, bool wait)
{
Exception runException = null;
Thread thread = CreateThread(delegate
{
try { action(); }
catch (Exception ex)
{
if (wait) runException = ex;
else throw;
}
});
thread.Start();
if (wait)
{
thread.Join();
if (runException != null) throw new ExecutionException(runException.Message, runException);
}
}
/// <summary>
/// Executes a function on a newly created STA Thread
/// </summary>
/// <param name="func">The function to execute</param>
/// <returns>The return value of the given function</returns>
public static T ExecuteThread<T>(Func<T> func)
{
Exception runException = null;
T result = default(T);
Thread thread = CreateThread(delegate
{
try { result = func(); }
catch (Exception ex) { runException = ex; }
});
thread.Start();
thread.Join();
if (runException != null) throw new ExecutionException(runException.Message, runException);
return result;
}
#endregion
#region Subroutines
/// <summary>
/// Notifies the execution loop to execute something
/// </summary>
private void NotifyThread()
{
lock (threadLock1)
{
block1 = false;
Monitor.Pulse(threadLock1);
}
}
/// <summary>
/// Blocks until the execution loop is done with the work
/// </summary>
private void WaitForThread()
{
lock (threadLock2)
{
while (block2) Monitor.Wait(threadLock2);
block2 = true;
}
}
/// <summary>
/// Releases the waiting <see cref="WaitForThread"/> method to continue
/// </summary>
private void ReleaseWait()
{
lock (threadLock2)
{
block2 = false;
Monitor.Pulse(threadLock2);
}
}
/// <summary>
/// The waiting routine on the execution loop
/// </summary>
protected virtual void WaitForNotification()
{
lock (threadLock1)
{
while (block1 && isRunning) { Monitor.Wait(threadLock1); }
block1 = true;
}
}
/// <summary>
/// The loop that is executed on the thread and where the work is done
/// </summary>
private void ExecutionLoop()
{
ReleaseWait();
try
{
lock (cmdLock)
{
while (isRunning)
{
WaitForNotification();
if (!isRunning) return;
runException = null;
try { lock (ExecLock) { runAction(); } }
catch (Exception ex) { runException = ex; }
ReleaseWait();
}
}
}
finally
{
isRunning = false;
ReleaseWait();
}
}
#endregion
}
}
using System;
using System.Linq;
using System.Collections.Generic;
using EOSDigital.SDK;
namespace EOSDigital.API
{
/// <summary>
/// Stores CameraValues and provides methods to get those values. Abstract class.
/// </summary>
public abstract class ValueBase
{
/// <summary>
/// Get the value from an int out of given possible values.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of the value to get</param>
/// <param name="Values">Possible values that will be searched for the given value</param>
/// <returns>The CameraValue with given uint representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(int value, List<CameraValue> Values)
{
var arr = Values.Where(t => t.IntValue == value).ToArray();
if (arr.Length == 0)
{
var invalid = Values.FirstOrDefault(t => t.IntValue == unchecked((int)0xFFFFFFFF));
if (invalid != null) return invalid;
else throw new KeyNotFoundException("There is no CameraValue for this ID");
}
else { return arr[0]; }
}
/// <summary>
/// Get the value from a string out of given possible values.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of value to get</param>
/// <param name="Values">Possible values that will be searched for the given value</param>
/// <returns>The CameraValue with given string representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(string value, List<CameraValue> Values)
{
var arr = Values.Where(t => t.StringValue == value).ToArray();
if (arr.Length == 0)
{
var invalid = Values.FirstOrDefault(t => t.IntValue == unchecked((int)0xFFFFFFFF));
if (invalid != null) return invalid;
else throw new KeyNotFoundException("There is no CameraValue for this ID");
}
else { return arr[0]; }
}
/// <summary>
/// Get the value from a double out of given possible values.
/// It searches for the closest representation and therefore might not return the exact input value.
/// </summary>
/// <param name="value">The value to get</param>
/// <param name="Values">Possible values that will be searched for the given value</param>
/// <returns>The CameraValue with given double representation</returns>
public static CameraValue GetValue(double value, List<CameraValue> Values)
{
CameraValue[] sorted = Values.Distinct(new CameraValueComparer())
.Where(t => t.IntValue != unchecked((int)0xFFFFFFFF) && t != TvValues.Bulb && t != ISOValues.Auto)
.OrderBy(t => t.DoubleValue).ToArray();
for (int i = 0; i < sorted.Length; i++)
{
//Exact match:
if (Math.Abs(sorted[i].DoubleValue - value) <= 0.00000000001) return sorted[i];
else if (sorted[i].DoubleValue > value)
{
//Value is smaller than the range of given list. Return first:
if (i == 0) return sorted[i];
else
{
//Select CameraValue closest to given value
double delta1 = value - sorted[i - 1].DoubleValue;
double delta = sorted[i].DoubleValue - value;
if (delta > delta1) return sorted[i - 1];
else return sorted[i];
}
}
}
//Value is bigger than the range of given list. Return last:
return sorted[sorted.Length - 1];
}
/// <summary>
/// Comparer for <see cref="CameraValue"/>s
/// </summary>
protected sealed class CameraValueComparer : IEqualityComparer<CameraValue>
{
/// <summary>
/// Determines whether the specified <see cref="CameraValue"/>s are equal.
/// </summary>
/// <param name="x">The first <see cref="CameraValue"/></param>
/// <param name="y">The second <see cref="CameraValue"/></param>
/// <returns>true if the specified <see cref="CameraValue"/>s are equal; otherwise, false.</returns>
public bool Equals(CameraValue x, CameraValue y)
{
return x.Equals(y);
}
/// <summary>
/// Serves as a hash function for a <see cref="CameraValue"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="CameraValue"/></returns>
public int GetHashCode(CameraValue obj)
{
return obj.GetHashCode();
}
}
}
/// <summary>
/// Stores Av Values and provides methods to get those values
/// </summary>
public sealed class AvValues : ValueBase
{
/// <summary>
/// All values for this property
/// </summary>
public static CameraValue[] Values { get { return values.ToArray(); } }
private static List<CameraValue> values;
/// <summary>
/// The Av <see cref="CameraValue"/> of the "Auto" or "None" setting
/// </summary>
public static readonly CameraValue Auto = new CameraValue("Auto", 0x00000000, 0, PropertyID.Av);
/// <summary>
/// The Av <see cref="CameraValue"/> of an invalid setting
/// </summary>
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.Av);
static AvValues()
{
values = new List<CameraValue>()
{
Auto,
new CameraValue("1", 0x08, 1, PropertyID.Av),
new CameraValue("1.1", 0x0B, 1.1, PropertyID.Av),
new CameraValue("1.2", 0x0C, 1.2, PropertyID.Av),
new CameraValue("1.2 (1/3)", 0x0D, 1.2, PropertyID.Av),
new CameraValue("1.4", 0x10, 1.4, PropertyID.Av),
new CameraValue("1.6", 0x13, 1.6, PropertyID.Av),
new CameraValue("1.8", 0x14, 1.8, PropertyID.Av),
new CameraValue("1.8 (1/3)", 0x15, 1.8, PropertyID.Av),
new CameraValue("2", 0x18, 2, PropertyID.Av),
new CameraValue("2.2", 0x1B, 2.2, PropertyID.Av),
new CameraValue("2.5", 0x1C, 2.5, PropertyID.Av),
new CameraValue("2.5 (1/3)", 0x1D, 2.5, PropertyID.Av),
new CameraValue("2.8", 0x20, 2.8, PropertyID.Av),
new CameraValue("3.2", 0x23, 3.2, PropertyID.Av),
new CameraValue("3.5", 0x24, 3.5, PropertyID.Av),
new CameraValue("3.5 (1/3)", 0x25, 3.5, PropertyID.Av),
new CameraValue("4", 0x28, 4, PropertyID.Av),
new CameraValue("4.5", 0x2B, 4.5, PropertyID.Av),
new CameraValue("4.5 (1/3)", 0x2C, 4.5, PropertyID.Av),
new CameraValue("5.0", 0x2D, 5.0, PropertyID.Av),
new CameraValue("5.6", 0x30, 5.6, PropertyID.Av),
new CameraValue("6.3", 0x33, 6.3, PropertyID.Av),
new CameraValue("6.7", 0x34, 6.7, PropertyID.Av),
new CameraValue("7.1", 0x35, 7.1, PropertyID.Av),
new CameraValue("8", 0x38, 8, PropertyID.Av),
new CameraValue("9", 0x3B, 9, PropertyID.Av),
new CameraValue("9.5", 0x3C, 9.5, PropertyID.Av),
new CameraValue("10", 0x3D, 10, PropertyID.Av),
new CameraValue("11", 0x40, 11, PropertyID.Av),
new CameraValue("13 (1/3)", 0x43, 13, PropertyID.Av),
new CameraValue("13", 0x44, 13, PropertyID.Av),
new CameraValue("14", 0x45, 14, PropertyID.Av),
new CameraValue("16", 0x48, 16, PropertyID.Av),
new CameraValue("18", 0x4B, 18, PropertyID.Av),
new CameraValue("19", 0x4C, 19, PropertyID.Av),
new CameraValue("20", 0x4D, 20, PropertyID.Av),
new CameraValue("22", 0x50, 22, PropertyID.Av),
new CameraValue("25", 0x53, 25, PropertyID.Av),
new CameraValue("27", 0x54, 27, PropertyID.Av),
new CameraValue("29", 0x55, 29, PropertyID.Av),
new CameraValue("32", 0x58, 32, PropertyID.Av),
new CameraValue("36", 0x5B, 36, PropertyID.Av),
new CameraValue("38", 0x5C, 38, PropertyID.Av),
new CameraValue("40", 0x5D, 40, PropertyID.Av),
new CameraValue("45", 0x60, 45, PropertyID.Av),
new CameraValue("51", 0x63, 51, PropertyID.Av),
new CameraValue("54", 0x64, 54, PropertyID.Av),
new CameraValue("57", 0x65, 57, PropertyID.Av),
new CameraValue("64", 0x68, 64, PropertyID.Av),
new CameraValue("72", 0x6B, 72, PropertyID.Av),
new CameraValue("76", 0x6C, 76, PropertyID.Av),
new CameraValue("80", 0x6D, 80, PropertyID.Av),
new CameraValue("91", 0x70, 91, PropertyID.Av),
Invalid
};
}
/// <summary>
/// Get the value from an int.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of the value to get</param>
/// <returns>The CameraValue with given int representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(int value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a string.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of value to get</param>
/// <returns>The CameraValue with given string representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(string value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a double.
/// It searches for the closest representation and therefore might not return the exact input value.
/// </summary>
/// <param name="value">The value to get</param>
/// <returns>The CameraValue with given double representation</returns>
public static CameraValue GetValue(double value)
{
return GetValue(value, values);
}
}
/// <summary>
/// Stores Tv Values and provides methods to get those values
/// </summary>
public sealed class TvValues : ValueBase
{
/// <summary>
/// All values for this property
/// </summary>
public static CameraValue[] Values { get { return values.ToArray(); } }
private static List<CameraValue> values;
/// <summary>
/// The Tv <see cref="CameraValue"/> of the "Auto" setting
/// </summary>
public static readonly CameraValue Auto = new CameraValue("Auto", 0x00000000, 0, PropertyID.Tv);
/// <summary>
/// The Tv <see cref="CameraValue"/> of the "Bulb" setting
/// </summary>
public static readonly CameraValue Bulb = new CameraValue("Bulb", 0x0C, 0, PropertyID.Tv);
/// <summary>
/// The Tv <see cref="CameraValue"/> of an invalid setting
/// </summary>
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.Tv);
static TvValues()
{
values = new List<CameraValue>()
{
Auto,
Bulb,
new CameraValue("30\"", 0x10, 30, PropertyID.Tv),
new CameraValue("25\"", 0x13, 25, PropertyID.Tv),
new CameraValue("20\"", 0x14, 20, PropertyID.Tv),
new CameraValue("20\" (1/3)", 0x15, 20, PropertyID.Tv),
new CameraValue("15\"", 0x18, 15, PropertyID.Tv),
new CameraValue("13\"", 0x1B, 13, PropertyID.Tv),
new CameraValue("10\"", 0x1C, 10, PropertyID.Tv),
new CameraValue("10\" (1/3)", 0x1D, 10, PropertyID.Tv),
new CameraValue("8\"", 0x20, 8, PropertyID.Tv),
new CameraValue("6\" (1/3)", 0x23, 6, PropertyID.Tv),
new CameraValue("6\"", 0x24, 6, PropertyID.Tv),
new CameraValue("5\"", 0x25, 5, PropertyID.Tv),
new CameraValue("4\"", 0x28, 4, PropertyID.Tv),
new CameraValue("3\"2", 0x2B, 3.2, PropertyID.Tv),
new CameraValue("3\"", 0x2C, 3, PropertyID.Tv),
new CameraValue("2\"5", 0x2D, 2.5, PropertyID.Tv),
new CameraValue("2\"", 0x30, 2, PropertyID.Tv),
new CameraValue("1\"6", 0x33, 1.6, PropertyID.Tv),
new CameraValue("1\"5", 0x34, 1.5, PropertyID.Tv),
new CameraValue("1\"3", 0x35, 1.3, PropertyID.Tv),
new CameraValue("1\"", 0x38, 1, PropertyID.Tv),
new CameraValue("0\"8", 0x3B, 0.8, PropertyID.Tv),
new CameraValue("0\"7", 0x3C, 0.7, PropertyID.Tv),
new CameraValue("0\"6", 0x3D, 0.6, PropertyID.Tv),
new CameraValue("0\"5", 0x40, 0.5, PropertyID.Tv),
new CameraValue("0\"4", 0x43, 0.4, PropertyID.Tv),
new CameraValue("0\"3", 0x44, 0.3, PropertyID.Tv),
new CameraValue("0\"3 (1/3)", 0x45, 0.3, PropertyID.Tv),
new CameraValue("1/4", 0x48, 1 / 4d, PropertyID.Tv),
new CameraValue("1/5", 0x4B, 1 / 5d, PropertyID.Tv),
new CameraValue("1/6", 0x4C, 1 / 6d, PropertyID.Tv),
new CameraValue("1/6 (1/3)", 0x4D, 1 / 6d, PropertyID.Tv),
new CameraValue("1/8", 0x50, 1 / 8d, PropertyID.Tv),
new CameraValue("1/10 (1/3)", 0x53, 1 / 10d, PropertyID.Tv),
new CameraValue("1/10", 0x54, 1 / 10d, PropertyID.Tv),
new CameraValue("1/13", 0x55, 1 / 13d, PropertyID.Tv),
new CameraValue("1/15", 0x58, 1 / 15d, PropertyID.Tv),
new CameraValue("1/20 (1/3)", 0x5B, 1 / 20d, PropertyID.Tv),
new CameraValue("1/20", 0x5C, 1 / 20d, PropertyID.Tv),
new CameraValue("1/25", 0x5D, 1 / 25d, PropertyID.Tv),
new CameraValue("1/30", 0x60, 1 / 30d, PropertyID.Tv),
new CameraValue("1/40", 0x63, 1 / 40d, PropertyID.Tv),
new CameraValue("1/45", 0x64, 1 / 45d, PropertyID.Tv),
new CameraValue("1/50", 0x65, 1 / 50d, PropertyID.Tv),
new CameraValue("1/60", 0x68, 1 / 60d, PropertyID.Tv),
new CameraValue("1/80", 0x6B, 1 / 80d, PropertyID.Tv),
new CameraValue("1/90", 0x6C, 1 / 90d, PropertyID.Tv),
new CameraValue("1/100", 0x6D, 1 / 100d, PropertyID.Tv),
new CameraValue("1/125", 0x70, 1 / 125d, PropertyID.Tv),
new CameraValue("1/160", 0x73, 1 / 160d, PropertyID.Tv),
new CameraValue("1/180", 0x74, 1 / 180d, PropertyID.Tv),
new CameraValue("1/200", 0x75, 1 / 200d, PropertyID.Tv),
new CameraValue("1/250", 0x78, 1 / 150d, PropertyID.Tv),
new CameraValue("1/320", 0x7B, 1 / 320d, PropertyID.Tv),
new CameraValue("1/350", 0x7C, 1 / 350d, PropertyID.Tv),
new CameraValue("1/400", 0x7D, 1 / 400d, PropertyID.Tv),
new CameraValue("1/500", 0x80, 1 / 500d, PropertyID.Tv),
new CameraValue("1/640", 0x83, 1 / 640d, PropertyID.Tv),
new CameraValue("1/750", 0x84, 1 / 750d, PropertyID.Tv),
new CameraValue("1/800", 0x85, 1 / 800d, PropertyID.Tv),
new CameraValue("1/1000", 0x88, 1 / 1000d, PropertyID.Tv),
new CameraValue("1/1250", 0x8B, 1 / 1250d, PropertyID.Tv),
new CameraValue("1/1500", 0x8C, 1 / 1500d, PropertyID.Tv),
new CameraValue("1/1600", 0x8D, 1 / 1600d, PropertyID.Tv),
new CameraValue("1/2000", 0x90, 1 / 2000d, PropertyID.Tv),
new CameraValue("1/2500", 0x93, 1 / 2500d, PropertyID.Tv),
new CameraValue("1/3000", 0x94, 1 / 3000d, PropertyID.Tv),
new CameraValue("1/3200", 0x95, 1 / 3200d, PropertyID.Tv),
new CameraValue("1/4000", 0x98, 1 / 4000d, PropertyID.Tv),
new CameraValue("1/5000", 0x9B, 1 / 5000d, PropertyID.Tv),
new CameraValue("1/6000", 0x9C, 1 / 6000d, PropertyID.Tv),
new CameraValue("1/6400", 0x9D, 1 / 6400d, PropertyID.Tv),
new CameraValue("1/8000", 0xA0, 1 / 8000d, PropertyID.Tv),
Invalid
};
}
/// <summary>
/// Get the value from an int.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of the value to get</param>
/// <returns>The CameraValue with given int representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(int value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a string.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of value to get</param>
/// <returns>The CameraValue with given string representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(string value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a double.
/// It searches for the closest representation and therefore might not return the exact input value.
/// </summary>
/// <param name="value">The value to get</param>
/// <returns>The CameraValue with given double representation</returns>
public static CameraValue GetValue(double value)
{
return GetValue(value, values);
}
}
/// <summary>
/// Stores ISO Values and provides methods to get those values
/// </summary>
public sealed class ISOValues : ValueBase
{
/// <summary>
/// All values for this property
/// </summary>
public static CameraValue[] Values { get { return values.ToArray(); } }
private static List<CameraValue> values;
/// <summary>
/// The ISO <see cref="CameraValue"/> of the "Auto" setting
/// </summary>
public static readonly CameraValue Auto = new CameraValue("ISO Auto", 0x00000000, 0, PropertyID.ISO);
/// <summary>
/// The ISO <see cref="CameraValue"/> of an invalid setting
/// </summary>
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.ISO);
static ISOValues()
{
values = new List<CameraValue>()
{
Auto,
new CameraValue("ISO 50", 0x00000040, 50, PropertyID.ISO),
new CameraValue("ISO 100", 0x00000048, 100, PropertyID.ISO),
new CameraValue("ISO 125", 0x0000004b, 125, PropertyID.ISO),
new CameraValue("ISO 160", 0x0000004d, 160, PropertyID.ISO),
new CameraValue("ISO 200", 0x00000050, 200, PropertyID.ISO),
new CameraValue("ISO 250", 0x00000053, 250, PropertyID.ISO),
new CameraValue("ISO 320", 0x00000055, 320, PropertyID.ISO),
new CameraValue("ISO 400", 0x00000058, 400, PropertyID.ISO),
new CameraValue("ISO 500", 0x0000005b, 500, PropertyID.ISO),
new CameraValue("ISO 640", 0x0000005d, 640, PropertyID.ISO),
new CameraValue("ISO 800", 0x00000060, 800, PropertyID.ISO),
new CameraValue("ISO 1000", 0x00000063, 1000, PropertyID.ISO),
new CameraValue("ISO 1250", 0x00000065, 1250, PropertyID.ISO),
new CameraValue("ISO 1600", 0x00000068, 1600, PropertyID.ISO),
new CameraValue("ISO 2000", 0x0000006b, 2000, PropertyID.ISO),
new CameraValue("ISO 2500", 0x0000006d, 2500, PropertyID.ISO),
new CameraValue("ISO 3200", 0x00000070, 3200, PropertyID.ISO),
new CameraValue("ISO 4000", 0x00000073, 4000, PropertyID.ISO),
new CameraValue("ISO 5000", 0x00000075, 5000, PropertyID.ISO),
new CameraValue("ISO 6400", 0x00000078, 6400, PropertyID.ISO),
new CameraValue("ISO 8000", 0x0000007b, 8000, PropertyID.ISO),
new CameraValue("ISO 10000", 0x0000007d, 10000, PropertyID.ISO),
new CameraValue("ISO 12800", 0x00000080, 12800, PropertyID.ISO),
new CameraValue("ISO 16000", 0x00000083, 16000, PropertyID.ISO),
new CameraValue("ISO 20000", 0x00000085, 20000, PropertyID.ISO),
new CameraValue("ISO 25600", 0x00000088, 25600, PropertyID.ISO),
new CameraValue("ISO 51200", 0x00000090, 51200, PropertyID.ISO),
new CameraValue("ISO 102400", 0x00000098, 102400, PropertyID.ISO),
Invalid
};
}
/// <summary>
/// Get the value from an int.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of the value to get</param>
/// <returns>The CameraValue with given int representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(int value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a string.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of value to get</param>
/// <returns>The CameraValue with given string representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(string value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a double.
/// It searches for the closest representation and therefore might not return the exact input value.
/// </summary>
/// <param name="value">The value to get</param>
/// <returns>The CameraValue with given double representation</returns>
public static CameraValue GetValue(double value)
{
return GetValue(value, values);
}
}
/// <summary>
/// Stores Exposure Compensation Values and provides methods to get those values
/// </summary>
public sealed class ExpCompValues : ValueBase
{
/// <summary>
/// All values for this property
/// </summary>
public static CameraValue[] Values { get { return values.ToArray(); } }
private static List<CameraValue> values;
/// <summary>
/// The ExposureCompensation <see cref="CameraValue"/> of Zero
/// </summary>
public static readonly CameraValue Zero = new CameraValue("0", 0x00, 0, PropertyID.ExposureCompensation);
/// <summary>
/// The ExposureCompensation <see cref="CameraValue"/> of an invalid setting
/// </summary>
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.ExposureCompensation);
static ExpCompValues()
{
values = new List<CameraValue>()
{
new CameraValue("+5", 0x28, 5, PropertyID.ExposureCompensation),
new CameraValue("+4 2/3", 0x25, 4 + (2 / 3d), PropertyID.ExposureCompensation),
new CameraValue("+4 1/2", 0x24, 4 + (1 / 2d), PropertyID.ExposureCompensation),
new CameraValue("+4 1/3", 0x23, 4 + (1 / 3d), PropertyID.ExposureCompensation),
new CameraValue("+4", 0x20, 4, PropertyID.ExposureCompensation),
new CameraValue("+3 2/3", 0x1D, 3 + (2 / 3d), PropertyID.ExposureCompensation),
new CameraValue("+3 1/2", 0x1C, 3 + (1 / 2d), PropertyID.ExposureCompensation),
new CameraValue("+3 1/3", 0x1B, 3 + (1 / 3d), PropertyID.ExposureCompensation),
new CameraValue("+3", 0x18, 3, PropertyID.ExposureCompensation),
new CameraValue("+2 2/3", 0x15, 2 + (2 / 3d), PropertyID.ExposureCompensation),
new CameraValue("+2 1/2", 0x14, 2 + (1 / 2d), PropertyID.ExposureCompensation),
new CameraValue("+2 1/3", 0x13, 2 + (1 / 3d), PropertyID.ExposureCompensation),
new CameraValue("+2", 0x10, 2, PropertyID.ExposureCompensation),
new CameraValue("+1 2/3", 0x0D, 1 + (2 / 3d), PropertyID.ExposureCompensation),
new CameraValue("+1 1/2", 0x0C, 1 + (1 / 2d), PropertyID.ExposureCompensation),
new CameraValue("+1 1/3", 0x0B, 1 + (1 / 3d), PropertyID.ExposureCompensation),
new CameraValue("+1", 0x08, 1, PropertyID.ExposureCompensation),
new CameraValue("+2/3", 0x05, 2 / 3d, PropertyID.ExposureCompensation),
new CameraValue("+1/2", 0x04, 1 / 2d, PropertyID.ExposureCompensation),
new CameraValue("+1/3", 0x03, 1 / 3d, PropertyID.ExposureCompensation),
Zero,
new CameraValue("–1/3", 0xFD, -1 / 3d, PropertyID.ExposureCompensation),
new CameraValue("–1/2", 0xFC, -1 / 2d, PropertyID.ExposureCompensation),
new CameraValue("–2/3", 0xFB, -2 / 3d, PropertyID.ExposureCompensation),
new CameraValue("–1", 0xF8, -1, PropertyID.ExposureCompensation),
new CameraValue("–1 1/3", 0xF5, -1 - (1 / 3d), PropertyID.ExposureCompensation),
new CameraValue("–1 1/2", 0xF4, -1 - (1 / 2d), PropertyID.ExposureCompensation),
new CameraValue("–1 2/3", 0xF3, -1 - (2 / 3d), PropertyID.ExposureCompensation),
new CameraValue("–2", 0xF0, -2, PropertyID.ExposureCompensation),
new CameraValue("–2 1/3", 0xED, -2 - (1 / 3d), PropertyID.ExposureCompensation),
new CameraValue("–2 1/2", 0xEC, -2 - (1 / 2d), PropertyID.ExposureCompensation),
new CameraValue("–2 2/3", 0xEB, -2 - (2 / 3d), PropertyID.ExposureCompensation),
new CameraValue("–3", 0xE8, -3, PropertyID.ExposureCompensation),
new CameraValue("-3 1/3", 0xE5, -3 - (1 / 3d), PropertyID.ExposureCompensation),
new CameraValue("-3 1/2", 0xE4, -3 - (1 / 2d), PropertyID.ExposureCompensation),
new CameraValue("-3 2/3", 0xE3, -3 - (2 / 3d), PropertyID.ExposureCompensation),
new CameraValue("-4", 0xE0, -4, PropertyID.ExposureCompensation),
new CameraValue("-4 1/3", 0xDD, -4 - (1 / 3d), PropertyID.ExposureCompensation),
new CameraValue("-4 1/2", 0xDC, -4 - (1 / 2d), PropertyID.ExposureCompensation),
new CameraValue("-4 2/3", 0xDB, -4 - (2 / 3d), PropertyID.ExposureCompensation),
new CameraValue("-5", 0xD8, -5, PropertyID.ExposureCompensation),
Invalid
};
}
/// <summary>
/// Get the value from an int.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of the value to get</param>
/// <returns>The CameraValue with given int representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(int value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a string.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of value to get</param>
/// <returns>The CameraValue with given string representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(string value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a double.
/// It searches for the closest representation and therefore might not return the exact input value.
/// </summary>
/// <param name="value">The value to get</param>
/// <returns>The CameraValue with given double representation</returns>
public static CameraValue GetValue(double value)
{
return GetValue(value, values);
}
}
/// <summary>
/// Stores AE Mode Values and provides methods to get those values
/// </summary>
public sealed class AEModeValues : ValueBase
{
/// <summary>
/// All values for this property
/// </summary>
public static CameraValue[] Values { get { return values.ToArray(); } }
private static List<CameraValue> values;
#pragma warning disable 1591
public static readonly CameraValue Program = new CameraValue("Program", 0, 0, PropertyID.AEMode);
public static readonly CameraValue Tv = new CameraValue("Tv", 1, 0, PropertyID.AEMode);
public static readonly CameraValue Av = new CameraValue("Av", 2, 0, PropertyID.AEMode);
public static readonly CameraValue Manual = new CameraValue("Manual", 3, 0, PropertyID.AEMode);
public static readonly CameraValue Bulb = new CameraValue("Bulb", 4, 0, PropertyID.AEMode);
public static readonly CameraValue A_DEP = new CameraValue("A_DEP", 5, 0, PropertyID.AEMode);
public static readonly CameraValue DEP = new CameraValue("DEP", 6, 0, PropertyID.AEMode);
public static readonly CameraValue Custom = new CameraValue("Custom", 7, 0, PropertyID.AEMode);
public static readonly CameraValue Lock = new CameraValue("Lock", 8, 0, PropertyID.AEMode);
public static readonly CameraValue Green = new CameraValue("Green", 9, 0, PropertyID.AEMode);
public static readonly CameraValue NightPortrait = new CameraValue("NightPortrait", 10, 0, PropertyID.AEMode);
public static readonly CameraValue Sports = new CameraValue("Sports", 11, 0, PropertyID.AEMode);
public static readonly CameraValue Portrait = new CameraValue("Portrait", 12, 0, PropertyID.AEMode);
public static readonly CameraValue Landscape = new CameraValue("Landscape", 13, 0, PropertyID.AEMode);
public static readonly CameraValue Closeup = new CameraValue("Closeup", 14, 0, PropertyID.AEMode);
public static readonly CameraValue FlashOff = new CameraValue("FlashOff", 15, 0, PropertyID.AEMode);
public static readonly CameraValue Custom2 = new CameraValue("Custom2", 16, 0, PropertyID.AEMode);
public static readonly CameraValue Custom3 = new CameraValue("Custom3", 17, 0, PropertyID.AEMode);
public static readonly CameraValue CreativeAuto = new CameraValue("CreativeAuto", 19, 0, PropertyID.AEMode);
public static readonly CameraValue Movie = new CameraValue("Movie", 20, 0, PropertyID.AEMode);
public static readonly CameraValue PhotoInMovie = new CameraValue("PhotoInMovie", 21, 0, PropertyID.AEMode);
public static readonly CameraValue SceneIntelligentAuto = new CameraValue("SceneIntelligentAuto", 22, 0, PropertyID.AEMode);
public static readonly CameraValue Scene = new CameraValue("Scene", 25, 0, PropertyID.AEMode);
public static readonly CameraValue NightScenes = new CameraValue("NightScenes", 23, 0, PropertyID.AEMode);
public static readonly CameraValue BacklitScenes = new CameraValue("BacklitScenes", 24, 0, PropertyID.AEMode);
public static readonly CameraValue Children = new CameraValue("Children", 26, 0, PropertyID.AEMode);
public static readonly CameraValue Food = new CameraValue("Food", 27, 0, PropertyID.AEMode);
public static readonly CameraValue CandlelightPortraits = new CameraValue("CandlelightPortraits", 28, 0, PropertyID.AEMode);
public static readonly CameraValue CreativeFilter = new CameraValue("CreativeFilter", 29, 0, PropertyID.AEMode);
public static readonly CameraValue RoughMonoChrome = new CameraValue("RoughMonoChrome", 30, 0, PropertyID.AEMode);
public static readonly CameraValue SoftFocus = new CameraValue("SoftFocus", 31, 0, PropertyID.AEMode);
public static readonly CameraValue ToyCamera = new CameraValue("ToyCamera", 32, 0, PropertyID.AEMode);
public static readonly CameraValue Fisheye = new CameraValue("Fisheye", 33, 0, PropertyID.AEMode);
public static readonly CameraValue WaterColor = new CameraValue("WaterColor", 34, 0, PropertyID.AEMode);
public static readonly CameraValue Miniature = new CameraValue("Miniature", 35, 0, PropertyID.AEMode);
public static readonly CameraValue Hdr_Standard = new CameraValue("Hdr_Standard", 36, 0, PropertyID.AEMode);
public static readonly CameraValue Hdr_Vivid = new CameraValue("Hdr_Vivid", 37, 0, PropertyID.AEMode);
public static readonly CameraValue Hdr_Bold = new CameraValue("Hdr_Bold", 38, 0, PropertyID.AEMode);
public static readonly CameraValue Hdr_Embossed = new CameraValue("Hdr_Embossed", 39, 0, PropertyID.AEMode);
public static readonly CameraValue Movie_Fantasy = new CameraValue("Movie_Fantasy", 40, 0, PropertyID.AEMode);
public static readonly CameraValue Movie_Old = new CameraValue("Movie_Old", 41, 0, PropertyID.AEMode);
public static readonly CameraValue Movie_Memory = new CameraValue("Movie_Memory", 42, 0, PropertyID.AEMode);
public static readonly CameraValue Movie_DirectMono = new CameraValue("Movie_DirectMono", 43, 0, PropertyID.AEMode);
public static readonly CameraValue Movie_Mini = new CameraValue("Movie_Mini", 44, 0, PropertyID.AEMode);
public static readonly CameraValue Unknown = new CameraValue("Unknown", unchecked((int)0xFFFFFFFF), 0, PropertyID.AEMode);
#pragma warning restore 1591
static AEModeValues()
{
values = new List<CameraValue>();
values.Add(Program);
values.Add(Tv);
values.Add(Av);
values.Add(Manual);
values.Add(Bulb);
values.Add(A_DEP);
values.Add(DEP);
values.Add(Custom);
values.Add(Lock);
values.Add(Green);
values.Add(NightPortrait);
values.Add(Sports);
values.Add(Portrait);
values.Add(Landscape);
values.Add(Closeup);
values.Add(FlashOff);
values.Add(Custom2);
values.Add(Custom3);
values.Add(CreativeAuto);
values.Add(Movie);
values.Add(PhotoInMovie);
values.Add(SceneIntelligentAuto);
values.Add(Scene);
values.Add(NightScenes);
values.Add(BacklitScenes);
values.Add(Children);
values.Add(Food);
values.Add(CandlelightPortraits);
values.Add(CreativeFilter);
values.Add(RoughMonoChrome);
values.Add(SoftFocus);
values.Add(ToyCamera);
values.Add(Fisheye);
values.Add(WaterColor);
values.Add(Miniature);
values.Add(Hdr_Standard);
values.Add(Hdr_Vivid);
values.Add(Hdr_Bold);
values.Add(Hdr_Embossed);
values.Add(Movie_Fantasy);
values.Add(Movie_Old);
values.Add(Movie_Memory);
values.Add(Movie_DirectMono);
values.Add(Movie_Mini);
values.Add(Unknown);
}
/// <summary>
/// Get the value from an int.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of the value to get</param>
/// <returns>The CameraValue with given int representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(int value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a string.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of value to get</param>
/// <returns>The CameraValue with given string representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(string value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a double.
/// It searches for the closest representation and therefore might not return the exact input value.
/// </summary>
/// <param name="value">The value to get</param>
/// <returns>The CameraValue with given double representation</returns>
public static CameraValue GetValue(double value)
{
return GetValue(value, values);
}
}
/// <summary>
/// Stores Metering Mode Values and provides methods to get those values
/// </summary>
public sealed class MeteringModeValues : ValueBase
{
/// <summary>
/// All values for this property
/// </summary>
public static CameraValue[] Values { get { return values.ToArray(); } }
private static List<CameraValue> values;
#pragma warning disable 1591
public static readonly CameraValue Spot = new CameraValue("Spot", 1, 0, PropertyID.MeteringMode);
public static readonly CameraValue Evaluative = new CameraValue("Evaluative", 3, 0, PropertyID.MeteringMode);
public static readonly CameraValue Partial = new CameraValue("Partial", 4, 0, PropertyID.MeteringMode);
public static readonly CameraValue CenterWeightedAveraging = new CameraValue("Center-weighted averaging", 5, 0, PropertyID.MeteringMode);
public static readonly CameraValue NotValid = new CameraValue("Not valid", unchecked((int)0xFFFFFFFF), 0, PropertyID.MeteringMode);
#pragma warning restore 1591
static MeteringModeValues()
{
values = new List<CameraValue>();
values.Add(Spot);
values.Add(Evaluative);
values.Add(Partial);
values.Add(CenterWeightedAveraging);
values.Add(NotValid);
}
/// <summary>
/// Get the value from an int.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of the value to get</param>
/// <returns>The CameraValue with given int representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(int value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a string.
/// It has to be an exact match, otherwise an exception is thrown.
/// </summary>
/// <param name="value">The ID of value to get</param>
/// <returns>The CameraValue with given string representation</returns>
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
public static CameraValue GetValue(string value)
{
return GetValue(value, values);
}
/// <summary>
/// Get the value from a double.
/// It searches for the closest representation and therefore might not return the exact input value.
/// </summary>
/// <param name="value">The value to get</param>
/// <returns>The CameraValue with given double representation</returns>
public static CameraValue GetValue(double value)
{
return GetValue(value, values);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{29A4AE92-DECF-4EDE-849F-4295FFA48209}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>EDSDKLib</RootNamespace>
<AssemblyName>EDSDKLib</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Drawing" />
</ItemGroup>
<ItemGroup>
<Compile Include="API\Base\Camera.cs" />
<Compile Include="API\Base\CanonAPI.cs" />
<Compile Include="API\Helper\ApiThread.cs" />
<Compile Include="API\Helper\CameraValue.cs" />
<Compile Include="API\Helper\Delegates.cs" />
<Compile Include="API\Helper\ExceptionHandling.cs" />
<Compile Include="API\Helper\IO.cs" />
<Compile Include="API\Helper\STAThread.cs" />
<Compile Include="API\Helper\ValueCollections.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SDK\SDKDelegates.cs" />
<Compile Include="SDK\SDKEnums.cs" />
<Compile Include="SDK\SDKMethods.cs" />
<Compile Include="SDK\SDKStructs.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="EDSDK\EDSDK.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="EDSDK\EdsImage.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Include="EDSDK\EDSDK_API.pdf" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectView>ProjectFiles</ProjectView>
</PropertyGroup>
</Project>
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("EDSDKLib")]
[assembly: AssemblyDescription("Canon SDK wrapper library")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EDSDKLib")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("29a4ae92-decf-4ede-849f-4295ffa48209")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("5.4.2024.6120")]
[assembly: AssemblyFileVersion("5.4.2024.6120")]
using System;
namespace EOSDigital.SDK
{
/// <summary>
/// A delegate for progress.
/// </summary>
/// <param name="inPercent">The progress. A value between 0 and 100</param>
/// <param name="inContext">Reference to the object the progress is about</param>
/// <param name="outCancel">Pass true to cancel the underlying process</param>
/// <returns></returns>
public delegate ErrorCode SDKProgressCallback(int inPercent, IntPtr inContext, ref bool outCancel);
/// <summary>
/// A delegate for property events.
/// </summary>
/// <param name="inEvent">The property event ID</param>
/// <param name="inPropertyID">The property ID</param>
/// <param name="inParameter">A parameter for additional information</param>
/// <param name="inContext">A reference to the object that has sent the event</param>
/// <returns>Any of the SDK errors</returns>
public delegate ErrorCode SDKPropertyEventHandler(PropertyEventID inEvent, PropertyID inPropertyID, int inParameter, IntPtr inContext);
/// <summary>
/// A delegate for object events.
/// </summary>
/// <param name="inEvent">The object event ID</param>
/// <param name="inRef">A pointer to the object that has changed</param>
/// <param name="inContext">A reference to the object that has sent the event</param>
/// <returns>Any of the SDK errors</returns>
public delegate ErrorCode SDKObjectEventHandler(ObjectEventID inEvent, IntPtr inRef, IntPtr inContext);
/// <summary>
/// A delegate for state events.
/// </summary>
/// <param name="inEvent">The state event ID</param>
/// <param name="inParameter">A parameter for additional information</param>
/// <param name="inContext">A reference to the object that has sent the event</param>
/// <returns>Any of the SDK errors</returns>
public delegate ErrorCode SDKStateEventHandler(StateEventID inEvent, int inParameter, IntPtr inContext);
/// <summary>
/// A delegate to inform of an added camera.
/// </summary>
/// <param name="inContext">A reference to the added camera</param>
/// <returns>Any of the SDK errors</returns>
public delegate ErrorCode SDKCameraAddedHandler(IntPtr inContext);
}
//To disable all the compiler warnings about the missing documentation of enum members
#pragma warning disable 1591
namespace EOSDigital.SDK
{
/// <summary>
/// Error Codes
/// </summary>
public enum ErrorCode : int
{
/// <summary>
/// ED-SDK Function Success Code
/// </summary>
OK = 0x00000000,
#region EDSDK Error Code Masks
ISSPECIFIC_MASK = unchecked((int)0x80000000),
COMPONENTID_MASK = 0x7F000000,
RESERVED_MASK = 0x00FF0000,
ERRORID_MASK = 0x0000FFFF,
#endregion
#region EDSDK Base Component IDs
CMP_ID_CLIENT_COMPONENTID = 0x01000000,
CMP_ID_LLSDK_COMPONENTID = 0x02000000,
CMP_ID_HLSDK_COMPONENTID = 0x03000000,
#endregion
#region EDSDK Generic Error IDs
#region Miscellaneous errors
UNIMPLEMENTED = 0x00000001,
INTERNAL_ERROR = 0x00000002,
MEM_ALLOC_FAILED = 0x00000003,
MEM_FREE_FAILED = 0x00000004,
OPERATION_CANCELLED = 0x00000005,
INCOMPATIBLE_VERSION = 0x00000006,
NOT_SUPPORTED = 0x00000007,
UNEXPECTED_EXCEPTION = 0x00000008,
PROTECTION_VIOLATION = 0x00000009,
MISSING_SUBCOMPONENT = 0x0000000A,
SELECTION_UNAVAILABLE = 0x0000000B,
#endregion
#region File errors
FILE_IO_ERROR = 0x00000020,
FILE_TOO_MANY_OPEN = 0x00000021,
FILE_NOT_FOUND = 0x00000022,
FILE_OPEN_ERROR = 0x00000023,
FILE_CLOSE_ERROR = 0x00000024,
FILE_SEEK_ERROR = 0x00000025,
FILE_TELL_ERROR = 0x00000026,
FILE_READ_ERROR = 0x00000027,
FILE_WRITE_ERROR = 0x00000028,
FILE_PERMISSION_ERROR = 0x00000029,
FILE_DISK_FULL_ERROR = 0x0000002A,
FILE_ALREADY_EXISTS = 0x0000002B,
FILE_FORMAT_UNRECOGNIZED = 0x0000002C,
FILE_DATA_CORRUPT = 0x0000002D,
FILE_NAMING_NA = 0x0000002E,
#endregion
#region Directory errors
DIR_NOT_FOUND = 0x00000040,
DIR_IO_ERROR = 0x00000041,
DIR_ENTRY_NOT_FOUND = 0x00000042,
DIR_ENTRY_EXISTS = 0x00000043,
DIR_NOT_EMPTY = 0x00000044,
#endregion
#region Property errors
PROPERTIES_UNAVAILABLE = 0x00000050,
PROPERTIES_MISMATCH = 0x00000051,
PROPERTIES_NOT_LOADED = 0x00000053,
#endregion
#region Function Parameter errors
INVALID_PARAMETER = 0x00000060,
INVALID_HANDLE = 0x00000061,
INVALID_POINTER = 0x00000062,
INVALID_INDEX = 0x00000063,
INVALID_LENGTH = 0x00000064,
INVALID_FN_POINTER = 0x00000065,
INVALID_SORT_FN = 0x00000066,
#endregion
#region Device errors
DEVICE_NOT_FOUND = 0x00000080,
DEVICE_BUSY = 0x00000081,
DEVICE_INVALID = 0x00000082,
DEVICE_EMERGENCY = 0x00000083,
DEVICE_MEMORY_FULL = 0x00000084,
DEVICE_INTERNAL_ERROR = 0x00000085,
DEVICE_INVALID_PARAMETER = 0x00000086,
DEVICE_NO_DISK = 0x00000087,
DEVICE_DISK_ERROR = 0x00000088,
DEVICE_CF_GATE_CHANGED = 0x00000089,
DEVICE_DIAL_CHANGED = 0x0000008A,
DEVICE_NOT_INSTALLED = 0x0000008B,
DEVICE_STAY_AWAKE = 0x0000008C,
DEVICE_NOT_RELEASED = 0x0000008D,
#endregion
#region Stream errors
STREAM_IO_ERROR = 0x000000A0,
STREAM_NOT_OPEN = 0x000000A1,
STREAM_ALREADY_OPEN = 0x000000A2,
STREAM_OPEN_ERROR = 0x000000A3,
STREAM_CLOSE_ERROR = 0x000000A4,
STREAM_SEEK_ERROR = 0x000000A5,
STREAM_TELL_ERROR = 0x000000A6,
STREAM_READ_ERROR = 0x000000A7,
STREAM_WRITE_ERROR = 0x000000A8,
STREAM_PERMISSION_ERROR = 0x000000A9,
STREAM_COULDNT_BEGIN_THREAD = 0x000000AA,
STREAM_BAD_OPTIONS = 0x000000AB,
STREAM_END_OF_STREAM = 0x000000AC,
#endregion
#region Communications errors
COMM_PORT_IS_IN_USE = 0x000000C0,
COMM_DISCONNECTED = 0x000000C1,
COMM_DEVICE_INCOMPATIBLE = 0x000000C2,
COMM_BUFFER_FULL = 0x000000C3,
COMM_USB_BUS_ERR = 0x000000C4,
#endregion
#region Lock/Unlock
USB_DEVICE_LOCK_ERROR = 0x000000D0,
USB_DEVICE_UNLOCK_ERROR = 0x000000D1,
#endregion
#region STI/WIA
STI_UNKNOWN_ERROR = 0x000000E0,
STI_INTERNAL_ERROR = 0x000000E1,
STI_DEVICE_CREATE_ERROR = 0x000000E2,
STI_DEVICE_RELEASE_ERROR = 0x000000E3,
DEVICE_NOT_LAUNCHED = 0x000000E4,
ENUM_NA = 0x000000F0,
INVALID_FN_CALL = 0x000000F1,
HANDLE_NOT_FOUND = 0x000000F2,
INVALID_ID = 0x000000F3,
WAIT_TIMEOUT_ERROR = 0x000000F4,
#endregion
#region PTP
SESSION_NOT_OPEN = 0x00002003,
INVALID_TRANSACTIONID = 0x00002004,
INCOMPLETE_TRANSFER = 0x00002007,
INVALID_STRAGEID = 0x00002008,
DEVICEPROP_NOT_SUPPORTED = 0x0000200A,
INVALID_OBJECTFORMATCODE = 0x0000200B,
SELF_TEST_FAILED = 0x00002011,
PARTIAL_DELETION = 0x00002012,
SPECIFICATION_BY_FORMAT_UNSUPPORTED = 0x00002014,
NO_VALID_OBJECTINFO = 0x00002015,
INVALID_CODE_FORMAT = 0x00002016,
UNKNOWN_VENDOR_CODE = 0x00002017,
CAPTURE_ALREADY_TERMINATED = 0x00002018,
INVALID_PARENTOBJECT = 0x0000201A,
INVALID_DEVICEPROP_FORMAT = 0x0000201B,
INVALID_DEVICEPROP_VALUE = 0x0000201C,
SESSION_ALREADY_OPEN = 0x0000201E,
TRANSACTION_CANCELLED = 0x0000201F,
SPECIFICATION_OF_DESTINATION_UNSUPPORTED = 0x00002020,
NOT_CAMERA_SUPPORT_SDK_VERSION = 0x00002021,
#endregion
#region PTP Vendor
UNKNOWN_COMMAND = 0x0000A001,
OPERATION_REFUSED = 0x0000A005,
LENS_COVER_CLOSE = 0x0000A006,
LOW_BATTERY = 0x0000A101,
OBJECT_NOTREADY = 0x0000A102,
CANNOT_MAKE_OBJECT = 0x0000A104,
MEMORYSTATUS_NOTREADY = 0x0000A106,
#endregion
#region Take Picture errors
TAKE_PICTURE_AF_NG = 0x00008D01,
TAKE_PICTURE_RESERVED = 0x00008D02,
TAKE_PICTURE_MIRROR_UP_NG = 0x00008D03,
TAKE_PICTURE_SENSOR_CLEANING_NG = 0x00008D04,
TAKE_PICTURE_SILENCE_NG = 0x00008D05,
TAKE_PICTURE_NO_CARD_NG = 0x00008D06,
TAKE_PICTURE_CARD_NG = 0x00008D07,
TAKE_PICTURE_CARD_PROTECT_NG = 0x00008D08,
TAKE_PICTURE_MOVIE_CROP_NG = 0x00008D09,
TAKE_PICTURE_STROBO_CHARGE_NG = 0x00008D0A,
TAKE_PICTURE_NO_LENS_NG = 0x00008D0B,
TAKE_PICTURE_SPECIAL_MOVIE_MODE_NG = 0x00008D0C,
TAKE_PICTURE_LV_REL_PROHIBIT_MODE_NG = 0x00008D0D,
#endregion
LAST_GENERIC_ERROR_PLUS_ONE = 0x000000F5,
#endregion
}
/// <summary>
/// SDK Data Types
/// </summary>
public enum DataType : int
{
Unknown = 0,
Bool = 1,
String = 2,
Int8 = 3,
UInt8 = 6,
Int16 = 4,
UInt16 = 7,
Int32 = 8,
UInt32 = 9,
Int64 = 10,
UInt64 = 11,
Float = 12,
Double = 13,
ByteBlock = 14,
Rational = 20,
Point = 21,
Rect = 22,
Time = 23,
Bool_Array = 30,
Int8_Array = 31,
Int16_Array = 32,
Int32_Array = 33,
UInt8_Array = 34,
UInt16_Array = 35,
UInt32_Array = 36,
Rational_Array = 37,
FocusInfo = 101,
PictureStyleDesc = 102,
}
/// <summary>
/// Property IDs
/// </summary>
public enum PropertyID : int
{
Unknown = 0x0000FFFF,
ProductName = 0x00000002,
OwnerName = 0x00000004,
MakerName = 0x00000005,
DateTime = 0x00000006,
FirmwareVersion = 0x00000007,
BatteryLevel = 0x00000008,
CFn = 0x00000009,
SaveTo = 0x0000000b,
CurrentStorage = 0x0000000c,
CurrentFolder = 0x0000000d,
MyMenu = 0x0000000e,
BatteryQuality = 0x00000010,
BodyIDEx = 0x00000015,
HDDirectoryStructure = 0x00000020,
//Image Properties
ImageQuality = 0x00000100,
JpegQuality = 0x00000101,
Orientation = 0x00000102,
ICCProfile = 0x00000103,
FocusInfo = 0x00000104,
DigitalExposure = 0x00000105,
WhiteBalance = 0x00000106,
ColorTemperature = 0x00000107,
WhiteBalanceShift = 0x00000108,
Contrast = 0x00000109,
ColorSaturation = 0x0000010a,
ColorTone = 0x0000010b,
Sharpness = 0x0000010c,
ColorSpace = 0x0000010d,
ToneCurve = 0x0000010e,
PhotoEffect = 0x0000010f,
FilterEffect = 0x00000110,
ToningEffect = 0x00000111,
ParameterSet = 0x00000112,
ColorMatrix = 0x00000113,
PictureStyle = 0x00000114,
PictureStyleDesc = 0x00000115,
PictureStyleCaption = 0x00000200,
//Image Processing Properties
Linear = 0x00000300,
ClickWBPoint = 0x00000301,
WBCoeffs = 0x00000302,
//Image GPS Properties
GPSVersionID = 0x00000800,
GPSLatitudeRef = 0x00000801,
GPSLatitude = 0x00000802,
GPSLongitudeRef = 0x00000803,
GPSLongitude = 0x00000804,
GPSAltitudeRef = 0x00000805,
GPSAltitude = 0x00000806,
GPSTimeStamp = 0x00000807,
GPSSatellites = 0x00000808,
GPSStatus = 0x00000809,
GPSMapDatum = 0x00000812,
GPSDateStamp = 0x0000081D,
//Property Mask
AtCapture_Flag = unchecked((int)0x80000000),
//Capture Properties
AEMode = 0x00000400,
DriveMode = 0x00000401,
ISO = 0x00000402,
MeteringMode = 0x00000403,
AFMode = 0x00000404,
Av = 0x00000405,
Tv = 0x00000406,
ExposureCompensation = 0x00000407,
FlashCompensation = 0x00000408,
FocalLength = 0x00000409,
AvailableShots = 0x0000040a,
Bracket = 0x0000040b,
WhiteBalanceBracket = 0x0000040c,
LensName = 0x0000040d,
AEBracket = 0x0000040e,
FEBracket = 0x0000040f,
ISOBracket = 0x00000410,
NoiseReduction = 0x00000411,
FlashOn = 0x00000412,
RedEye = 0x00000413,
FlashMode = 0x00000414,
LensStatus = 0x00000416,
Artist = 0x00000418,
Copyright = 0x00000419,
DepthOfField = 0x0000041b,
EFCompensation = 0x0000041e,
AEModeSelect = 0x00000436,
//EVF Properties
Evf_OutputDevice = 0x00000500,
Evf_Mode = 0x00000501,
Evf_WhiteBalance = 0x00000502,
Evf_ColorTemperature = 0x00000503,
Evf_DepthOfFieldPreview = 0x00000504,
//EVF IMAGE DATA Properties
Evf_Zoom = 0x00000507,
Evf_ZoomPosition = 0x00000508,
Evf_FocusAid = 0x00000509,
Evf_ImagePosition = 0x0000050B,
Evf_HistogramStatus = 0x0000050C,
Evf_AFMode = 0x0000050E,
Record = 0x00000510,
Evf_HistogramY = 0x00000515,
Evf_HistogramR = 0x00000516,
Evf_HistogramG = 0x00000517,
Evf_HistogramB = 0x00000518,
Evf_CoordinateSystem = 0x00000540,
Evf_ZoomRect = 0x00000541,
Evf_ImageClipRect = 0x00000545,
}
/// <summary>
/// MyMenu IDs
/// </summary>
public enum MyMenuID : int
{
Quality = 11,
RedEye = 12,
Beep = 8,
Shoot_WO_Card = 9,
ReviewTime = 7,
AEB = 13,
Whitebalance = 0,
CustomWB = 15,
WBShift_BKT = 2,
Colorspace = 3,
PictureStyle = 4,
DustDeleteData = 10,
ProtectImages = 65536,
Rotate = 65537,
EraseImages = 65538,
PrintOrder = 65539,
TransferOrder = 65540,
HighlightAlert = 65543,
AFPointDisplay = 65544,
Histogram = 65545,
AutoPlay = 65548,
AutoPowerOff = 131072,
FileNumbering = 131074,
AutoRotate = 131076,
InfoButton = 131091,
Format = 131093,
LCDBrigthness = 131078,
DateTime = 131079,
Language = 131080,
Videosystem = 131081,
SensorCleaning = 131088,
LiveViewFunctionSettings = 131083,
FlashControl = 131094,
CameraUserSettings = 131095,
ClearAllCameraSettings = 131087,
FirmwareVersion = 131089,
CFnI_Exposure = 196608,
CFnII_Image = 196614,
CFn_III_AutoFocus_Drive = 196610,
CFnIV_Operation_Others196611,
ClearAllCFn = 196612,
ExposureLevelIncrements = 262144,
ISOSpeedSettingsIncrements = 262145,
ISOExpansion = 262159,
BracketingAutoCancel = 262147,
BracketingSequence = 262148,
SafetyShift = 262151,
FlashSyncSpeenInAvMode = 262158,
LongExpNoiseReduction = 327680,
HighISOSpeedNoiseReduction = 327681,
HighlightTonePriority = 327682,
LensDriveWhenAFImpossible = 393220,
LensAFStopButtonFunction = 393221,
AFPointSelectionMethod = 393235,
SuperimposedDisplay393236,
AFAssistBeamFiring = 393229,
AFDuringLiveViewShooting = 393233,
MirrorLockup = 393230,
ShutterButton_AFONButton = 458752,
AFON_AELockButtonSwitch = 458753,
SetButtonWhenShooting = 458755,
DialDirectionDuringTv_Av = 458757,
FocusingScreen = 458762,
AddOriginalDecisionData = 458766,
LiveViewExposureSimulation = 458767,
NotSet = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Camera Commands
/// </summary>
public enum CameraCommand : int
{
TakePicture = 0x00000000,
ExtendShutDownTimer = 0x00000001,
BulbStart = 0x00000002,
BulbEnd = 0x00000003,
PressShutterButton = 0x00000004,
DoEvfAf = 0x00000102,
DriveLensEvf = 0x00000103,
DoClickWBEvf = 0x00000104,
}
/// <summary>
/// Shutter Button State
/// </summary>
public enum ShutterButton : int
{
OFF = 0x00000000,
Halfway = 0x00000001,
Completely = 0x00000003,
Halfway_NonAF = 0x00010001,
Completely_NonAF = 0x00010003,
}
/// <summary>
/// Camera Status
/// </summary>
public enum CameraStatusCommand : int
{
UILock = 0x00000000,
UIUnLock = 0x00000001,
EnterDirectTransfer = 0x00000002,
ExitDirectTransfer = 0x00000003,
}
/// <summary>
/// Property Event IDs
/// </summary>
public enum PropertyEventID : int
{
/// <summary>
/// Notifies all property events.
/// </summary>
All = 0x00000100,
/// <summary>
/// Notifies that a camera property value has been changed.
/// The changed property can be retrieved from event data.
/// The changed value can be retrieved by means of EdsGetPropertyData.
/// In the case of type 1 protocol standard cameras,
/// notification of changed properties can only be issued for custom functions (CFn).
/// If the property type is 0x0000FFFF, the changed property cannot be identified.
/// Thus, retrieve all required properties repeatedly.
/// </summary>
PropertyChanged = 0x00000101,
/// <summary>
/// Notifies of changes in the list of camera properties with configurable values.
/// The list of configurable values for property IDs indicated in event data
/// can be retrieved by means of EdsGetPropertyDesc.
/// For type 1 protocol standard cameras, the property ID is identified as "Unknown"
/// during notification.
/// Thus, you must retrieve a list of configurable values for all properties and
/// retrieve the property values repeatedly.
/// (For details on properties for which you can retrieve a list of configurable
/// properties, see the description of EdsGetPropertyDesc).
/// </summary>
PropertyDescChanged = 0x00000102,
}
/// <summary>
/// Object Event IDs
/// </summary>
public enum ObjectEventID : int
{
/// <summary>
/// Notifies all object events.
/// </summary>
All = 0x00000200,
/// <summary>
/// Notifies that the volume object (memory card) state (VolumeInfo)
/// has been changed.
/// Changed objects are indicated by event data.
/// The changed value can be retrieved by means of EdsGetVolumeInfo.
/// Notification of this event is not issued for type 1 protocol standard cameras.
/// </summary>
VolumeInfoChanged = 0x00000201,
/// <summary>
/// Notifies if the designated volume on a camera has been formatted.
/// If notification of this event is received, get sub-items of the designated
/// volume again as needed.
/// Changed volume objects can be retrieved from event data.
/// Objects cannot be identified on cameras earlier than the D30
/// if files are added or deleted.
/// Thus, these events are subject to notification.
/// </summary>
VolumeUpdateItems = 0x00000202,
/// <summary>
/// Notifies if many images are deleted in a designated folder on a camera.
/// If notification of this event is received, get sub-items of the designated
/// folder again as needed.
/// Changed folders (specifically, directory item objects) can be retrieved
/// from event data.
/// </summary>
FolderUpdateItems = 0x00000203,
/// <summary>
/// Notifies of the creation of objects such as new folders or files
/// on a camera compact flash card or the like.
/// This event is generated if the camera has been set to store captured
/// images simultaneously on the camera and a computer,
/// for example, but not if the camera is set to store images
/// on the computer alone.
/// Newly created objects are indicated by event data.
/// Because objects are not indicated for type 1 protocol standard cameras,
/// (that is, objects are indicated as NULL),
/// you must again retrieve child objects under the camera object to
/// identify the new objects.
/// </summary>
DirItemCreated = 0x00000204,
/// <summary>
/// Notifies of the deletion of objects such as folders or files on a camera
/// compact flash card or the like.
/// Deleted objects are indicated in event data.
/// Because objects are not indicated for type 1 protocol standard cameras,
/// you must again retrieve child objects under the camera object to
/// identify deleted objects.
/// </summary>
DirItemRemoved = 0x00000205,
/// <summary>
/// Notifies that information of DirItem objects has been changed.
/// Changed objects are indicated by event data.
/// The changed value can be retrieved by means of EdsGetDirectoryItemInfo.
/// Notification of this event is not issued for type 1 protocol standard cameras.
/// </summary>
DirItemInfoChanged = 0x00000206,
/// <summary>
/// Notifies that header information has been updated, as for rotation information
/// of image files on the camera.
/// If this event is received, get the file header information again, as needed.
/// This function is for type 2 protocol standard cameras only.
/// </summary>
DirItemContentChanged = 0x00000207,
/// <summary>
/// Notifies that there are objects on a camera to be transferred to a computer.
/// This event is generated after remote release from a computer or local release
/// from a camera.
/// If this event is received, objects indicated in the event data must be downloaded.
/// Furthermore, if the application does not require the objects, instead
/// of downloading them,
/// execute EdsDownloadCancel and release resources held by the camera.
/// The order of downloading from type 1 protocol standard cameras must be the order
/// in which the events are received.
/// </summary>
DirItemRequestTransfer = 0x00000208,
/// <summary>
/// Notifies if the camera's direct transfer button is pressed.
/// If this event is received, objects indicated in the event data must be downloaded.
/// Furthermore, if the application does not require the objects, instead of
/// downloading them,
/// execute EdsDownloadCancel and release resources held by the camera.
/// Notification of this event is not issued for type 1 protocol standard cameras.
/// </summary>
DirItemRequestTransferDT = 0x00000209,
/// <summary>
/// Notifies of requests from a camera to cancel object transfer
/// if the button to cancel direct transfer is pressed on the camera.
/// If the parameter is 0, it means that cancellation of transfer is requested for
/// objects still not downloaded,
/// with these objects indicated by kEdsObjectEvent_DirItemRequestTransferDT.
/// Notification of this event is not issued for type 1 protocol standard cameras.
/// </summary>
DirItemCancelTransferDT = 0x0000020A,
VolumeAdded = 0x0000020C,
VolumeRemoved = 0x0000020D,
}
/// <summary>
/// State Event IDs
/// </summary>
public enum StateEventID : int
{
/// <summary>
/// Notifies all state events.
/// </summary>
All = 0x00000300,
/// <summary>
/// Indicates that a camera is no longer connected to a computer,
/// whether it was disconnected by unplugging a cord, opening
/// the compact flash compartment,
/// turning the camera off, auto shut-off, or by other means.
/// </summary>
Shutdown = 0x00000301,
/// <summary>
/// Notifies of whether or not there are objects waiting to
/// be transferred to a host computer.
/// This is useful when ensuring all shot images have been transferred
/// when the application is closed.
/// Notification of this event is not issued for type 1 protocol
/// standard cameras.
/// </summary>
JobStatusChanged = 0x00000302,
/// <summary>
/// Notifies that the camera will shut down after a specific period.
/// Generated only if auto shut-off is set.
/// Exactly when notification is issued (that is, the number of
/// seconds until shutdown) varies depending on the camera model.
/// To continue operation without having the camera shut down,
/// use EdsSendCommand to extend the auto shut-off timer.
/// The time in seconds until the camera shuts down is returned
/// as the initial value.
/// </summary>
WillSoonShutDown = 0x00000303,
/// <summary>
/// As the counterpart event to kEdsStateEvent_WillSoonShutDown,
/// this event notifies of updates to the number of seconds until
/// a camera shuts down.
/// After the update, the period until shutdown is model-dependent.
/// </summary>
ShutDownTimerUpdate = 0x00000304,
/// <summary>
/// Notifies that a requested release has failed, due to focus
/// failure or similar factors.
/// </summary>
CaptureError = 0x00000305,
/// <summary>
/// Notifies of internal SDK errors.
/// If this error event is received, the issuing device will probably
/// not be able to continue working properly,
/// so cancel the remote connection.
/// </summary>
InternalError = 0x00000306,
/// <summary>
/// The autofocus is done working.
/// </summary>
AfResult = 0x00000309,
/// <summary>
/// The bulb exposure time has changed.
/// </summary>
BulbExposureTime = 0x00000310,
}
/// <summary>
/// Drive Lens
/// </summary>
public enum DriveLens : int
{
Near1 = 0x00000001,
Near2 = 0x00000002,
Near3 = 0x00000003,
Far1 = 0x00008001,
Far2 = 0x00008002,
Far3 = 0x00008003,
}
/// <summary>
/// Seek Origin
/// </summary>
public enum SeekOrigin : int
{
Current = 0,
Begin = 1,
End = 2,
}
/// <summary>
/// File Access
/// </summary>
public enum FileAccess : int
{
Read = 0,
Write = 1,
ReadWrite = 2,
Error = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// File-creation Disposition
/// </summary>
public enum FileCreateDisposition : int
{
/// <summary>
/// Creates a new file. An error occurs if the designated file already exists
/// </summary>
CreateNew = 0,
/// <summary>
/// Creates a new file. If the designated file already
/// exists, that file is overwritten and existing attributes
/// </summary>
CreateAlways = 1,
/// <summary>
/// Opens a file. An error occurs if the designated file does not exist.
/// </summary>
OpenExisting = 2,
/// <summary>
/// If the file exists, it is opened. If the designated file
/// does not exist, a new file is created.
/// </summary>
OpenAlways = 3,
/// <summary>
/// Opens a file and sets the file size to 0 bytes.
/// </summary>
TruncateExisting = 4,
}
/// <summary>
/// Image Type
/// </summary>
public enum ImageType : int
{
Unknown = 0x00000000,
Jpeg = 0x00000001,
CRW = 0x00000002,
RAW = 0x00000004,
CR2 = 0x00000006,
}
/// <summary>
/// Image Size
/// </summary>
public enum ImageSize : int
{
Large = 0,
Middle = 1,
Small = 2,
Middle1 = 5,
Middle2 = 6,
Small1 = 14,
Small2 = 15,
Small3 = 16,
Unknown = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Compression Quality
/// </summary>
public enum CompressQuality : int
{
Normal = 2,
Fine = 3,
Lossless = 4,
SuperFine = 5,
Unknown = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Image Quality
/// </summary>
public enum ImageQuality : int
{
/// <summary>
/// Jpeg Large
/// </summary>
LargeJpeg = 0x0010FF0F,
/// <summary>
/// Jpeg Middle1
/// </summary>
Middle1Jpeg = 0x0510FF0F,
/// <summary>
/// Jpeg Middle2
/// </summary>
Middle2Jpeg = 0x0610FF0F,
/// <summary>
/// Jpeg Small
/// </summary>
SmallJpeg = 0x0210FF0F,
/// <summary>
/// Jpeg Small2
/// </summary>
Small2Jpeg = 0x0F13FF0F,
/// <summary>
/// Jpeg Small3
/// </summary>
Small3Jpeg = 0x1013FF0F,
/// <summary>
/// Jpeg Large Fine
/// </summary>
LargeJpegFine = 0x0013FF0F,
/// <summary>
/// Jpeg Large Normal
/// </summary>
LargeJpegNormal = 0x0012FF0F,
/// <summary>
/// Jpeg Middle Fine
/// </summary>
MiddleJpegFine = 0x0113FF0F,
/// <summary>
/// Jpeg Middle Normal
/// </summary>
MiddleJpegNormal = 0x0112FF0F,
/// <summary>
/// Jpeg Small Fine
/// </summary>
SmallJpegFine = 0x0213FF0F,
/// <summary>
/// Jpeg Small Normal
/// </summary>
SmallJpegNormal = 0x0212FF0F,
/// <summary>
/// Jpeg Small1 Fine
/// </summary>
Small1JpegFine = 0x0E13FF0F,
/// <summary>
/// Jpeg Small1 Normal
/// </summary>
Small1JpegNormal = 0x0E12FF0F,
/// <summary>
/// RAW
/// </summary>
RAW = 0x0064FF0F,
/// <summary>
/// RAW + Jpeg Large Fine
/// </summary>
RAW_LargeJpegFine = 0x00640013,
/// <summary>
/// RAW + Jpeg Large Normal
/// </summary>
RAW_LargeJpegNormal = 0x00640012,
/// <summary>
/// RAW + Jpeg Middle Fine
/// </summary>
RAW_MiddleJpegFine = 0x00640113,
/// <summary>
/// RAW + Jpeg Middle Normal
/// </summary>
RAW_MiddleJpegNormal = 0x00640112,
/// <summary>
/// RAW + Jpeg Small Fine
/// </summary>
RAW_SmallJpegFine = 0x00640213,
/// <summary>
/// RAW + Jpeg Small Normal
/// </summary>
RAW_SmallJpegNormal = 0x00640212,
/// <summary>
/// RAW + Jpeg Small1 Fine
/// </summary>
RAW_Small1JpegFine = 0x00640E13,
/// <summary>
/// RAW + Jpeg Small1 Normal
/// </summary>
RAW_Small1JpegNormal = 0x00640E12,
/// <summary>
/// RAW + Jpeg Small2
/// </summary>
RAW_Small2Jpeg = 0x00640F13,
/// <summary>
/// RAW + Jpeg Small3
/// </summary>
RAW_Small3Jpeg = 0x00641013,
/// <summary>
/// RAW + Jpeg Large
/// </summary>
RAW_LargeJpeg = 0x00640010,
/// <summary>
/// RAW + Jpeg Middle1
/// </summary>
RAW_Middle1Jpeg = 0x00640510,
/// <summary>
/// RAW + Jpeg Middle2
/// </summary>
RAW_Middle2Jpeg = 0x00640610,
/// <summary>
/// RAW + Jpeg Small
/// </summary>
RAW_SmallJpeg = 0x00640210,
/// <summary>
/// MRAW(SRAW1)
/// </summary>
MRAW = 0x0164FF0F,
/// <summary>
/// MRAW(SRAW1) + Jpeg Large Fine
/// </summary>
MRAW_LargeJpegFine = 0x01640013,
/// <summary>
/// MRAW(SRAW1) + Jpeg Large Normal
/// </summary>
MRAW_LargeJpegNormal = 0x01640012,
/// <summary>
/// MRAW(SRAW1) + Jpeg Middle Fine
/// </summary>
MRAW_MiddleJpegFine = 0x01640113,
/// <summary>
/// MRAW(SRAW1) + Jpeg Middle Normal
/// </summary>
MRAW_MiddleJpegNormal = 0x01640112,
/// <summary>
/// MRAW(SRAW1) + Jpeg Small Fine
/// </summary>
MRAW_SmallJpegFine = 0x01640213,
/// <summary>
/// MRAW(SRAW1) + Jpeg Small Normal
/// </summary>
MRAW_SmallJpegNormal = 0x01640212,
/// <summary>
/// MRAW(SRAW1) + Jpeg Small1 Fine
/// </summary>
MRAW_Small1JpegFine = 0x01640E13,
/// <summary>
/// MRAW(SRAW1) + Jpeg Small1 Normal
/// </summary>
MRAW_Small1JpegNormal = 0x01640E12,
/// <summary>
/// MRAW(SRAW1) + Jpeg Small2
/// </summary>
MRAW_Small2Jpeg = 0x01640F13,
/// <summary>
/// MRAW(SRAW1) + Jpeg Small3
/// </summary>
MRAW_Small3Jpeg = 0x01641013,
/// <summary>
/// MRAW(SRAW1) + Jpeg Large
/// </summary>
MRAW_LargeJpeg = 0x01640010,
/// <summary>
/// MRAW(SRAW1) + Jpeg Middle1
/// </summary>
MRAW_Middle1Jpeg = 0x01640510,
/// <summary>
/// MRAW(SRAW1) + Jpeg Middle2
/// </summary>
MRAW_Middle2Jpeg = 0x01640610,
/// <summary>
/// MRAW(SRAW1) + Jpeg Small
/// </summary>
MRAW_SmallJpeg = 0x01640210,
/// <summary>
/// SRAW(SRAW2)
/// </summary>
SRAW = 0x0264FF0F,
/// <summary>
/// SRAW(SRAW2) + Jpeg Large Fine
/// </summary>
SRAW_LargeJpegFine = 0x02640013,
/// <summary>
/// SRAW(SRAW2) + Jpeg Large Normal
/// </summary>
SRAW_LargeJpegNormal = 0x02640012,
/// <summary>
/// SRAW(SRAW2) + Jpeg Middle Fine
/// </summary>
SRAW_MiddleJpegFine = 0x02640113,
/// <summary>
/// SRAW(SRAW2) + Jpeg Middle Normal
/// </summary>
SRAW_MiddleJpegNormal = 0x02640112,
/// <summary>
/// SRAW(SRAW2) + Jpeg Small Fine
/// </summary>
SRAW_SmallJpegFine = 0x02640213,
/// <summary>
/// SRAW(SRAW2) + Jpeg Small Normal
/// </summary>
SRAW_SmallJpegNormal = 0x02640212,
/// <summary>
/// SRAW(SRAW2) + Jpeg Small1 Fine
/// </summary>
SRAW_Small1JpegFine = 0x02640E13,
/// <summary>
/// SRAW(SRAW2) + Jpeg Small1 Normal
/// </summary>
SRAW_Small1JpegNormal = 0x02640E12,
/// <summary>
/// SRAW(SRAW2) + Jpeg Small2
/// </summary>
SRAW_Small2Jpeg = 0x02640F13,
/// <summary>
/// SRAW(SRAW2) + Jpeg Small3
/// </summary>
SRAW_Small3Jpeg = 0x02641013,
/// <summary>
/// SRAW(SRAW2) + Jpeg Large
/// </summary>
SRAW_LargeJpeg = 0x02640010,
/// <summary>
/// SRAW(SRAW2) + Jpeg Middle1
/// </summary>
SRAW_Middle1Jpeg = 0x02640510,
/// <summary>
/// SRAW(SRAW2) + Jpeg Middle2
/// </summary>
SRAW_Middle2Jpeg = 0x02640610,
/// <summary>
/// SRAW(SRAW2) + Jpeg Small
/// </summary>
SRAW_SmallJpeg = 0x02640210,
Unknown = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Image Quality for Legacy Cameras
/// </summary>
public enum ImageQualityLegacy : int
{
/// <summary>
/// Jpeg Large
/// </summary>
LJ = 0x001F000F,
/// <summary>
/// Jpeg Middle1
/// </summary>
M1J = 0x051F000F,
/// <summary>
/// Jpeg Middle2
/// </summary>
M2J = 0x061F000F,
/// <summary>
/// Jpeg Small
/// </summary>
SJ = 0x021F000F,
/// <summary>
/// Jpeg Large Fine
/// </summary>
LJF = 0x00130000,
/// <summary>
/// Jpeg Large Normal
/// </summary>
LJN = 0x00120000,
/// <summary>
/// Jpeg Middle Fine
/// </summary>
MJF = 0x01130000,
/// <summary>
/// Jpeg Middle Normal
/// </summary>
MJN = 0x01120000,
/// <summary>
/// Jpeg Small Fine
/// </summary>
SJF = 0x02130000,
/// <summary>
/// Jpeg Small Normal
/// </summary>
SJN = 0x02120000,
/// <summary>
/// RAW
/// </summary>
LR = 0x00240000,
/// <summary>
/// RAW + Jpeg Large Fine
/// </summary>
LRLJF = 0x00240013,
/// <summary>
/// RAW + Jpeg Large Normal
/// </summary>
LRLJN = 0x00240012,
/// <summary>
/// RAW + Jpeg Middle Fine
/// </summary>
LRMJF = 0x00240113,
/// <summary>
/// RAW + Jpeg Middle Normal
/// </summary>
LRMJN = 0x00240112,
/// <summary>
/// RAW + Jpeg Small Fine
/// </summary>
LRSJF = 0x00240213,
/// <summary>
/// RAW + Jpeg Small Normal
/// </summary>
LRSJN = 0x00240212,
/// <summary>
/// RAW
/// </summary>
LR2 = 0x002F000F,
/// <summary>
/// RAW + Jpeg Large
/// </summary>
LR2LJ = 0x002F001F,
/// <summary>
/// RAW + Jpeg Middle1
/// </summary>
LR2M1J = 0x002F051F,
/// <summary>
/// RAW + Jpeg Middle2
/// </summary>
LR2M2J = 0x002F061F,
/// <summary>
/// RAW + Jpeg Small
/// </summary>
LR2SJ = 0x002F021F,
Unknown = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Image Source
/// </summary>
public enum ImageSource : int
{
FullView = 0,
Thumbnail = 1,
Preview = 2,
RAWThumbnail = 3,
RAWFullView = 4,
}
/// <summary>
/// Target Image Type
/// </summary>
public enum TargetImageType : int
{
Unknown = 0x00000000,
Jpeg = 0x00000001,
TIFF = 0x00000007,
TIFF16 = 0x00000008,
RGB = 0x00000009,
RGB16 = 0x0000000A,
DIB = 0x0000000B,
}
/// <summary>
/// Progress Option
/// </summary>
public enum ProgressOption : int
{
NoReport = 0,
Done = 1,
Periodically = 2,
}
/// <summary>
/// File Attribute
/// </summary>
public enum FileAttribute : int
{
Normal = 0x00000000,
ReadOnly = 0x00000001,
Hidden = 0x00000002,
System = 0x00000004,
Archive = 0x00000020,
}
/// <summary>
/// Battery Level
/// </summary>
public enum BatteryQuality : int
{
Empty = 0,
Low = 9,
Half = 49,
Normal = 80,
High = 69,
Quarter = 19,
//Error = 0,
//BCLevel = 0,
AC = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Save to Device
/// </summary>
public enum SaveTo : int
{
Camera = 1,
Host = 2,
Both = 3,
}
/// <summary>
/// Storage Type
/// </summary>
public enum StorageType : int
{
None = 0,
CF = 1,
SD = 2,
HD = 4,
CFast = 5,
}
/// <summary>
/// Whitebalance
/// </summary>
public enum WhiteBalance : int
{
Pasted = -2,
Click = -1,
Auto = 0,
Daylight = 1,
Cloudy = 2,
Tangsten = 3,
Fluorescent = 4,
Strobe = 5,
WhitePaper = 6,
Shade = 8,
ColorTemperature = 9,
PCSet1 = 10,
PCSet2 = 11,
PCSet3 = 12,
WhitePaper2 = 15,
WhitePaper3 = 16,
WhitePaper4 = 18,
WhitePaper5 = 19,
PCSet4 = 20,
PCSet5 = 21,
}
/// <summary>
/// Photo Effect
/// </summary>
public enum PhotoEffect : int
{
Off = 0,
Monochrome = 5,
}
/// <summary>
/// Color Matrix
/// </summary>
public enum ColorMatrix : int
{
Custom = 0,
ColorMatrix1 = 1,
ColorMatrix2 = 2,
ColorMatrix3 = 3,
ColorMatrix4 = 4,
ColorMatrix5 = 5,
ColorMatrix6 = 6,
ColorMatrix7 = 7,
}
/// <summary>
/// Filter Effect
/// </summary>
public enum FilterEffect : int
{
None = 0,
Yellow = 1,
Orange = 2,
Red = 3,
Green = 4,
}
/// <summary>
/// Toning Effect
/// </summary>
public enum ToningEffect : int
{
None = 0,
Sepia = 1,
Blue = 2,
Purple = 3,
Green = 4,
}
/// <summary>
/// Color Space
/// </summary>
public enum ColorSpace : int
{
sRGB = 1,
AdobeRGB = 2,
Unknown = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Picture Style
/// </summary>
public enum PictureStyle : int
{
Standard = 0x0081,
Portrait = 0x0082,
Landscape = 0x0083,
Neutral = 0x0084,
Faithful = 0x0085,
Monochrome = 0x0086,
Auto = 0x0087,
User1 = 0x0021,
User2 = 0x0022,
User3 = 0x0023,
PC1 = 0x0041,
PC2 = 0x0042,
PC3 = 0x0043,
}
/// <summary>
/// Transfer Option
/// </summary>
public enum TransferOption : int
{
ByDirectTransfer = 1,
ByRelease = 2,
ToDesktop = 0x00000100,
}
/// <summary>
/// Bracketing Mode
/// </summary>
public enum BracketMode : int
{
Exposure = 0x01,
ISO = 0x02,
Whitebalance = 0x04,
FlashExposure = 0x08,
Unknown = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Liveview Output Device
/// </summary>
public enum EvfOutputDevice : int
{
Off = 0,
Camera = 1,
PC = 2,
Filming = 3,
Mobile = 4,
Mobile2 = 8,
}
/// <summary>
/// Liveview Zoom Level
/// </summary>
public enum EvfZoom : int
{
Fit = 1,
x5 = 5,
x10 = 10,
}
/// <summary>
/// Liveview Autofocus Mode
/// </summary>
public enum EvfAFMode : int
{
Quick = 0,
Live = 1,
LiveFace = 2,
LiveMulti = 3,
}
/// <summary>
/// Flash Type
/// </summary>
public enum FlashType : int
{
None = 0,
Internal = 1,
ExternalETTL = 2,
ExternalATTL = 3,
Invalid = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Flash ETTL 2 Mode
/// </summary>
public enum ETTL2Mode : int
{
Evaluative = 0,
Average = 1,
}
/// <summary>
/// Processing parameter of a camera
/// </summary>
public enum ProcessingParameter : int
{
Standard = 0,
ProcessingParameter1 = 1,
ProcessingParameter2 = 2,
ProcessingParameter3 = 3,
}
/// <summary>
/// The orientation of an image
/// </summary>
public enum ImageOrientation : int
{
/// <summary>
/// The 0th row is at the visual top of the image, and the 0th column is on the visual left-hand side
/// </summary>
ULRD = 1,
/// <summary>
/// The 0th row is at the visual bottom of the image, and the 0th column is on the visual right-hand side
/// </summary>
DRLU = 3,
/// <summary>
/// The 0th row is on the visual right-hand side of the image, and the 0th column is at the visual top
/// </summary>
LDUR = 6,
/// <summary>
/// The 0th row is on the visual left-hand side of the image, and the 0th column is at the visual bottom
/// </summary>
RUDL = 8,
Unknown = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Tone curve
/// </summary>
public enum ToneCurve : int
{
Standard = 0x00000000,
UserSetting = 0x00000011,
CustomSetting = 0x00000080,
TCD1 = 0x00000001,
TCD2 = 0x00000002,
TCD3 = 0x00000003,
}
/// <summary>
/// Drive mode of a camera
/// </summary>
public enum DriveMode : int
{
SingleFrame = 0x00000000,
Continuous = 0x00000001,
Video = 0x00000002,
HighSpeedContinuous = 0x00000004,
LowSpeedContinuous = 0x00000005,
SilentSingleFrame = 0x00000006,
SelfTimer10sContinuous = 0x00000007,
SelfTimer10s = 0x00000010,
SelfTimer2s = 0x00000011,
}
/// <summary>
/// Autofocus mode of a camera
/// </summary>
public enum AFMode : int
{
OneShot = 0,
AIServo = 1,
AIFocus = 2,
Manual = 3,
Unknown = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Noise reduction method
/// </summary>
public enum NoiseReduction : int
{
Off = 0,
On1 = 1,
On2 = 2,
On = 3,
Auto = 4,
}
/// <summary>
/// State of red eye reduction
/// </summary>
public enum RedEye : int
{
Off = 0,
On = 1,
Invalid = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Flash synchronization of curtain
/// </summary>
public enum SynchroTiming : int
{
Curtain1 = 0,
Curtain2 = 1,
Invalid = unchecked((int)0xFFFFFFFF),
}
/// <summary>
/// Mode of histogram
/// </summary>
public enum HistogramStatus : int
{
Hide = 0,
Normal = 1,
Grayout = 2,
}
/// <summary>
/// Video recording methods
/// </summary>
public enum Recording : int
{
Off = 0,
Ready = 3,
On = 4,
}
/// <summary>
/// Image type to save after RAW processing
/// </summary>
public enum SaveImageType : int
{
Jpeg = 0x00000001,
TIFF = 0x00000007,
TIFF16 = 0x00000008,
}
/// <summary>
/// Camera sub-type
/// </summary>
public enum DeviceSubType : int
{
CanonPTPCameras = 1,
CanonPTP_IPCameras = 2,
}
}
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace EOSDigital.SDK
{
/// <summary>
/// This class contains all of the native Canon SDK calls and some wrapper methods
/// </summary>
public static class CanonSDK
{
/// <summary>
/// Maximum length of string
/// </summary>
public const int MAX_NAME = 256;
/// <summary>
/// Block size of a data transfer
/// </summary>
public const int TRANSFER_BLOCK_SIZE = 512;
/// <summary>
/// The path to the Canon SDK DLL
/// </summary>
public const string DllPath = @"EDSDK\EDSDK.dll";//"EDSDK";//@"EDSDK\EDSDK.dll";
#region Version Check
/// <summary>
/// Version of the currently used Canon SDK DLL
/// </summary>
public static Version SDKVersion
{
get;
private set;
}
/// <summary>
/// States if the used SDK version is >=3.4
/// Call <see cref="InitializeVersion"/> to initialize this property.
/// </summary>
public static bool IsVerGE34
{
get;
private set;
}
/// <summary>
/// Checks which SDK version is currently used and sets IsVer* properties
/// </summary>
/// <exception cref="InvalidOperationException">Could not extract version information</exception>
public static void InitializeVersion()
{
try
{
SDKVersion = GetSDKVersion();
if (SDKVersion == null) throw new InvalidOperationException("Could not find SDK version");
IsVerGE34 = SDKVersion.Major >= 3 && SDKVersion.Minor >= 4;
}
catch (Exception ex)
{
throw new InvalidOperationException("Could not find SDK version", ex);
}
}
/// <summary>
/// Get SDK version on Windows
/// </summary>
/// <returns>The SDK version or null if not found</returns>
private static Version GetSDKVersion()
{
var modules = Process.GetCurrentProcess().Modules;
foreach (var module in modules)
{
var pm = module as ProcessModule;
string name = pm?.ModuleName?.ToLower();
if (name == "edsdk.dll")
{
FileVersionInfo vi = pm.FileVersionInfo;
return new Version(vi.ProductMajorPart, vi.ProductMinorPart, vi.ProductBuildPart, vi.ProductPrivatePart);
}
}
return null;
}
#endregion
#region Init/Close
/// <summary>
/// Initializes the libraries.
/// This must be called before using the EDSDK API
/// </summary>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsInitializeSDK();
/// <summary>
/// Terminates the use of the libraries.
/// This must be called when ending the SDK, it releases all resources used by the libraries.
/// </summary>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsTerminateSDK();
/// <summary>
/// Establishes a logical connection with a remote camera. Use this method after getting the camera object.
/// </summary>
/// <param name="inCameraRef">The reference of the camera.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsOpenSession(IntPtr inCameraRef);
/// <summary>
/// Closes a logical connection with a remote camera.
/// </summary>
/// <param name="inCameraRef">The reference of the camera.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCloseSession(IntPtr inCameraRef);
#endregion
#region Properties
/// <summary>
/// Gets the byte size and data type of a designated property from a camera object or image object.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outDataType">Pointer to the buffer that is to receive the property type data.</param>
/// <param name="outSize">Pointer to the buffer that is to receive the property size.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetPropertySize(IntPtr inRef, PropertyID inPropertyID, int inParam, out DataType outDataType, out int outSize);
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="inPropertySize">The number of bytes of the prepared buffer for receive property-value.</param>
/// <param name="outPropertyData">The buffer pointer to receive property-value.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, int inPropertySize, IntPtr outPropertyData);
/// <summary>
/// Sets property data for the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID</param>
/// <param name="inParam">Additional information of property.</param>
/// <param name="inPropertySize">The number of bytes of the prepared buffer for set property-value.</param>
/// <param name="inPropertyData">The buffer pointer to set property-value.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, int inPropertySize, [MarshalAs(UnmanagedType.AsAny), In] object inPropertyData);
/// <summary>
/// Gets a list of property data that can be set for the object designated in inRef,
/// as well as maximum and minimum values. This method is only intended for some shooting-related properties
/// </summary>
/// <param name="inRef">The reference of the camera.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="outPropertyDesc">Array of the values which can be set up.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetPropertyDesc(IntPtr inRef, PropertyID inPropertyID, out PropertyDesc outPropertyDesc);
#endregion
#region Commands
/// <summary>
/// Sends a command such as "Shoot" to a remote camera.
/// </summary>
/// <param name="inCameraRef">The reference of the camera which will receive the command.</param>
/// <param name="inCommand">Specifies the command to be sent</param>
/// <param name="inParam">Specifies additional command-specific information.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSendCommand(IntPtr inCameraRef, CameraCommand inCommand, int inParam);
/// <summary>
/// Sets the remote camera state or mode.
/// </summary>
/// <param name="inCameraRef">The reference of the camera which will receive the command.</param>
/// <param name="inCameraState">Specifies the command to be sent.</param>
/// <param name="inParam">Specifies additional command-specific information.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSendStatusCommand(IntPtr inCameraRef, CameraStatusCommand inCameraState, int inParam);
#endregion
#region Camera File System
/// <summary>
/// Sets the remaining HDD capacity on the host computer (excluding the portion from image transfer), as calculated by subtracting the portion from the previous time.
/// Set a reset flag initially and designate the cluster length and number of free clusters.
/// Some type 2 protocol standard cameras can display the number of shots left on the camera based on the available disk capacity of the host computer.
/// For these cameras, after the storage destination is set to the computer, use this method to notify the camera of the available disk capacity of the host computer.
/// </summary>
/// <param name="inCameraRef">The reference of the camera which will receive the command.</param>
/// <param name="inCapacity">The remaining capacity of a transmission place.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSetCapacity(IntPtr inCameraRef, Capacity inCapacity);
/// <summary>
/// Gets volume information for a memory card in the camera
/// </summary>
/// <param name="inCameraRef">Information of the volume</param>
/// <param name="outVolumeInfo"></param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetVolumeInfo(IntPtr inCameraRef, out VolumeInfo outVolumeInfo);
/// <summary>
/// Formats a volume.
/// </summary>
/// <param name="inVolumeRef">The reference of the volume.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsFormatVolume(IntPtr inVolumeRef);
/// <summary>
/// Gets information about the directory or file object on the memory card (volume) in a remote camera.
/// </summary>
/// <param name="inDirItemRef">The reference of the directory item.</param>
/// <param name="outDirItemInfo">Information of the directory item.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetDirectoryItemInfo(IntPtr inDirItemRef, out DirectoryItemInfo outDirItemInfo);
/// <summary>
/// Deletes a camera folder or file.
/// If folders with subdirectories are designated, all files are deleted except protected files.
/// DirectoryItem objects deleted by means of this method are implicitly released.
/// Thus, there is no need to release them by means of Release.
/// </summary>
/// <param name="inDirItemRef"></param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsDeleteDirectoryItem(IntPtr inDirItemRef);
/// <summary>
/// Gets attributes of files of a camera.
/// </summary>
/// <param name="inDirItemRef">The reference of the directory item.</param>
/// <param name="outFileAttribute">
/// Indicates the file attributes.
/// As for the file attributes, OR values of the value defined by enum FileAttributes can be retrieved.
/// Thus, when determining the file attributes, it must be checked if an attribute flag is set for target attributes.
/// </param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetAttribute(IntPtr inDirItemRef, out FileAttribute outFileAttribute);
/// <summary>
/// Changes attributes of files on a camera.
/// </summary>
/// <param name="inDirItemRef">The reference of the directory item.</param>
/// <param name="inFileAttribute">
/// Indicates the file attributes.
/// As for the file attributes, OR values of the value defined by enum FileAttributes can be retrieved.
/// </param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSetAttribute(IntPtr inDirItemRef, FileAttribute inFileAttribute);
#endregion
#region Download
/// <summary>
/// Downloads a file on a remote camera (in the camera memory or on a memory card) to the host computer.
/// The downloaded file is sent directly to a file stream created in advance.
/// When dividing the file being retrieved, call this method repeatedly.
/// Also in this case, make the data block size a multiple of 512 (bytes), excluding the final block.
/// <para>USE ONLY WITH SDK VERSION &lt;3.4</para>
/// </summary>
/// <param name="inDirItemRef">The reference of the directory item.</param>
/// <param name="inReadSize">-</param>
/// <param name="outStream">The reference of the stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsDownload(IntPtr inDirItemRef, int inReadSize, IntPtr outStream);
/// <summary>
/// Downloads a file on a remote camera (in the camera memory or on a memory card) to the host computer.
/// The downloaded file is sent directly to a file stream created in advance.
/// When dividing the file being retrieved, call this method repeatedly.
/// Also in this case, make the data block size a multiple of 512 (bytes), excluding the final block.
/// <para>USE ONLY WITH SDK VERSION &gt;=3.4</para>
/// </summary>
/// <param name="inDirItemRef">The reference of the directory item.</param>
/// <param name="inReadSize">-</param>
/// <param name="outStream">The reference of the stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsDownload(IntPtr inDirItemRef, long inReadSize, IntPtr outStream);
/// <summary>
/// Must be executed when downloading of a directory item is canceled.
/// Calling this method makes the camera cancel file transmission.
/// It also releases resources.
/// This operation need not be executed when using DownloadThumbnail.
/// </summary>
/// <param name="inDirItemRef">The reference of the directory item.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsDownloadCancel(IntPtr inDirItemRef);
/// <summary>
/// Must be called when downloading of directory items is complete.
/// Executing this method makes the camera recognize that file transmission is complete.
/// This operation need not be executed when using DownloadThumbnail.
/// </summary>
/// <param name="inDirItemRef"></param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsDownloadComplete(IntPtr inDirItemRef);
/// <summary>
/// Extracts and downloads thumbnail information from image files in a camera.
/// Thumbnail information in the camera's image files is downloaded to the host computer.
/// Downloaded thumbnails are sent directly to a file stream created in advance.
/// </summary>
/// <param name="inDirItemRef">The reference of the directory item.</param>
/// <param name="outStream">The reference of the stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsDownloadThumbnail(IntPtr inDirItemRef, IntPtr outStream);
#endregion
#region Streams
/// <summary>
/// Creates a new file on a host computer (or opens an existing file) and creates a file stream for access to the file.
/// If a new file is designated before executing this method, the file is actually created following the timing of writing by means of Write or the like with respect to an open stream.
/// </summary>
/// <param name="inFileName">Pointer to a null-terminated string that specifies the file name.</param>
/// <param name="inCreateDisposition">Action to take on files that exist, and which action to take hen files do not exist.</param>
/// <param name="inDesiredAccess">Access to the stream (reading, writing, or both).</param>
/// <param name="outStream">The reference of the stream</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCreateFileStream(string inFileName, FileCreateDisposition inCreateDisposition, FileAccess inDesiredAccess, out IntPtr outStream);
/// <summary>
/// Creates a stream in the memory of a host computer.
/// In the case if writing in excess of the allocated buffer size, the memory is automatically extended.
/// <para>USE ONLY WITH SDK VERSION &lt;3.4</para>
/// </summary>
/// <param name="inBufferSize">The number of bytes of the memory to allocate.</param>
/// <param name="outStream">The reference of the stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCreateMemoryStream(int inBufferSize, out IntPtr outStream);
/// <summary>
/// Creates a stream in the memory of a host computer.
/// In the case if writing in excess of the allocated buffer size, the memory is automatically extended.
/// <para>USE ONLY WITH SDK VERSION &gt;=3.4</para>
/// </summary>
/// <param name="inBufferSize">The number of bytes of the memory to allocate.</param>
/// <param name="outStream">The reference of the stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCreateMemoryStream(long inBufferSize, out IntPtr outStream);
/// <summary>
/// An extended version of CreateStreamFromFile.
/// Use this method when working with Unicode file names.
/// </summary>
/// <param name="inFileName">Designate the file name.</param>
/// <param name="inCreateDisposition">Action to take on files take when files do not exist.</param>
/// <param name="inDesiredAccess">Access to the stream (reading, writing, or both)</param>
/// <param name="outStream">The reference of the stream</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath, CharSet = CharSet.Unicode)]
public extern static ErrorCode EdsCreateFileStreamEx(string inFileName, FileCreateDisposition inCreateDisposition, FileAccess inDesiredAccess, out IntPtr outStream);
/// <summary>
/// Creates a stream from the memory buffer you prepared.
/// Unlike the buffer size of streams created by means of CreateMemoryStream, the buffer size you prepare
/// for streams created this way does not expand.
/// <para>USE ONLY WITH SDK VERSION &lt;3.4</para>
/// </summary>
/// <param name="inUserBuffer">-</param>
/// <param name="inBufferSize">The number of bytes of the memory to allocate.</param>
/// <param name="outStream">The reference of the stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCreateMemoryStreamFromPointer(IntPtr inUserBuffer, int inBufferSize, out IntPtr outStream);
/// <summary>
/// Creates a stream from the memory buffer you prepared.
/// Unlike the buffer size of streams created by means of CreateMemoryStream, the buffer size you prepare
/// for streams created this way does not expand.
/// <para>USE ONLY WITH SDK VERSION &gt;=3.4</para>
/// </summary>
/// <param name="inUserBuffer">-</param>
/// <param name="inBufferSize">The number of bytes of the memory to allocate.</param>
/// <param name="outStream">The reference of the stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCreateMemoryStreamFromPointer(IntPtr inUserBuffer, long inBufferSize, out IntPtr outStream);
/// <summary>
/// Creates a stream from the memory buffer you prepared.
/// Unlike the buffer size of streams created by means of CreateMemoryStream, the buffer size you prepare for streams created this way does not expand.
/// <para>USE ONLY WITH SDK VERSION &lt;3.4</para>
/// </summary>
/// <param name="inUserBuffer">-</param>
/// <param name="inBufferSize">The number of bytes of the memory to allocate.</param>
/// <param name="outStream">The reference of the stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCreateMemoryStreamFromPointer(byte[] inUserBuffer, int inBufferSize, out IntPtr outStream);
/// <summary>
/// Creates a stream from the memory buffer you prepared.
/// Unlike the buffer size of streams created by means of CreateMemoryStream, the buffer size you prepare for streams created this way does not expand.
/// <para>USE ONLY WITH SDK VERSION &gt;=3.4</para>
/// </summary>
/// <param name="inUserBuffer">-</param>
/// <param name="inBufferSize">The number of bytes of the memory to allocate.</param>
/// <param name="outStream">The reference of the stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCreateMemoryStreamFromPointer(byte[] inUserBuffer, long inBufferSize, out IntPtr outStream);
/// <summary>
/// Creates a stream from an existing stream.
/// </summary>
/// <param name="inStream">The reference of the input stream.</param>
/// <param name="outStreamRef">The reference of the output stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCreateStream(IntPtr inStream, IntPtr outStreamRef);
/// <summary>
/// Gets the pointer to the start address of memory managed by the memory stream.
/// As the EDSDK automatically resizes the buffer, the memory stream provides you with the same access methods as for the file stream.
/// If access is attempted that is excessive with regard to the buffer size for the stream, data before the required buffer size is allocated is copied internally, and new writing occurs.
/// Thus, the buffer pointer might be switched on an unknown timing. Caution in use is therefore advised.
/// </summary>
/// <param name="inStreamRef">Designate the memory stream for the pointer to retrieve.</param>
/// <param name="outPointer">If successful, returns the pointer to the buffer written in the memory stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetPointer(IntPtr inStreamRef, out IntPtr outPointer);
/// <summary>
/// Reads data the size of inReadSize into the outBuffer buffer, starting at the current read or write position of the stream.
/// The size if data actually read can be designated in outReadSize.
/// <para>USE ONLY WITH SDK VERSION &lt;3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="inReadSize">The number of bytes to read.</param>
/// <param name="outBuffer">Pointer to the user-supplied buffer that is to receive the data read from the stream.</param>
/// <param name="outReadSize">The actually read number of bytes.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsRead(IntPtr inStreamRef, int inReadSize, IntPtr outBuffer, out int outReadSize);
/// <summary>
/// Reads data the size of inReadSize into the outBuffer buffer, starting at the current read or write position of the stream.
/// The size if data actually read can be designated in outReadSize.
/// <para>USE ONLY WITH SDK VERSION &gt;=3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="inReadSize">The number of bytes to read.</param>
/// <param name="outBuffer">Pointer to the user-supplied buffer that is to receive the data read from the stream.</param>
/// <param name="outReadSize">The actually read number of bytes.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsRead(IntPtr inStreamRef, long inReadSize, IntPtr outBuffer, out long outReadSize);
/// <summary>
/// Writes data of a designated buffer to the current read or write position of the stream.
/// <para>USE ONLY WITH SDK VERSION &lt;3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="inWriteSize">The number of bytes to write.</param>
/// <param name="inBuffer">A pointer to the user-supplied buffer that contains the data to be written (in number of bytes)</param>
/// <param name="outWrittenSize"></param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsWrite(IntPtr inStreamRef, int inWriteSize, IntPtr inBuffer, out int outWrittenSize);
/// <summary>
/// Writes data of a designated buffer to the current read or write position of the stream.
/// <para>USE ONLY WITH SDK VERSION &gt;=3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="inWriteSize">The number of bytes to write.</param>
/// <param name="inBuffer">A pointer to the user-supplied buffer that contains the data to be written (in number of bytes)</param>
/// <param name="outWrittenSize"></param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsWrite(IntPtr inStreamRef, long inWriteSize, IntPtr inBuffer, out long outWrittenSize);
/// <summary>
/// Moves the read or write position of the stream (that is, the file position indicator)
/// <para>USE ONLY WITH SDK VERSION &lt;3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="inSeekOffset">Number of bytes to move the pointer.</param>
/// <param name="inSeekOrigin">Pointer movement mode.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSeek(IntPtr inStreamRef, int inSeekOffset, SeekOrigin inSeekOrigin);
/// <summary>
/// Moves the read or write position of the stream (that is, the file position indicator)
/// <para>USE ONLY WITH SDK VERSION &gt;=3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="inSeekOffset">Number of bytes to move the pointer.</param>
/// <param name="inSeekOrigin">Pointer movement mode.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSeek(IntPtr inStreamRef, long inSeekOffset, SeekOrigin inSeekOrigin);
/// <summary>
/// Gets the current read or write position of the stream (that is, the file position indicator)
/// <para>USE ONLY WITH SDK VERSION &lt;3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="outPosition">The current stream pointer.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetPosition(IntPtr inStreamRef, out int outPosition);
/// <summary>
/// Gets the current read or write position of the stream (that is, the file position indicator)
/// <para>USE ONLY WITH SDK VERSION &gt;=3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="outPosition">The current stream pointer.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetPosition(IntPtr inStreamRef, out long outPosition);
/// <summary>
/// Gets the stream size.
/// <para>USE ONLY WITH SDK VERSION &lt;3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="outLength">The length of the stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetLength(IntPtr inStreamRef, out int outLength);
/// <summary>
/// Gets the stream size.
/// <para>USE ONLY WITH SDK VERSION &gt;=3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="outLength">The length of the stream.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetLength(IntPtr inStreamRef, out long outLength);
/// <summary>
/// Copies data from the copy source stream to the copy destination stream.
/// The read or write position of the data to copy is determined from the current file read or write position of the respective stream.
/// After this method is executed, the read or write position of the copy source and copy destination streams are moved
/// an amount corresponding to inWriteSize in the positive direction.
/// <para>USE ONLY WITH SDK VERSION &lt;3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="inWriteSize">The number of bytes to copy.</param>
/// <param name="outStreamRef">The reference of the stream or image.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCopyData(IntPtr inStreamRef, int inWriteSize, IntPtr outStreamRef);
/// <summary>
/// Copies data from the copy source stream to the copy destination stream.
/// The read or write position of the data to copy is determined from the current file read or write position of the respective stream.
/// After this method is executed, the read or write position of the copy source and copy destination streams are moved
/// an amount corresponding to inWriteSize in the positive direction.
/// <para>USE ONLY WITH SDK VERSION &gt;=3.4</para>
/// </summary>
/// <param name="inStreamRef">The reference of the stream or image.</param>
/// <param name="inWriteSize">The number of bytes to copy.</param>
/// <param name="outStreamRef">The reference of the stream or image.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCopyData(IntPtr inStreamRef, long inWriteSize, IntPtr outStreamRef);
#endregion
#region Image Handling
/// <summary>
/// Creates an image object from an image file.
/// Without modification, stream objects cannot be worked with as images.
/// Thus, when extracting images from image files, this method must be used to create image objects.
/// The image object created this way can be used to get image information
/// (such as height and width, number of components, and resolution), thumbnail image data, and the image data itself.
/// </summary>
/// <param name="inStreamRef">The reference of the stream.</param>
/// <param name="outImageRef">The reference of the image.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCreateImageRef(IntPtr inStreamRef, out IntPtr outImageRef);
/// <summary>
/// Gets image information from a designated image object.
/// Here, image information means the image width and height, number of color components, resolution, and effective image area.
/// </summary>
/// <param name="inImageRef">Designate the object which to get image information.</param>
/// <param name="inImageSource">
/// Of the various image data items in the image file, designate the type of image data representing the information you want to get.
/// Designate the image as defined in the enum ImageSource.
/// </param>
/// <param name="outImageInfo">Stores the image information designated in inImageSource</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetImageInfo(IntPtr inImageRef, ImageSource inImageSource, out ImageInfo outImageInfo);
/// <summary>
/// Gets designated image data from an image file, in the form of a designated rectangle.
/// Returns uncompressed results for JPEGs and processed results in the designated pixel order (RGB, Top-down BGR, and so on) for RAW images.
/// Additionally, by designating the input/output rectangle, it is possible to get reduced, enlarged, or partial images.
/// However, because images corresponding to the designated output rectangle are always returned by the SDK, the SDK does not take the aspect ratio into account.
/// To maintain the aspect ratio, you must keep the aspect ratio in mind when designating the rectangle.
/// </summary>
/// <param name="inImageRef">Designate the image object for which to get the image data.</param>
/// <param name="inImageSource">Designate the type of image data to get from the image file (thumbnail, preview, and so on). Designate values as defined in Enum ImageSource.</param>
/// <param name="inImageType">
/// Designate the output image type.
/// Because the output format of EdGetImage may only be RGB, only kTargetImageType_RGB or kTargetImageType_RGB16 can be designated.
/// However, image types exceeding the resolution of inImageSource cannot be designated.
/// </param>
/// <param name="inSrcRect">Designate the coordinates and size of the rectangle to be retrieved (processed) from the source image. </param>
/// <param name="inDstSize">Designate the rectangle size for output.</param>
/// <param name="outStreamRef">Designate the memory or file stream for output of the image.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetImage(IntPtr inImageRef, ImageSource inImageSource, TargetImageType inImageType, Rectangle inSrcRect, Size inDstSize, IntPtr outStreamRef);
/// <summary>
/// Saves as a designated image type after RAW processing.
/// When saving with JPEG compression, the JPEG quality setting applies with respect to OptionRef.
/// </summary>
/// <param name="inImageRef">Designate the image object for which to produce the file.</param>
/// <param name="inImageType">Designate the image type to produce. Designate the following image types.</param>
/// <param name="inSaveSetting">Designate saving options, such as JPEG image quality.</param>
/// <param name="outStreamRef">Specifies the output file stream. The memory stream cannot be specified here.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSaveImage(IntPtr inImageRef, SaveImageType inImageType, SaveImageSetting inSaveSetting, IntPtr outStreamRef);
/// <summary>
/// Switches a setting on and off for creation of an image cache in the SDK for a designated image object during extraction (processing) of the image data.
/// </summary>
/// <param name="inImageRef">The reference of the image.</param>
/// <param name="inUseCache">If cache image data or not. If set to false, the cached image data will be released.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCacheImage(IntPtr inImageRef, bool inUseCache);
/// <summary>
/// Incorporates image object property changes (effected by means of SetPropertyData) in the stream.
/// </summary>
/// <param name="inImageRef">The reference of the image.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsReflectImageProperty(IntPtr inImageRef);
#endregion
#region Events
/// <summary>
/// Registers a callback function for when a camera is detected.
/// </summary>
/// <param name="inCameraAddedHandler">Pointer to a callback function called when a camera is connected physically.</param>
/// <param name="inContext">Specifies an application-defined value to be sent to the callback function pointed to by CallBack parameter.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSetCameraAddedHandler(SDKCameraAddedHandler inCameraAddedHandler, IntPtr inContext);
/// <summary>
/// Registers a callback function for receiving status change notification events for property-related camera evens.
/// </summary>
/// <param name="inCameraRef">Designate the camera object.</param>
/// <param name="inEvent">Designate one or all events to be supplemented.</param>
/// <param name="inPropertyEventHandler">Designate the pointer to the callback function for receiving property-related camera events.</param>
/// <param name="inContext">Designate application information to be passed by mens of the callback funcion.Any data needed for your application can be passed.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSetPropertyEventHandler(IntPtr inCameraRef, PropertyEventID inEvent, SDKPropertyEventHandler inPropertyEventHandler, IntPtr inContext);
/// <summary>
/// Registers a callback function for receiving status change notification events for objects on a remote camera.
/// Here, object means columns representation memory cards, files and directories, and shot images stored in memory, in particular.
/// </summary>
/// <param name="inCameraRef">Designate the camera object.</param>
/// <param name="inEvent">Designate one or all events to be supplemented.</param>
/// <param name="inObjectEventHandler">Designate the pointer to the callback function for receiving object-related camera events.</param>
/// <param name="inContext">Passes inContext without modification, as designated as an SetObjectEventHandler argument.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSetObjectEventHandler(IntPtr inCameraRef, ObjectEventID inEvent, SDKObjectEventHandler inObjectEventHandler, IntPtr inContext);
/// <summary>
/// Registers a callback function for receiving status change notification events for property states on a camera.
/// </summary>
/// <param name="inCameraRef">Designate the camera object.</param>
/// <param name="inEvent">Designate one or all events to be supplemented.</param>
/// <param name="inStateEventHandler">Designate the pointer to the callback function for receiving events related to camera object states.</param>
/// <param name="inContext">Designate application information to be passed by means of the callback function. Any data needed for the application can be passed.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSetCameraStateEventHandler(IntPtr inCameraRef, StateEventID inEvent, SDKStateEventHandler inStateEventHandler, IntPtr inContext);
/// <summary>
/// Register a progress callback function.
/// An event is received as notification of progress during processing that takes a relatively long time, such as downloading files from a remote camera.
/// If you register the callback function, the EDSDK calls the callback function during execution or on completion of the following APIs.
/// This timing can be used in updating on-screen progress bars, for example.
/// </summary>
/// <param name="inRef">The reference of the stream or image.</param>
/// <param name="inProgressFunc">Pointer to the progress callback function.</param>
/// <param name="inProgressOption">The option about progress is specified.</param>
/// <param name="inContext">
/// Application information, passed in the argument when the callback function is called.
/// Any information required for the program may be added.
/// </param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsSetProgressCallback(IntPtr inRef, SDKProgressCallback inProgressFunc, ProgressOption inProgressOption, IntPtr inContext);
/// <summary>
/// This function acquires an event.
/// In console application, please call this function regularly to acquire
/// the event from a camera.
/// </summary>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetEvent();
#endregion
#region Evf Image
/// <summary>
/// Creates an object used to get the live view image data set.
/// </summary>
/// <param name="inStreamRef">The stream reference which opened to get EVF JPEG image.</param>
/// <param name="outEvfImageRef">The EVFData reference.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsCreateEvfImageRef(IntPtr inStreamRef, out IntPtr outEvfImageRef);
/// <summary>
/// Downloads the live view image data set for a camera currently in live view mode.
/// Live view can be started by using the property ID: PropertyID_Evf_OutputDevice and
/// data:OutputDevice_PC to call SetPropertyData.
/// In addition to image data, information such as zoom, focus position, and histogram data
/// is included in the image data set. Image data is saved in a stream maintained by EvfImageRef.
/// GetPropertyData can be used to get information such as the zoom, focus position, etc.
/// Although the information of the zoom and focus position can be obtained from EvfImageRef,
/// settings are applied to CameraRef.
/// </summary>
/// <param name="inCameraRef">The camera reference.</param>
/// <param name="outEvfImageRef">The EVFData reference.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsDownloadEvfImage(IntPtr inCameraRef, IntPtr outEvfImageRef);
#endregion
#region Misc
/// <summary>
/// Gets camera list objects.
/// </summary>
/// <param name="outCameraListRef">Pointer to the camera-list.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetCameraList(out IntPtr outCameraListRef);
/// <summary>
/// Gets device information, such as the device name.
/// Because device information of remote cameras is stored on the host computer, this method can be called before the session with the camera is opened.
/// </summary>
/// <param name="inCameraRef">The reference of the camera.</param>
/// <param name="outDeviceInfo">Information as device of camera.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetDeviceInfo(IntPtr inCameraRef, out DeviceInfo outDeviceInfo);
/// <summary>
/// Increments the reference counter of existing objects.
/// </summary>
/// <param name="inRef">The reference for the item</param>
/// <returns>The number of references for this pointer or 0xFFFFFFFF for an error</returns>
[DllImport(DllPath)]
public extern static int EdsRetain(IntPtr inRef);
/// <summary>
/// Decrements the reference counter of an object.
/// When the reference counter reaches 0, the object is release.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <returns>The number of references for this pointer or 0xFFFFFFFF for an error</returns>
[DllImport(DllPath)]
public extern static int EdsRelease(IntPtr inRef);
/// <summary>
/// Gets the number of child objects of the designated object.
/// Example: Number of files in a directory
/// </summary>
/// <param name="inRef">The reference of the list</param>
/// <param name="outCount">Number of elements in this list.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetChildCount(IntPtr inRef, out int outCount);
/// <summary>
/// Gets an indexed child object of the designated object.
/// </summary>
/// <param name="inRef">The reference of the item</param>
/// <param name="inIndex">The index that is passes in (zero based)</param>
/// <param name="outRef">The pointer which receives reference of the specific index.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetChildAtIndex(IntPtr inRef, int inIndex, out IntPtr outRef);
/// <summary>
/// Gets the parent object of the designated object.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="outParentRef">The pointer which receives reference.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
public extern static ErrorCode EdsGetParent(IntPtr inRef, out IntPtr outParentRef);
#endregion
#region Helper Methods
/// <summary>
/// Gets information about the directory or file object on the memory card (volume) in a remote camera.
/// This method works regardless of the used SDK version.
/// </summary>
/// <param name="inDirItemRef">The reference of the directory item.</param>
/// <param name="outDirItemInfo">Information of the directory item.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetDirectoryItemInfo(IntPtr inDirItemRef, out DirectoryItemInfo outDirItemInfo)
{
if (IsVerGE34) { return EdsGetDirectoryItemInfo(inDirItemRef, out outDirItemInfo); }
else
{
DirectoryItemInfo_3_4 tmpValue;
ErrorCode err = EdsGetDirectoryItemInfo(inDirItemRef, out tmpValue);
if (err == ErrorCode.OK)
{
outDirItemInfo = tmpValue.ToCurrent();
return err;
}
outDirItemInfo = default(DirectoryItemInfo);
return err;
}
}
/// <summary>
/// Gets information about the directory or file object on the memory card (volume) in a remote camera.
/// <para></para>
/// </summary>
/// <param name="inDirItemRef">The reference of the directory item.</param>
/// <param name="outDirItemInfo">Information of the directory item.</param>
/// <returns>Any of the SDK errors</returns>
[DllImport(DllPath)]
private extern static ErrorCode EdsGetDirectoryItemInfo(IntPtr inDirItemRef, out DirectoryItemInfo_3_4 outDirItemInfo);
#endregion
#region GetPropertyData Wrapper
/// <summary>
/// Gets property information from the object designated in inRef.
/// This method takes care of differences between SDK versions.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <typeparam name="T">The type of a struct. Must be on of the types described in the <see cref="DataType"/> enum</typeparam>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData<T>(IntPtr inRef, PropertyID inPropertyID, int inParam, out T outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
outPropertyData = default(T);
if (outPropertyData is PictureStyleDesc)
{
PictureStyleDesc tmpValue;
err = GetPropertyData(inRef, inPropertyID, inParam, out tmpValue);
if (err == ErrorCode.OK) outPropertyData = (T)(object)tmpValue;
}
else { err = GetPropertyDataSub(inRef, inPropertyID, inParam, out outPropertyData); }
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <typeparam name="T">The type of a struct. Must be on of the types described in the <see cref="DataType"/> enum</typeparam>
/// <returns>Any of the SDK errors</returns>
private static ErrorCode GetPropertyDataSub<T>(IntPtr inRef, PropertyID inPropertyID, int inParam, out T outPropertyData)
{
IntPtr ptr = IntPtr.Zero;
ErrorCode err = ErrorCode.INTERNAL_ERROR;
outPropertyData = default(T);
try
{
DataType dt;
int size;
err = EdsGetPropertySize(inRef, inPropertyID, inParam, out dt, out size);
if (err == ErrorCode.OK)
{
ptr = Marshal.AllocHGlobal(size);
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, ptr);
if (err == ErrorCode.OK) outPropertyData = (T)Marshal.PtrToStructure(ptr, typeof(T));
}
}
finally { if (ptr != IntPtr.Zero) Marshal.FreeHGlobal(ptr); }
return err;
}
#region Primitive Types
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out bool outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(bool));
bool val;
unsafe
{
bool* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out byte outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(byte));
byte val;
unsafe
{
byte* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out short outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(short));
short val;
unsafe
{
short* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
[CLSCompliant(false)]
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out ushort outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(ushort));
ushort val;
unsafe
{
ushort* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
[CLSCompliant(false)]
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out uint outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(uint));
uint val;
unsafe
{
uint* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out int outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(int));
int val;
unsafe
{
int* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out string outPropertyData)
{
IntPtr ptr = IntPtr.Zero;
ErrorCode err = ErrorCode.INTERNAL_ERROR;
outPropertyData = string.Empty;
try
{
DataType dt;
int size;
err = EdsGetPropertySize(inRef, inPropertyID, inParam, out dt, out size);
if (err == ErrorCode.OK)
{
ptr = Marshal.AllocHGlobal(size);
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, ptr);
if (err == ErrorCode.OK) outPropertyData = Marshal.PtrToStringAnsi(ptr);
}
}
finally { if (ptr != IntPtr.Zero) Marshal.FreeHGlobal(ptr); }
return err;
}
#endregion
#region Arrays
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out bool[] outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int tpsize = Marshal.SizeOf(typeof(bool));
int propsize;
DataType proptype;
err = EdsGetPropertySize(inRef, inPropertyID, inParam, out proptype, out propsize);
if (err == ErrorCode.OK)
{
var data = new bool[propsize / tpsize];
unsafe
{
fixed (bool* dataP = data)
{
err = EdsGetPropertyData(inRef, inPropertyID, inParam, propsize, (IntPtr)dataP);
}
}
if (err == ErrorCode.OK) outPropertyData = data;
else outPropertyData = new bool[0];
}
else outPropertyData = new bool[0];
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out short[] outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int tpsize = Marshal.SizeOf(typeof(short));
int propsize;
DataType proptype;
err = EdsGetPropertySize(inRef, inPropertyID, inParam, out proptype, out propsize);
if (err == ErrorCode.OK)
{
var data = new short[propsize / tpsize];
unsafe
{
fixed (short* dataP = data)
{
err = EdsGetPropertyData(inRef, inPropertyID, inParam, propsize, (IntPtr)dataP);
}
}
if (err == ErrorCode.OK) outPropertyData = data;
else outPropertyData = new short[0];
}
else outPropertyData = new short[0];
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out int[] outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int tpsize = Marshal.SizeOf(typeof(int));
int propsize;
DataType proptype;
err = EdsGetPropertySize(inRef, inPropertyID, inParam, out proptype, out propsize);
if (err == ErrorCode.OK)
{
var data = new int[propsize / tpsize];
unsafe
{
fixed (int* dataP = data)
{
err = EdsGetPropertyData(inRef, inPropertyID, inParam, propsize, (IntPtr)dataP);
}
}
if (err == ErrorCode.OK) outPropertyData = data;
else outPropertyData = new int[0];
}
else outPropertyData = new int[0];
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out byte[] outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int tpsize = Marshal.SizeOf(typeof(byte));
int propsize;
DataType proptype;
err = EdsGetPropertySize(inRef, inPropertyID, inParam, out proptype, out propsize);
if (err == ErrorCode.OK)
{
var data = new byte[propsize / tpsize];
unsafe
{
fixed (byte* dataP = data)
{
err = EdsGetPropertyData(inRef, inPropertyID, inParam, propsize, (IntPtr)dataP);
}
}
if (err == ErrorCode.OK) outPropertyData = data;
else outPropertyData = new byte[0];
}
else outPropertyData = new byte[0];
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
[CLSCompliant(false)]
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out uint[] outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int tpsize = Marshal.SizeOf(typeof(uint));
int propsize;
DataType proptype;
err = EdsGetPropertySize(inRef, inPropertyID, inParam, out proptype, out propsize);
if (err == ErrorCode.OK)
{
var data = new uint[propsize / tpsize];
unsafe
{
fixed (uint* dataP = data)
{
err = EdsGetPropertyData(inRef, inPropertyID, inParam, propsize, (IntPtr)dataP);
}
}
if (err == ErrorCode.OK) outPropertyData = data;
else outPropertyData = new uint[0];
}
else outPropertyData = new uint[0];
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out Rational[] outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int tpsize = Marshal.SizeOf(typeof(Rational));
int propsize;
DataType proptype;
err = EdsGetPropertySize(inRef, inPropertyID, inParam, out proptype, out propsize);
if (err == ErrorCode.OK)
{
var data = new Rational[propsize / tpsize];
unsafe
{
fixed (Rational* dataP = data)
{
err = EdsGetPropertyData(inRef, inPropertyID, inParam, propsize, (IntPtr)dataP);
}
}
if (err == ErrorCode.OK) outPropertyData = data;
else outPropertyData = new Rational[0];
}
else outPropertyData = new Rational[0];
return err;
}
#endregion
#region Structs
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out Time outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(Time));
Time val;
unsafe
{
Time* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out FocusInfo outPropertyData)
{
IntPtr ptr = IntPtr.Zero;
ErrorCode err = ErrorCode.INTERNAL_ERROR;
try
{
int size = Marshal.SizeOf(typeof(FocusInfo));
ptr = Marshal.AllocHGlobal(size);
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, ptr);
outPropertyData = (FocusInfo)Marshal.PtrToStructure(ptr, typeof(FocusInfo));
}
finally { if (ptr != IntPtr.Zero) Marshal.FreeHGlobal(ptr); }
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out FocusPoint outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(FocusPoint));
FocusPoint val;
unsafe
{
FocusPoint* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out Size outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(Size));
Size val;
unsafe
{
Size* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out Rectangle outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(Rectangle));
Rectangle val;
unsafe
{
Rectangle* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out Point outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(Point));
Point val;
unsafe
{
Point* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out MyMenuItems outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
int size = Marshal.SizeOf(typeof(MyMenuItems));
MyMenuItems val;
unsafe
{
MyMenuItems* ptr = &val;
err = EdsGetPropertyData(inRef, inPropertyID, inParam, size, (IntPtr)ptr);
}
outPropertyData = val;
return err;
}
/// <summary>
/// Gets property information from the object designated in inRef.
/// </summary>
/// <param name="inRef">The reference of the item.</param>
/// <param name="inPropertyID">The property ID.</param>
/// <param name="inParam">Additional information of property. Used in order to specify an index in case there are two or more values over the same ID.</param>
/// <param name="outPropertyData">The value of the property.</param>
/// <returns>Any of the SDK errors</returns>
public static ErrorCode GetPropertyData(IntPtr inRef, PropertyID inPropertyID, int inParam, out PictureStyleDesc outPropertyData)
{
ErrorCode err = ErrorCode.INTERNAL_ERROR;
DataType dt;
int size;
outPropertyData = default(PictureStyleDesc);
err = EdsGetPropertySize(inRef, inPropertyID, inParam, out dt, out size);
if (err == ErrorCode.OK)
{
if (size == Marshal.SizeOf(typeof(PictureStyleDesc)))
{
return GetPropertyDataSub(inRef, inPropertyID, inParam, out outPropertyData);
}
else if (size == Marshal.SizeOf(typeof(PictureStyleDesc_3_2)))
{
PictureStyleDesc_3_2 tmpValue;
err = GetPropertyDataSub(inRef, inPropertyID, inParam, out tmpValue);
if (err == ErrorCode.OK)
{
outPropertyData = tmpValue.ToCurrent();
return err;
}
}
else throw new InvalidOperationException("Cannot find correct struct size");
}
return err;
}
#endregion
#endregion
}
}
using System;
using System.Linq;
using System.Runtime.InteropServices;
namespace EOSDigital.SDK
{
/// <summary>
/// Point
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct Point
{
/// <summary>
/// X Coordinate
/// </summary>
public int X;
/// <summary>
/// Y Coordinate
/// </summary>
public int Y;
/// <summary>
/// Creates a new instance of the <see cref="Point"/> struct
/// </summary>
/// <param name="X">X Coordinate</param>
/// <param name="Y">Y Coordinate</param>
public Point(int X, int Y)
{
this.X = X;
this.Y = Y;
}
/// <summary>
/// Determines whether the specified <see cref="Point"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="Point"/></param>
/// <param name="y">The second <see cref="Point"/></param>
/// <returns>True if the <see cref="Point"/>s are equal; otherwise, false</returns>
public static bool operator ==(Point x, Point y)
{
return x.X == y.X && x.Y == y.Y;
}
/// <summary>
/// Determines whether the specified <see cref="Point"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="Point"/></param>
/// <param name="y">The second <see cref="Point"/></param>
/// <returns>True if the <see cref="Point"/>s are unequal; otherwise, false</returns>
public static bool operator !=(Point x, Point y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="Point"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="Point"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="Point"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is Point && this == (Point)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="Point"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="Point"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ X.GetHashCode();
hash *= 16777619 ^ Y.GetHashCode();
return hash;
}
}
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>A string that represents the current object.</returns>
public override string ToString()
{
return string.Concat(X, ";", Y);
}
}
/// <summary>
/// Size
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct Size
{
/// <summary>
/// Width
/// </summary>
public int Width;
/// <summary>
/// Height
/// </summary>
public int Height;
/// <summary>
/// Creates a new instance of the <see cref="Size"/> struct
/// </summary>
public Size(int Width, int Height)
{
this.Width = Width;
this.Height = Height;
}
/// <summary>
/// Determines whether the specified <see cref="Size"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="Size"/></param>
/// <param name="y">The second <see cref="Size"/></param>
/// <returns>True if the <see cref="Size"/>s are equal; otherwise, false</returns>
public static bool operator ==(Size x, Size y)
{
return x.Width == y.Width && x.Height == y.Height;
}
/// <summary>
/// Determines whether the specified <see cref="Size"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="Size"/></param>
/// <param name="y">The second <see cref="Size"/></param>
/// <returns>True if the <see cref="Size"/>s are unequal; otherwise, false</returns>
public static bool operator !=(Size x, Size y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="Size"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="Size"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="Size"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is Size && this == (Size)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="Size"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="Size"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ Width.GetHashCode();
hash *= 16777619 ^ Height.GetHashCode();
return hash;
}
}
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>A string that represents the current object.</returns>
public override string ToString()
{
return string.Concat(Width, ";", Height);
}
}
/// <summary>
/// Rectangle
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct Rectangle
{
/// <summary>
/// X Coordinate
/// </summary>
public int X;
/// <summary>
/// Y Coordinate
/// </summary>
public int Y;
/// <summary>
/// Width of the rectangle
/// </summary>
public int Width;
/// <summary>
/// Height of the rectangle
/// </summary>
public int Height;
/// <summary>
/// Creates a new instance of the <see cref="Rectangle"/> struct
/// </summary>
/// <param name="Width">Width of the rectangle</param>
/// <param name="Height">Height of the rectangle</param>
public Rectangle(int Width, int Height)
: this(0, 0, Width, Height)
{ }
/// <summary>
/// Creates a new instance of the <see cref="Rectangle"/> struct
/// </summary>
/// <param name="X">X Coordinate</param>
/// <param name="Y">Y Coordinate</param>
/// <param name="Width">Width of the rectangle</param>
/// <param name="Height">Height of the rectangle</param>
public Rectangle(int X, int Y, int Width, int Height)
{
this.X = X;
this.Y = Y;
this.Width = Width;
this.Height = Height;
}
/// <summary>
/// Determines whether the specified <see cref="Rectangle"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="Rectangle"/></param>
/// <param name="y">The second <see cref="Rectangle"/></param>
/// <returns>True if the <see cref="Rectangle"/>s are equal; otherwise, false</returns>
public static bool operator ==(Rectangle x, Rectangle y)
{
return x.X == y.X && x.Y == y.Y && x.Width == y.Width && x.Height == y.Height;
}
/// <summary>
/// Determines whether the specified <see cref="Rectangle"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="Rectangle"/></param>
/// <param name="y">The second <see cref="Rectangle"/></param>
/// <returns>True if the <see cref="Rectangle"/>s are unequal; otherwise, false</returns>
public static bool operator !=(Rectangle x, Rectangle y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="Rectangle"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="Rectangle"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="Rectangle"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is Rectangle && this == (Rectangle)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="Size"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="Size"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ X.GetHashCode();
hash *= 16777619 ^ Y.GetHashCode();
hash *= 16777619 ^ Width.GetHashCode();
hash *= 16777619 ^ Height.GetHashCode();
return hash;
}
}
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>A string that represents the current object.</returns>
public override string ToString()
{
return string.Concat(X, ";", Y, ";", Width, ";", Height);
}
}
/// <summary>
/// Rational
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct Rational
{
/// <summary>
/// Numerator of the rational number
/// </summary>
public int Numerator;
/// <summary>
/// Denominator of the rational number
/// </summary>
public int Denominator;
/// <summary>
/// Calculates the value as double
/// </summary>
/// <param name="val">The given Rational value</param>
/// <returns>The Rational as double</returns>
public static implicit operator double(Rational val)
{
return val.Numerator / (double)val.Denominator;
}
/// <summary>
/// Calculates the value as decimal
/// </summary>
/// <param name="val">The given Rational value</param>
/// <returns>The Rational as decimal</returns>
public static implicit operator decimal(Rational val)
{
return val.Numerator / (decimal)val.Denominator;
}
/// <summary>
/// Determines whether the specified <see cref="Rational"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="Rational"/></param>
/// <param name="y">The second <see cref="Rational"/></param>
/// <returns>True if the <see cref="Rational"/>s are equal; otherwise, false</returns>
public static bool operator ==(Rational x, Rational y)
{
return x.Numerator == y.Numerator && x.Denominator == y.Denominator;
}
/// <summary>
/// Determines whether the specified <see cref="Rational"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="Rational"/></param>
/// <param name="y">The second <see cref="Rational"/></param>
/// <returns>True if the <see cref="Rational"/>s are unequal; otherwise, false</returns>
public static bool operator !=(Rational x, Rational y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="Rational"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="Rational"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="Rational"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is Rational && this == (Rational)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="Rational"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="Rational"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ Numerator.GetHashCode();
hash *= 16777619 ^ Denominator.GetHashCode();
return hash;
}
}
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>A string that represents the current object.</returns>
public override string ToString()
{
return Numerator + "/" + Denominator;
}
}
/// <summary>
/// Time
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct Time
{
/// <summary>
/// Year component
/// </summary>
public int Year;
/// <summary>
/// Month component
/// </summary>
public int Month;
/// <summary>
/// Day component
/// </summary>
public int Day;
/// <summary>
/// Hour component
/// </summary>
public int Hour;
/// <summary>
/// Minute component
/// </summary>
public int Minute;
/// <summary>
/// Second component
/// </summary>
public int Second;
/// <summary>
/// Milliseconds component
/// </summary>
public int Milliseconds;
/// <summary>
/// Creates a new instance of the <see cref="Time"/> struct
/// </summary>
/// <param name="Year">Year component</param>
/// <param name="Month">Month component</param>
/// <param name="Day">Day component</param>
public Time(int Year, int Month, int Day)
: this(Year, Month, Day, 0, 0, 0, 0)
{ }
/// <summary>
/// Creates a new instance of the <see cref="Time"/> struct
/// </summary>
/// <param name="Year">Year component</param>
/// <param name="Month">Month component</param>
/// <param name="Day">Day component</param>
/// <param name="Hour">Hour component</param>
public Time(int Year, int Month, int Day, int Hour)
: this(Year, Month, Day, Hour, 0, 0, 0)
{ }
/// <summary>
/// Creates a new instance of the <see cref="Time"/> struct
/// </summary>
/// <param name="Year">Year component</param>
/// <param name="Month">Month component</param>
/// <param name="Day">Day component</param>
/// <param name="Hour">Hour component</param>
/// <param name="Minute">Minute component</param>
public Time(int Year, int Month, int Day, int Hour, int Minute)
: this(Year, Month, Day, Hour, Minute, 0, 0)
{ }
/// <summary>
/// Creates a new instance of the <see cref="Time"/> struct
/// </summary>
/// <param name="Year">Year component</param>
/// <param name="Month">Month component</param>
/// <param name="Day">Day component</param>
/// <param name="Hour">Hour component</param>
/// <param name="Minute">Minute component</param>
/// <param name="Second">Second component</param>
public Time(int Year, int Month, int Day, int Hour, int Minute, int Second)
: this(Year, Month, Day, Hour, Minute, Second, 0)
{ }
/// <summary>
/// Creates a new instance of the <see cref="Time"/> struct
/// </summary>
/// <param name="Year">Year component</param>
/// <param name="Month">Month component</param>
/// <param name="Day">Day component</param>
/// <param name="Hour">Hour component</param>
/// <param name="Minute">Minute component</param>
/// <param name="Second">Second component</param>
/// <param name="Milliseconds">Milliseconds component</param>
public Time(int Year, int Month, int Day, int Hour, int Minute, int Second, int Milliseconds)
{
this.Year = Year;
this.Month = Month;
this.Day = Day;
this.Hour = Hour;
this.Minute = Minute;
this.Second = Second;
this.Milliseconds = Milliseconds;
}
/// <summary>
/// Implicitly converts <see cref="Time"/> to <see cref="DateTime"/>
/// /// </summary>
/// <param name="t">The <see cref="Time"/> to convert</param>
/// <returns>The <see cref="DateTime"/></returns>
public static implicit operator DateTime(Time t)
{
return new DateTime(t.Year, t.Month, t.Day, t.Hour, t.Minute, t.Second, t.Milliseconds);
}
/// <summary>
/// Implicitly converts <see cref="DateTime"/> to <see cref="Time"/>
/// </summary>
/// <param name="t">The <see cref="DateTime"/> to convert</param>
/// <returns>The <see cref="Time"/></returns>
public static implicit operator Time(DateTime t)
{
return new Time(t.Year, t.Month, t.Day, t.Hour, t.Minute, t.Second, t.Millisecond);
}
/// <summary>
/// Determines whether the specified <see cref="Time"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="Time"/></param>
/// <param name="y">The second <see cref="Time"/></param>
/// <returns>True if the <see cref="Time"/>s are equal; otherwise, false</returns>
public static bool operator ==(Time x, Time y)
{
return x.Year == y.Year && x.Month == y.Month && x.Day == y.Day && x.Hour == y.Hour
&& x.Minute == y.Minute && x.Second == y.Second && x.Milliseconds == y.Milliseconds;
}
/// <summary>
/// Determines whether the specified <see cref="Time"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="Time"/></param>
/// <param name="y">The second <see cref="Time"/></param>
/// <returns>True if the <see cref="Time"/>s are unequal; otherwise, false</returns>
public static bool operator !=(Time x, Time y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="Time"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="Time"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="Time"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is Time && this == (Time)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="Time"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="Time"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ Year.GetHashCode();
hash *= 16777619 ^ Month.GetHashCode();
hash *= 16777619 ^ Day.GetHashCode();
hash *= 16777619 ^ Hour.GetHashCode();
hash *= 16777619 ^ Minute.GetHashCode();
hash *= 16777619 ^ Second.GetHashCode();
hash *= 16777619 ^ Milliseconds.GetHashCode();
return hash;
}
}
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>A string that represents the current object.</returns>
public override string ToString()
{
return ((DateTime)this).ToString();
}
}
/// <summary>
/// Device Info
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct DeviceInfo
{
/// <summary>
/// Name of port
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CanonSDK.MAX_NAME)]
public string PortName;
/// <summary>
/// Name of device
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CanonSDK.MAX_NAME)]
public string DeviceDescription;
/// <summary>
/// Device Sub-type
/// </summary>
public DeviceSubType DeviceSubType;
private uint Reserved;
/// <summary>
/// Determines whether the specified <see cref="DeviceInfo"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="DeviceInfo"/></param>
/// <param name="y">The second <see cref="DeviceInfo"/></param>
/// <returns>True if the <see cref="DeviceInfo"/>s are equal; otherwise, false</returns>
public static bool operator ==(DeviceInfo x, DeviceInfo y)
{
return x.PortName == y.PortName && x.DeviceDescription == y.DeviceDescription && x.DeviceSubType == y.DeviceSubType;
}
/// <summary>
/// Determines whether the specified <see cref="DeviceInfo"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="DeviceInfo"/></param>
/// <param name="y">The second <see cref="DeviceInfo"/></param>
/// <returns>True if the <see cref="DeviceInfo"/>s are unequal; otherwise, false</returns>
public static bool operator !=(DeviceInfo x, DeviceInfo y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="DeviceInfo"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="DeviceInfo"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="DeviceInfo"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is DeviceInfo && this == (DeviceInfo)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="DeviceInfo"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="DeviceInfo"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ PortName.GetHashCode();
hash *= 16777619 ^ DeviceDescription.GetHashCode();
hash *= 16777619 ^ DeviceSubType.GetHashCode();
return hash;
}
}
}
/// <summary>
/// Volume Info
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct VolumeInfo
{
/// <summary>
/// Type of storage
/// </summary>
public int StorageType;
/// <summary>
/// Accessibility
/// </summary>
public FileAccess Access;
/// <summary>
/// Maximum capacity
/// </summary>
public long MaxCapacity;
/// <summary>
/// Free space on volume in bytes
/// </summary>
public long FreeSpaceInBytes;
/// <summary>
/// Label/name of the volume
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CanonSDK.MAX_NAME)]
public string VolumeLabel;
/// <summary>
/// Determines whether the specified <see cref="VolumeInfo"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="VolumeInfo"/></param>
/// <param name="y">The second <see cref="VolumeInfo"/></param>
/// <returns>True if the <see cref="VolumeInfo"/>s are equal; otherwise, false</returns>
public static bool operator ==(VolumeInfo x, VolumeInfo y)
{
return x.StorageType == y.StorageType && x.Access == y.Access && x.MaxCapacity == y.MaxCapacity
&& x.FreeSpaceInBytes == y.FreeSpaceInBytes && x.VolumeLabel == y.VolumeLabel;
}
/// <summary>
/// Determines whether the specified <see cref="VolumeInfo"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="VolumeInfo"/></param>
/// <param name="y">The second <see cref="VolumeInfo"/></param>
/// <returns>True if the <see cref="VolumeInfo"/>s are unequal; otherwise, false</returns>
public static bool operator !=(VolumeInfo x, VolumeInfo y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="VolumeInfo"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="VolumeInfo"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="VolumeInfo"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is VolumeInfo && this == (VolumeInfo)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="VolumeInfo"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="VolumeInfo"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ StorageType.GetHashCode();
hash *= 16777619 ^ Access.GetHashCode();
hash *= 16777619 ^ MaxCapacity.GetHashCode();
hash *= 16777619 ^ FreeSpaceInBytes.GetHashCode();
hash *= 16777619 ^ VolumeLabel.GetHashCode();
return hash;
}
}
}
/// <summary>
/// DirectoryItem Info
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct DirectoryItemInfo
{
/// <summary>
/// Size of directory item
/// </summary>
public int Size
{
get { return (int)Size64; }
}
/// <summary>
/// Size of directory item (as long)
/// </summary>
public long Size64;
/// <summary>
/// Marker if it's a folder or a file
/// </summary>
public bool IsFolder;
/// <summary>
/// Group ID
/// </summary>
public int GroupID;
/// <summary>
/// Option
/// </summary>
public int Option;
/// <summary>
/// File name
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CanonSDK.MAX_NAME)]
public string FileName;
/// <summary>
/// Format
/// </summary>
public TargetImageType Format;
/// <summary>
/// Date time
/// </summary>
public int DateTime;
/// <summary>
/// Determines whether the specified <see cref="DirectoryItemInfo"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="DirectoryItemInfo"/></param>
/// <param name="y">The second <see cref="DirectoryItemInfo"/></param>
/// <returns>True if the <see cref="DirectoryItemInfo"/>s are equal; otherwise, false</returns>
public static bool operator ==(DirectoryItemInfo x, DirectoryItemInfo y)
{
return x.Size == y.Size && x.IsFolder == y.IsFolder && x.GroupID == y.GroupID && x.Option == y.Option
&& x.FileName == y.FileName && x.Format == y.Format && x.DateTime == y.DateTime;
}
/// <summary>
/// Determines whether the specified <see cref="DirectoryItemInfo"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="DirectoryItemInfo"/></param>
/// <param name="y">The second <see cref="DirectoryItemInfo"/></param>
/// <returns>True if the <see cref="DirectoryItemInfo"/>s are unequal; otherwise, false</returns>
public static bool operator !=(DirectoryItemInfo x, DirectoryItemInfo y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="DirectoryItemInfo"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="DirectoryItemInfo"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="DirectoryItemInfo"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is DirectoryItemInfo && this == (DirectoryItemInfo)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="DirectoryItemInfo"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="DirectoryItemInfo"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ Size.GetHashCode();
hash *= 16777619 ^ IsFolder.GetHashCode();
hash *= 16777619 ^ GroupID.GetHashCode();
hash *= 16777619 ^ Option.GetHashCode();
hash *= 16777619 ^ FileName.GetHashCode();
hash *= 16777619 ^ Format.GetHashCode();
hash *= 16777619 ^ DateTime.GetHashCode();
return hash;
}
}
}
/// <summary>
/// DirectoryItemInfo struct for SDK versions &lt;3.4
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct DirectoryItemInfo_3_4
{
public int Size;
public bool IsFolder;
public int GroupID;
public int Option;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CanonSDK.MAX_NAME)]
public string FileName;
public TargetImageType Format;
public int DateTime;
public DirectoryItemInfo ToCurrent()
{
return new DirectoryItemInfo
{
Size64 = Size,
IsFolder = IsFolder,
GroupID = GroupID,
Option = Option,
FileName = FileName,
DateTime = DateTime,
};
}
}
/// <summary>
/// Image Info
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ImageInfo
{
/// <summary>
/// Width of image
/// </summary>
public int Width;
/// <summary>
/// Height of image
/// </summary>
public int Height;
/// <summary>
/// Number of channels
/// </summary>
public int NumOfComponents;
/// <summary>
/// Bitdepth of channels
/// </summary>
public int ComponentDepth;
/// <summary>
/// Effective size of image
/// </summary>
public Rectangle EffectiveRect;
private uint Reserved1;
private uint Reserved2;
/// <summary>
/// Determines whether the specified <see cref="ImageInfo"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="ImageInfo"/></param>
/// <param name="y">The second <see cref="ImageInfo"/></param>
/// <returns>True if the <see cref="ImageInfo"/>s are equal; otherwise, false</returns>
public static bool operator ==(ImageInfo x, ImageInfo y)
{
return x.Width == y.Width && x.Height == y.Height && x.NumOfComponents == y.NumOfComponents
&& x.ComponentDepth == y.ComponentDepth && x.EffectiveRect == y.EffectiveRect;
}
/// <summary>
/// Determines whether the specified <see cref="ImageInfo"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="ImageInfo"/></param>
/// <param name="y">The second <see cref="ImageInfo"/></param>
/// <returns>True if the <see cref="ImageInfo"/>s are unequal; otherwise, false</returns>
public static bool operator !=(ImageInfo x, ImageInfo y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="ImageInfo"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="ImageInfo"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="ImageInfo"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is ImageInfo && this == (ImageInfo)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="ImageInfo"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="ImageInfo"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ Width.GetHashCode();
hash *= 16777619 ^ Height.GetHashCode();
hash *= 16777619 ^ NumOfComponents.GetHashCode();
hash *= 16777619 ^ ComponentDepth.GetHashCode();
hash *= 16777619 ^ EffectiveRect.GetHashCode();
return hash;
}
}
}
/// <summary>
/// SaveImage Setting
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct SaveImageSetting
{
/// <summary>
/// Quality of Jpeg file (1-10)
/// </summary>
public int JPEGQuality;
/// <summary>
/// Pointer to ICC profile stream
/// </summary>
public IntPtr ICCProfileStream;
private uint Reserved;
/// <summary>
/// Determines whether the specified <see cref="SaveImageSetting"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="SaveImageSetting"/></param>
/// <param name="y">The second <see cref="SaveImageSetting"/></param>
/// <returns>True if the <see cref="SaveImageSetting"/>s are equal; otherwise, false</returns>
public static bool operator ==(SaveImageSetting x, SaveImageSetting y)
{
return x.JPEGQuality == y.JPEGQuality && x.ICCProfileStream == y.ICCProfileStream;
}
/// <summary>
/// Determines whether the specified <see cref="SaveImageSetting"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="SaveImageSetting"/></param>
/// <param name="y">The second <see cref="SaveImageSetting"/></param>
/// <returns>True if the <see cref="SaveImageSetting"/>s are unequal; otherwise, false</returns>
public static bool operator !=(SaveImageSetting x, SaveImageSetting y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="SaveImageSetting"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="SaveImageSetting"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="SaveImageSetting"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is SaveImageSetting && this == (SaveImageSetting)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="SaveImageSetting"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="SaveImageSetting"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ JPEGQuality.GetHashCode();
hash *= 16777619 ^ ICCProfileStream.GetHashCode();
return hash;
}
}
}
/// <summary>
/// Property Description
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct PropertyDesc
{
/// <summary>
/// Form
/// </summary>
public int Form;
/// <summary>
/// Accessibility
/// </summary>
public int Access;
/// <summary>
/// Number of elements
/// </summary>
public int NumElements;
/// <summary>
/// Array of all elements
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public int[] PropDesc;
/// <summary>
/// Determines whether the specified <see cref="PropertyDesc"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="PropertyDesc"/></param>
/// <param name="y">The second <see cref="PropertyDesc"/></param>
/// <returns>True if the <see cref="PropertyDesc"/>s are equal; otherwise, false</returns>
public static bool operator ==(PropertyDesc x, PropertyDesc y)
{
return x.Form == y.Form && x.Access == y.Access && x.NumElements == y.NumElements && x.PropDesc.SequenceEqual(y.PropDesc);
}
/// <summary>
/// Determines whether the specified <see cref="PropertyDesc"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="PropertyDesc"/></param>
/// <param name="y">The second <see cref="PropertyDesc"/></param>
/// <returns>True if the <see cref="PropertyDesc"/>s are unequal; otherwise, false</returns>
public static bool operator !=(PropertyDesc x, PropertyDesc y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="PropertyDesc"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="PropertyDesc"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="PropertyDesc"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is PropertyDesc && this == (PropertyDesc)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="Time"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="Time"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ Form.GetHashCode();
hash *= 16777619 ^ Access.GetHashCode();
hash *= 16777619 ^ NumElements.GetHashCode();
hash *= 16777619 ^ PropDesc.GetHashCode();
return hash;
}
}
}
/// <summary>
/// Picture Style Description
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct PictureStyleDesc
{
/// <summary>
/// Contrast; Range: -4 to 4
/// </summary>
public int Contrast;
/// <summary>
/// Sharpness; Range: 0 to 7
/// </summary>
public int Sharpness;
/// <summary>
/// Saturation; Range: -4 to 4
/// </summary>
public int Saturation;
/// <summary>
/// ColorTone; Range: -4 to 4
/// </summary>
public int ColorTone;
/// <summary>
/// Filter Effect
/// </summary>
public FilterEffect FilterEffect;
/// <summary>
/// Toning Effect
/// </summary>
public ToningEffect ToningEffect;
/// <summary>
/// Sharp Fineness
/// </summary>
public int SharpFineness;
/// <summary>
/// Sharp Threshold
/// </summary>
public int SharpThreshold;
/// <summary>
/// Creates a new instance of the <see cref="PictureStyleDesc"/> struct
/// </summary>
/// <param name="Contrast">Range: -4 to 4</param>
/// <param name="Sharpness">Range: 0 to 7</param>
/// <param name="Saturation">Range: -4 to 4</param>
/// <param name="ColorTone">Range: -4 to 4</param>
/// <param name="FilterEffect">Filter Effect</param>
/// <param name="ToningEffect">Toning Effect</param>
public PictureStyleDesc(int Contrast, int Sharpness, int Saturation, int ColorTone, int FilterEffect, int ToningEffect)
{
this.Contrast = Math.Min(4, Math.Max(-4, Contrast));
this.Sharpness = Math.Min(7, Math.Max(0, Sharpness));
this.Saturation = Math.Min(4, Math.Max(-4, Saturation));
this.ColorTone = Math.Min(4, Math.Max(-4, ColorTone));
this.FilterEffect = (FilterEffect)FilterEffect;
this.ToningEffect = (ToningEffect)ToningEffect;
SharpFineness = 0;
SharpThreshold = 0;
}
/// <summary>
/// Determines whether the specified <see cref="PictureStyleDesc"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="PictureStyleDesc"/></param>
/// <param name="y">The second <see cref="PictureStyleDesc"/></param>
/// <returns>True if the <see cref="PictureStyleDesc"/>s are equal; otherwise, false</returns>
public static bool operator ==(PictureStyleDesc x, PictureStyleDesc y)
{
return x.Contrast == y.Contrast && x.Sharpness == y.Sharpness && x.Saturation == y.Saturation && x.ColorTone == y.ColorTone
&& x.FilterEffect == y.FilterEffect && x.ToningEffect == y.ToningEffect;
}
/// <summary>
/// Determines whether the specified <see cref="PictureStyleDesc"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="PictureStyleDesc"/></param>
/// <param name="y">The second <see cref="PictureStyleDesc"/></param>
/// <returns>True if the <see cref="PictureStyleDesc"/>s are unequal; otherwise, false</returns>
public static bool operator !=(PictureStyleDesc x, PictureStyleDesc y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="PictureStyleDesc"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="PictureStyleDesc"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="PictureStyleDesc"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is PictureStyleDesc && this == (PictureStyleDesc)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="PictureStyleDesc"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="PictureStyleDesc"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ Contrast.GetHashCode();
hash *= 16777619 ^ Sharpness.GetHashCode();
hash *= 16777619 ^ Saturation.GetHashCode();
hash *= 16777619 ^ ColorTone.GetHashCode();
hash *= 16777619 ^ FilterEffect.GetHashCode();
hash *= 16777619 ^ ToningEffect.GetHashCode();
return hash;
}
}
}
/// <summary>
/// PictureStyleDesc struct for SDK versions &lt;3.2
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct PictureStyleDesc_3_2
{
public int Contrast;
public int Sharpness;
public int Saturation;
public int ColorTone;
public FilterEffect FilterEffect;
public ToningEffect ToningEffect;
public PictureStyleDesc ToCurrent()
{
return new PictureStyleDesc
{
Contrast = Contrast,
Sharpness = Sharpness,
Saturation = Saturation,
ColorTone = ColorTone,
FilterEffect = FilterEffect,
ToningEffect = ToningEffect,
};
}
}
/// <summary>
/// Focus Point
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct FocusPoint
{
/// <summary>
/// <para>Invalid AF frame: 0</para>
/// <para>Valid AF frame: 1</para>
/// <para>Note: There are as many valid AF frames as the number in
/// FrameNumber. Usually, AF frames are recorded consecutively, starting with 0.</para>
/// <para>Note: AF frame coordinates and the array number for storage vary by model.</para>
/// </summary>
public int Valid;
/// <summary>
/// <para>Selected AF frame: 0</para>
/// <para>Unselected AF frame: 1</para>
/// </summary>
public int Selected;
/// <summary>
/// <para>In focus: 1</para>
/// <para>Out of focus: 0</para>
/// </summary>
public int JustFocus;
/// <summary>
/// Upper-left and lower-right coordinates of the AF frame
/// </summary>
public Rectangle Rectangle;
private uint Reserved;
/// <summary>
/// Determines whether the specified <see cref="FocusPoint"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="FocusPoint"/></param>
/// <param name="y">The second <see cref="FocusPoint"/></param>
/// <returns>True if the <see cref="FocusPoint"/>s are equal; otherwise, false</returns>
public static bool operator ==(FocusPoint x, FocusPoint y)
{
return x.Valid == y.Valid && x.Selected == y.Selected && x.JustFocus == y.JustFocus && x.Rectangle == y.Rectangle;
}
/// <summary>
/// Determines whether the specified <see cref="FocusPoint"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="FocusPoint"/></param>
/// <param name="y">The second <see cref="FocusPoint"/></param>
/// <returns>True if the <see cref="FocusPoint"/>s are unequal; otherwise, false</returns>
public static bool operator !=(FocusPoint x, FocusPoint y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="FocusPoint"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="FocusPoint"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="FocusPoint"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is FocusPoint && this == (FocusPoint)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="Time"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="Time"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ Valid.GetHashCode();
hash *= 16777619 ^ Selected.GetHashCode();
hash *= 16777619 ^ JustFocus.GetHashCode();
hash *= 16777619 ^ Rectangle.GetHashCode();
return hash;
}
}
}
/// <summary>
/// Focus Info
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct FocusInfo
{
/// <summary>
/// The upper-left coordinates of the image, as well as the width and height
/// </summary>
public Rectangle ImageRectangle;
/// <summary>
/// AF frame number
/// </summary>
public int PointNumber;
/// <summary>
/// Detailed information about focus points
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public FocusPoint[] FocusPoints;
/// <summary>
/// Execute Mode
/// </summary>
public int ExecuteMode;
/// <summary>
/// Determines whether the specified <see cref="FocusInfo"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="FocusInfo"/></param>
/// <param name="y">The second <see cref="FocusInfo"/></param>
/// <returns>True if the <see cref="FocusInfo"/>s are equal; otherwise, false</returns>
public static bool operator ==(FocusInfo x, FocusInfo y)
{
return x.ImageRectangle == y.ImageRectangle && x.PointNumber == y.PointNumber
&& x.FocusPoints.SequenceEqual(y.FocusPoints) && x.ExecuteMode == y.ExecuteMode;
}
/// <summary>
/// Determines whether the specified <see cref="FocusInfo"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="FocusInfo"/></param>
/// <param name="y">The second <see cref="FocusInfo"/></param>
/// <returns>True if the <see cref="FocusInfo"/>s are unequal; otherwise, false</returns>
public static bool operator !=(FocusInfo x, FocusInfo y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="FocusInfo"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="FocusInfo"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="FocusInfo"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is FocusInfo && this == (FocusInfo)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="FocusInfo"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="FocusInfo"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ ImageRectangle.GetHashCode();
hash *= 16777619 ^ PointNumber.GetHashCode();
hash *= 16777619 ^ FocusPoints.GetHashCode();
hash *= 16777619 ^ ExecuteMode.GetHashCode();
return hash;
}
}
}
/// <summary>
/// User WhiteBalance (PC set1,2,3); User ToneCurve; User PictureStyle dataset
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct UsersetData
{
/// <summary>
/// Marker if data is valid
/// </summary>
public int Valid;
/// <summary>
/// Size of data
/// </summary>
public int DataSize;
/// <summary>
/// Caption
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string Caption;
/// <summary>
/// Data
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public byte[] Data;
/// <summary>
/// Determines whether the specified <see cref="UsersetData"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="UsersetData"/></param>
/// <param name="y">The second <see cref="UsersetData"/></param>
/// <returns>True if the <see cref="UsersetData"/>s are equal; otherwise, false</returns>
public static bool operator ==(UsersetData x, UsersetData y)
{
return x.Valid == y.Valid && x.DataSize == y.DataSize && x.Caption == y.Caption && x.Data.SequenceEqual(y.Data);
}
/// <summary>
/// Determines whether the specified <see cref="UsersetData"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="UsersetData"/></param>
/// <param name="y">The second <see cref="UsersetData"/></param>
/// <returns>True if the <see cref="UsersetData"/>s are unequal; otherwise, false</returns>
public static bool operator !=(UsersetData x, UsersetData y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="UsersetData"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="UsersetData"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="UsersetData"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is UsersetData && this == (UsersetData)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="UsersetData"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="UsersetData"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ Valid.GetHashCode();
hash *= 16777619 ^ DataSize.GetHashCode();
hash *= 16777619 ^ Caption.GetHashCode();
hash *= 16777619 ^ Data.GetHashCode();
return hash;
}
}
}
/// <summary>
/// Capacity
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 2)]
public struct Capacity
{
/// <summary>
/// Number of free clusters on the HD
/// </summary>
public int NumberOfFreeClusters;
/// <summary>
/// Bytes per HD sector
/// </summary>
public int BytesPerSector;
/// <summary>
/// Reset flag
/// </summary>
public bool Reset;
/// <summary>
/// Creates a new instance of the <see cref="Capacity"/> struct
/// </summary>
/// <param name="BytesPerSector">Bytes per HD sector</param>
/// <param name="NumberOfFreeClusters">Number of free clusters on the HD</param>
/// <param name="Reset"></param>
public Capacity(int NumberOfFreeClusters, int BytesPerSector, bool Reset)
{
this.NumberOfFreeClusters = NumberOfFreeClusters;
this.BytesPerSector = BytesPerSector;
this.Reset = Reset;
}
/// <summary>
/// Determines whether the specified <see cref="Capacity"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="Capacity"/></param>
/// <param name="y">The second <see cref="Capacity"/></param>
/// <returns>True if the <see cref="Capacity"/>s are equal; otherwise, false</returns>
public static bool operator ==(Capacity x, Capacity y)
{
return x.NumberOfFreeClusters == y.NumberOfFreeClusters && x.BytesPerSector == y.BytesPerSector && x.Reset == y.Reset;
}
/// <summary>
/// Determines whether the specified <see cref="Capacity"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="Capacity"/></param>
/// <param name="y">The second <see cref="Capacity"/></param>
/// <returns>True if the <see cref="Capacity"/>s are unequal; otherwise, false</returns>
public static bool operator !=(Capacity x, Capacity y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="Capacity"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="Capacity"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="Capacity"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is Capacity && this == (Capacity)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="Capacity"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="Capacity"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ NumberOfFreeClusters.GetHashCode();
hash *= 16777619 ^ BytesPerSector.GetHashCode();
hash *= 16777619 ^ Reset.GetHashCode();
return hash;
}
}
}
/// <summary>
/// MyMenu Items
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct MyMenuItems
{
/// <summary>
/// Menu Item 1
/// </summary>
public MyMenuID MenuItem1;
/// <summary>
/// Menu Item 2
/// </summary>
public MyMenuID MenuItem2;
/// <summary>
/// Menu Item 3
/// </summary>
public MyMenuID MenuItem3;
/// <summary>
/// Menu Item 4
/// </summary>
public MyMenuID MenuItem4;
/// <summary>
/// Menu Item 5
/// </summary>
public MyMenuID MenuItem5;
/// <summary>
/// Menu Item 6
/// </summary>
public MyMenuID MenuItem6;
/// <summary>
/// Creates a new instance of the <see cref="MyMenuItems"/> struct
/// </summary>
/// <param name="items">Array of items (max length is 6)</param>
/// <exception cref="ArgumentNullException">The array of given items is null</exception>
public MyMenuItems(params MyMenuID[] items)
{
if (items == null) throw new ArgumentNullException(nameof(items));
MenuItem1 = MenuItem2 = MenuItem3 = MenuItem4 = MenuItem5 = MenuItem6 = MyMenuID.NotSet;
if (items.Length > 0) MenuItem1 = items[0];
if (items.Length > 1) MenuItem2 = items[1];
if (items.Length > 2) MenuItem3 = items[2];
if (items.Length > 3) MenuItem4 = items[3];
if (items.Length > 4) MenuItem5 = items[4];
if (items.Length > 5) MenuItem6 = items[5];
}
/// <summary>
/// Determines whether the specified <see cref="MyMenuItems"/>s are equal to each other.
/// </summary>
/// <param name="x">The first <see cref="MyMenuItems"/></param>
/// <param name="y">The second <see cref="MyMenuItems"/></param>
/// <returns>True if the <see cref="MyMenuItems"/>s are equal; otherwise, false</returns>
public static bool operator ==(MyMenuItems x, MyMenuItems y)
{
return x.MenuItem1 == y.MenuItem1
&& x.MenuItem2 == y.MenuItem2
&& x.MenuItem3 == y.MenuItem3
&& x.MenuItem4 == y.MenuItem4
&& x.MenuItem5 == y.MenuItem5
&& x.MenuItem6 == y.MenuItem6;
}
/// <summary>
/// Determines whether the specified <see cref="MyMenuItems"/>s are unequal to each other.
/// </summary>
/// <param name="x">The first <see cref="MyMenuItems"/></param>
/// <param name="y">The second <see cref="MyMenuItems"/></param>
/// <returns>True if the <see cref="MyMenuItems"/>s are unequal; otherwise, false</returns>
public static bool operator !=(MyMenuItems x, MyMenuItems y)
{
return !(x == y);
}
/// <summary>
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="MyMenuItems"/>.
/// </summary>
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="MyMenuItems"/></param>
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="MyMenuItems"/>; otherwise, false.</returns>
public override bool Equals(object obj)
{
return obj is MyMenuItems && this == (MyMenuItems)obj;
}
/// <summary>
/// Serves as a hash function for a <see cref="MyMenuItems"/>.
/// </summary>
/// <returns>A hash code for the current <see cref="MyMenuItems"/></returns>
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash *= 16777619 ^ MenuItem1.GetHashCode();
hash *= 16777619 ^ MenuItem2.GetHashCode();
hash *= 16777619 ^ MenuItem3.GetHashCode();
hash *= 16777619 ^ MenuItem4.GetHashCode();
hash *= 16777619 ^ MenuItem5.GetHashCode();
hash *= 16777619 ^ MenuItem6.GetHashCode();
return hash;
}
}
}
}

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34728.123
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kivii.Client.Canon.V4.5", "Src\Kivii.Client.Canon.V4.5.csproj", "{08FA5081-59F1-4E6A-B44C-309EF67159E6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EDSDKLib", "EDSDKLib\Src\EDSDKLib.csproj", "{29A4AE92-DECF-4EDE-849F-4295FFA48209}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{08FA5081-59F1-4E6A-B44C-309EF67159E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08FA5081-59F1-4E6A-B44C-309EF67159E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08FA5081-59F1-4E6A-B44C-309EF67159E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08FA5081-59F1-4E6A-B44C-309EF67159E6}.Release|Any CPU.Build.0 = Release|Any CPU
{29A4AE92-DECF-4EDE-849F-4295FFA48209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{29A4AE92-DECF-4EDE-849F-4295FFA48209}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29A4AE92-DECF-4EDE-849F-4295FFA48209}.Release|Any CPU.ActiveCfg = Release|Any CPU
{29A4AE92-DECF-4EDE-849F-4295FFA48209}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9B3B0DFC-C021-41FA-A472-6DE4F06DAB92}
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
\ No newline at end of file
namespace Kivii.Canon
{
partial class CanonForm
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.FocusFar1Button = new System.Windows.Forms.Button();
this.FocusNear2Button = new System.Windows.Forms.Button();
this.MainProgressBar = new System.Windows.Forms.ProgressBar();
this.SavePathTextBox = new System.Windows.Forms.TextBox();
this.BrowseButton = new System.Windows.Forms.Button();
this.SaveToGroupBox = new System.Windows.Forms.GroupBox();
this.STBothRdButton = new System.Windows.Forms.RadioButton();
this.STComputerRdButton = new System.Windows.Forms.RadioButton();
this.STCameraRdButton = new System.Windows.Forms.RadioButton();
this.FocusNear1Button = new System.Windows.Forms.Button();
this.FocusNear3Button = new System.Windows.Forms.Button();
this.LiveViewButton = new System.Windows.Forms.Button();
this.label4 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.TakePhotoButton = new System.Windows.Forms.Button();
this.BulbUpDo = new System.Windows.Forms.NumericUpDown();
this.RefreshButton = new System.Windows.Forms.Button();
this.CameraListBox = new System.Windows.Forms.ListBox();
this.SessionLabel = new System.Windows.Forms.Label();
this.InitGroupBox = new System.Windows.Forms.GroupBox();
this.SessionButton = new System.Windows.Forms.Button();
this.SaveFolderBrowser = new System.Windows.Forms.FolderBrowserDialog();
this.ISOCoBox = new System.Windows.Forms.ComboBox();
this.FocusFar3Button = new System.Windows.Forms.Button();
this.LiveViewGroupBox = new System.Windows.Forms.GroupBox();
this.FocusFar2Button = new System.Windows.Forms.Button();
this.LiveViewPicBox = new System.Windows.Forms.PictureBox();
this.TvCoBox = new System.Windows.Forms.ComboBox();
this.AvCoBox = new System.Windows.Forms.ComboBox();
this.SettingsGroupBox = new System.Windows.Forms.GroupBox();
this.SaveToGroupBox.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.BulbUpDo)).BeginInit();
this.InitGroupBox.SuspendLayout();
this.LiveViewGroupBox.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.LiveViewPicBox)).BeginInit();
this.SettingsGroupBox.SuspendLayout();
this.SuspendLayout();
//
// FocusFar1Button
//
this.FocusFar1Button.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FocusFar1Button.Location = new System.Drawing.Point(277, 18);
this.FocusFar1Button.Name = "FocusFar1Button";
this.FocusFar1Button.Size = new System.Drawing.Size(28, 21);
this.FocusFar1Button.TabIndex = 6;
this.FocusFar1Button.Text = ">";
this.FocusFar1Button.UseVisualStyleBackColor = true;
this.FocusFar1Button.Click += new System.EventHandler(this.FocusFar1Button_Click);
//
// FocusNear2Button
//
this.FocusNear2Button.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FocusNear2Button.Location = new System.Drawing.Point(209, 18);
this.FocusNear2Button.Name = "FocusNear2Button";
this.FocusNear2Button.Size = new System.Drawing.Size(28, 21);
this.FocusNear2Button.TabIndex = 6;
this.FocusNear2Button.Text = "<<";
this.FocusNear2Button.UseVisualStyleBackColor = true;
this.FocusNear2Button.Click += new System.EventHandler(this.FocusNear2Button_Click);
//
// MainProgressBar
//
this.MainProgressBar.Location = new System.Drawing.Point(6, 92);
this.MainProgressBar.Name = "MainProgressBar";
this.MainProgressBar.Size = new System.Drawing.Size(282, 18);
this.MainProgressBar.TabIndex = 8;
//
// SavePathTextBox
//
this.SavePathTextBox.Enabled = false;
this.SavePathTextBox.Location = new System.Drawing.Point(6, 116);
this.SavePathTextBox.Name = "SavePathTextBox";
this.SavePathTextBox.Size = new System.Drawing.Size(282, 21);
this.SavePathTextBox.TabIndex = 6;
//
// BrowseButton
//
this.BrowseButton.Enabled = false;
this.BrowseButton.Location = new System.Drawing.Point(294, 114);
this.BrowseButton.Name = "BrowseButton";
this.BrowseButton.Size = new System.Drawing.Size(99, 21);
this.BrowseButton.TabIndex = 5;
this.BrowseButton.Text = "Browse";
this.BrowseButton.UseVisualStyleBackColor = true;
this.BrowseButton.Click += new System.EventHandler(this.BrowseButton_Click);
//
// SaveToGroupBox
//
this.SaveToGroupBox.Controls.Add(this.STBothRdButton);
this.SaveToGroupBox.Controls.Add(this.STComputerRdButton);
this.SaveToGroupBox.Controls.Add(this.STCameraRdButton);
this.SaveToGroupBox.Location = new System.Drawing.Point(297, 18);
this.SaveToGroupBox.Name = "SaveToGroupBox";
this.SaveToGroupBox.Size = new System.Drawing.Size(96, 92);
this.SaveToGroupBox.TabIndex = 4;
this.SaveToGroupBox.TabStop = false;
this.SaveToGroupBox.Text = "Save To";
//
// STBothRdButton
//
this.STBothRdButton.AutoSize = true;
this.STBothRdButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.STBothRdButton.Location = new System.Drawing.Point(6, 66);
this.STBothRdButton.Name = "STBothRdButton";
this.STBothRdButton.Size = new System.Drawing.Size(52, 20);
this.STBothRdButton.TabIndex = 0;
this.STBothRdButton.Text = "Both";
this.STBothRdButton.UseVisualStyleBackColor = true;
this.STBothRdButton.Visible = false;
this.STBothRdButton.CheckedChanged += new System.EventHandler(this.SaveToRdButton_CheckedChanged);
//
// STComputerRdButton
//
this.STComputerRdButton.AutoSize = true;
this.STComputerRdButton.Checked = true;
this.STComputerRdButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.STComputerRdButton.Location = new System.Drawing.Point(6, 42);
this.STComputerRdButton.Name = "STComputerRdButton";
this.STComputerRdButton.Size = new System.Drawing.Size(83, 20);
this.STComputerRdButton.TabIndex = 0;
this.STComputerRdButton.TabStop = true;
this.STComputerRdButton.Text = "Computer";
this.STComputerRdButton.UseVisualStyleBackColor = true;
this.STComputerRdButton.CheckedChanged += new System.EventHandler(this.SaveToRdButton_CheckedChanged);
//
// STCameraRdButton
//
this.STCameraRdButton.AutoSize = true;
this.STCameraRdButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.STCameraRdButton.Location = new System.Drawing.Point(6, 18);
this.STCameraRdButton.Name = "STCameraRdButton";
this.STCameraRdButton.Size = new System.Drawing.Size(73, 20);
this.STCameraRdButton.TabIndex = 0;
this.STCameraRdButton.Text = "Camera";
this.STCameraRdButton.UseVisualStyleBackColor = true;
this.STCameraRdButton.Visible = false;
this.STCameraRdButton.CheckedChanged += new System.EventHandler(this.SaveToRdButton_CheckedChanged);
//
// FocusNear1Button
//
this.FocusNear1Button.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FocusNear1Button.Location = new System.Drawing.Point(243, 18);
this.FocusNear1Button.Name = "FocusNear1Button";
this.FocusNear1Button.Size = new System.Drawing.Size(28, 21);
this.FocusNear1Button.TabIndex = 6;
this.FocusNear1Button.Text = "<";
this.FocusNear1Button.UseVisualStyleBackColor = true;
this.FocusNear1Button.Click += new System.EventHandler(this.FocusNear1Button_Click);
//
// FocusNear3Button
//
this.FocusNear3Button.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FocusNear3Button.Location = new System.Drawing.Point(175, 18);
this.FocusNear3Button.Name = "FocusNear3Button";
this.FocusNear3Button.Size = new System.Drawing.Size(28, 21);
this.FocusNear3Button.TabIndex = 6;
this.FocusNear3Button.Text = "<<<";
this.FocusNear3Button.UseVisualStyleBackColor = true;
this.FocusNear3Button.Click += new System.EventHandler(this.FocusNear3Button_Click);
//
// LiveViewButton
//
this.LiveViewButton.Location = new System.Drawing.Point(8, 18);
this.LiveViewButton.Name = "LiveViewButton";
this.LiveViewButton.Size = new System.Drawing.Size(70, 20);
this.LiveViewButton.TabIndex = 2;
this.LiveViewButton.Text = "Start LV";
this.LiveViewButton.UseVisualStyleBackColor = true;
this.LiveViewButton.Click += new System.EventHandler(this.LiveViewButton_Click);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label4.Location = new System.Drawing.Point(236, 18);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(52, 16);
this.label4.TabIndex = 3;
this.label4.Text = "Bulb (s)";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label3.Location = new System.Drawing.Point(106, 68);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(29, 16);
this.label3.TabIndex = 3;
this.label3.Text = "ISO";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.Location = new System.Drawing.Point(106, 43);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(23, 16);
this.label2.TabIndex = 3;
this.label2.Text = "Tv";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(106, 18);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(23, 16);
this.label1.TabIndex = 3;
this.label1.Text = "Av";
//
// TakePhotoButton
//
this.TakePhotoButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.TakePhotoButton.Location = new System.Drawing.Point(142, 45);
this.TakePhotoButton.Name = "TakePhotoButton";
this.TakePhotoButton.Size = new System.Drawing.Size(146, 44);
this.TakePhotoButton.TabIndex = 2;
this.TakePhotoButton.Text = "Take Photo";
this.TakePhotoButton.UseVisualStyleBackColor = true;
this.TakePhotoButton.Click += new System.EventHandler(this.TakePhotoButton_Click);
//
// BulbUpDo
//
this.BulbUpDo.Location = new System.Drawing.Point(142, 18);
this.BulbUpDo.Maximum = new decimal(new int[] {
10000,
0,
0,
0});
this.BulbUpDo.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.BulbUpDo.Name = "BulbUpDo";
this.BulbUpDo.Size = new System.Drawing.Size(90, 21);
this.BulbUpDo.TabIndex = 1;
this.BulbUpDo.Value = new decimal(new int[] {
20,
0,
0,
0});
//
// RefreshButton
//
this.RefreshButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.RefreshButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.RefreshButton.Location = new System.Drawing.Point(96, 117);
this.RefreshButton.Name = "RefreshButton";
this.RefreshButton.Size = new System.Drawing.Size(31, 21);
this.RefreshButton.TabIndex = 9;
this.RefreshButton.Text = "↻";
this.RefreshButton.UseVisualStyleBackColor = true;
this.RefreshButton.Click += new System.EventHandler(this.RefreshButton_Click);
//
// CameraListBox
//
this.CameraListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.CameraListBox.FormattingEnabled = true;
this.CameraListBox.ItemHeight = 12;
this.CameraListBox.Location = new System.Drawing.Point(8, 32);
this.CameraListBox.Name = "CameraListBox";
this.CameraListBox.Size = new System.Drawing.Size(121, 76);
this.CameraListBox.TabIndex = 6;
//
// SessionLabel
//
this.SessionLabel.AutoSize = true;
this.SessionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.SessionLabel.Location = new System.Drawing.Point(6, 15);
this.SessionLabel.Name = "SessionLabel";
this.SessionLabel.Size = new System.Drawing.Size(109, 16);
this.SessionLabel.TabIndex = 8;
this.SessionLabel.Text = "No open session";
//
// InitGroupBox
//
this.InitGroupBox.Controls.Add(this.RefreshButton);
this.InitGroupBox.Controls.Add(this.CameraListBox);
this.InitGroupBox.Controls.Add(this.SessionLabel);
this.InitGroupBox.Controls.Add(this.SessionButton);
this.InitGroupBox.Location = new System.Drawing.Point(12, 12);
this.InitGroupBox.Name = "InitGroupBox";
this.InitGroupBox.Size = new System.Drawing.Size(135, 146);
this.InitGroupBox.TabIndex = 15;
this.InitGroupBox.TabStop = false;
this.InitGroupBox.Text = "Init";
//
// SessionButton
//
this.SessionButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.SessionButton.Location = new System.Drawing.Point(6, 117);
this.SessionButton.Name = "SessionButton";
this.SessionButton.Size = new System.Drawing.Size(84, 21);
this.SessionButton.TabIndex = 7;
this.SessionButton.Text = "Open Session";
this.SessionButton.UseVisualStyleBackColor = true;
this.SessionButton.Click += new System.EventHandler(this.SessionButton_Click);
//
// SaveFolderBrowser
//
this.SaveFolderBrowser.Description = "Save Images To...";
//
// ISOCoBox
//
this.ISOCoBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.ISOCoBox.FormattingEnabled = true;
this.ISOCoBox.Location = new System.Drawing.Point(6, 67);
this.ISOCoBox.Name = "ISOCoBox";
this.ISOCoBox.Size = new System.Drawing.Size(94, 20);
this.ISOCoBox.TabIndex = 0;
this.ISOCoBox.SelectedIndexChanged += new System.EventHandler(this.ISOCoBox_SelectedIndexChanged);
//
// FocusFar3Button
//
this.FocusFar3Button.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FocusFar3Button.Location = new System.Drawing.Point(345, 18);
this.FocusFar3Button.Name = "FocusFar3Button";
this.FocusFar3Button.Size = new System.Drawing.Size(28, 21);
this.FocusFar3Button.TabIndex = 6;
this.FocusFar3Button.Text = ">>>";
this.FocusFar3Button.UseVisualStyleBackColor = true;
this.FocusFar3Button.Click += new System.EventHandler(this.FocusFar3Button_Click);
//
// LiveViewGroupBox
//
this.LiveViewGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.LiveViewGroupBox.Controls.Add(this.FocusFar3Button);
this.LiveViewGroupBox.Controls.Add(this.FocusFar2Button);
this.LiveViewGroupBox.Controls.Add(this.FocusFar1Button);
this.LiveViewGroupBox.Controls.Add(this.FocusNear1Button);
this.LiveViewGroupBox.Controls.Add(this.FocusNear2Button);
this.LiveViewGroupBox.Controls.Add(this.FocusNear3Button);
this.LiveViewGroupBox.Controls.Add(this.LiveViewPicBox);
this.LiveViewGroupBox.Controls.Add(this.LiveViewButton);
this.LiveViewGroupBox.Enabled = false;
this.LiveViewGroupBox.Location = new System.Drawing.Point(12, 163);
this.LiveViewGroupBox.Name = "LiveViewGroupBox";
this.LiveViewGroupBox.Size = new System.Drawing.Size(548, 379);
this.LiveViewGroupBox.TabIndex = 16;
this.LiveViewGroupBox.TabStop = false;
this.LiveViewGroupBox.Text = "LiveView";
//
// FocusFar2Button
//
this.FocusFar2Button.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FocusFar2Button.Location = new System.Drawing.Point(311, 18);
this.FocusFar2Button.Name = "FocusFar2Button";
this.FocusFar2Button.Size = new System.Drawing.Size(28, 21);
this.FocusFar2Button.TabIndex = 6;
this.FocusFar2Button.Text = ">>";
this.FocusFar2Button.UseVisualStyleBackColor = true;
this.FocusFar2Button.Click += new System.EventHandler(this.FocusFar2Button_Click);
//
// LiveViewPicBox
//
this.LiveViewPicBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.LiveViewPicBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.LiveViewPicBox.Location = new System.Drawing.Point(10, 47);
this.LiveViewPicBox.Name = "LiveViewPicBox";
this.LiveViewPicBox.Size = new System.Drawing.Size(524, 322);
this.LiveViewPicBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.LiveViewPicBox.TabIndex = 1;
this.LiveViewPicBox.TabStop = false;
this.LiveViewPicBox.SizeChanged += new System.EventHandler(this.LiveViewPicBox_SizeChanged);
//
// TvCoBox
//
this.TvCoBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.TvCoBox.FormattingEnabled = true;
this.TvCoBox.Location = new System.Drawing.Point(6, 42);
this.TvCoBox.Name = "TvCoBox";
this.TvCoBox.Size = new System.Drawing.Size(94, 20);
this.TvCoBox.TabIndex = 0;
this.TvCoBox.SelectedIndexChanged += new System.EventHandler(this.TvCoBox_SelectedIndexChanged);
//
// AvCoBox
//
this.AvCoBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.AvCoBox.FormattingEnabled = true;
this.AvCoBox.Location = new System.Drawing.Point(6, 18);
this.AvCoBox.Name = "AvCoBox";
this.AvCoBox.Size = new System.Drawing.Size(94, 20);
this.AvCoBox.TabIndex = 0;
this.AvCoBox.SelectedIndexChanged += new System.EventHandler(this.AvCoBox_SelectedIndexChanged);
//
// SettingsGroupBox
//
this.SettingsGroupBox.Controls.Add(this.MainProgressBar);
this.SettingsGroupBox.Controls.Add(this.SavePathTextBox);
this.SettingsGroupBox.Controls.Add(this.BrowseButton);
this.SettingsGroupBox.Controls.Add(this.SaveToGroupBox);
this.SettingsGroupBox.Controls.Add(this.label4);
this.SettingsGroupBox.Controls.Add(this.label3);
this.SettingsGroupBox.Controls.Add(this.label2);
this.SettingsGroupBox.Controls.Add(this.label1);
this.SettingsGroupBox.Controls.Add(this.TakePhotoButton);
this.SettingsGroupBox.Controls.Add(this.BulbUpDo);
this.SettingsGroupBox.Controls.Add(this.ISOCoBox);
this.SettingsGroupBox.Controls.Add(this.TvCoBox);
this.SettingsGroupBox.Controls.Add(this.AvCoBox);
this.SettingsGroupBox.Enabled = false;
this.SettingsGroupBox.Location = new System.Drawing.Point(153, 12);
this.SettingsGroupBox.MinimumSize = new System.Drawing.Size(407, 146);
this.SettingsGroupBox.Name = "SettingsGroupBox";
this.SettingsGroupBox.Size = new System.Drawing.Size(407, 146);
this.SettingsGroupBox.TabIndex = 17;
this.SettingsGroupBox.TabStop = false;
this.SettingsGroupBox.Text = "Settings";
//
// CanonForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(572, 554);
this.Controls.Add(this.InitGroupBox);
this.Controls.Add(this.LiveViewGroupBox);
this.Controls.Add(this.SettingsGroupBox);
this.Name = "CanonForm";
this.Text = "Canon";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CanonForm_FormClosing);
this.SaveToGroupBox.ResumeLayout(false);
this.SaveToGroupBox.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.BulbUpDo)).EndInit();
this.InitGroupBox.ResumeLayout(false);
this.InitGroupBox.PerformLayout();
this.LiveViewGroupBox.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.LiveViewPicBox)).EndInit();
this.SettingsGroupBox.ResumeLayout(false);
this.SettingsGroupBox.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button FocusFar1Button;
private System.Windows.Forms.Button FocusNear2Button;
private System.Windows.Forms.ProgressBar MainProgressBar;
private System.Windows.Forms.TextBox SavePathTextBox;
private System.Windows.Forms.Button BrowseButton;
private System.Windows.Forms.GroupBox SaveToGroupBox;
private System.Windows.Forms.RadioButton STBothRdButton;
private System.Windows.Forms.RadioButton STComputerRdButton;
private System.Windows.Forms.RadioButton STCameraRdButton;
private System.Windows.Forms.Button FocusNear1Button;
private System.Windows.Forms.Button FocusNear3Button;
private System.Windows.Forms.Button LiveViewButton;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button TakePhotoButton;
private System.Windows.Forms.NumericUpDown BulbUpDo;
private System.Windows.Forms.Button RefreshButton;
private System.Windows.Forms.ListBox CameraListBox;
private System.Windows.Forms.Label SessionLabel;
private System.Windows.Forms.GroupBox InitGroupBox;
private System.Windows.Forms.Button SessionButton;
private System.Windows.Forms.FolderBrowserDialog SaveFolderBrowser;
private System.Windows.Forms.ComboBox ISOCoBox;
private System.Windows.Forms.Button FocusFar3Button;
private System.Windows.Forms.GroupBox LiveViewGroupBox;
private System.Windows.Forms.Button FocusFar2Button;
private System.Windows.Forms.PictureBox LiveViewPicBox;
private System.Windows.Forms.ComboBox TvCoBox;
private System.Windows.Forms.ComboBox AvCoBox;
private System.Windows.Forms.GroupBox SettingsGroupBox;
}
}
using EOSDigital.API;
using EOSDigital.SDK;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Kivii.Canon
{
public partial class CanonForm : Form
{
#region Variables
CanonAPI APIHandler;
Camera MainCamera;
CameraValue[] AvList;
CameraValue[] TvList;
CameraValue[] ISOList;
List<Camera> CamList;
bool IsInit = false;
Bitmap Evf_Bmp;
int LVBw, LVBh, w, h;
float LVBratio, LVration;
int ErrCount;
object ErrLock = new object();
object LvLock = new object();
#endregion
public CanonForm()
{
try
{
InitializeComponent();
APIHandler = new CanonAPI();
APIHandler.CameraAdded += APIHandler_CameraAdded;
ErrorHandler.SevereErrorHappened += ErrorHandler_SevereErrorHappened;
ErrorHandler.NonSevereErrorHappened += ErrorHandler_NonSevereErrorHappened;
SavePathTextBox.Text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "RemotePhoto");
SaveFolderBrowser.Description = "Save Images To...";
LiveViewPicBox.Paint += LiveViewPicBox_Paint;
LVBw = LiveViewPicBox.Width;
LVBh = LiveViewPicBox.Height;
RefreshCamera();
IsInit = true;
}
catch (DllNotFoundException) { ReportError("Canon DLLs not found!", true); }
catch (Exception ex) { ReportError(ex.Message, true); }
}
private void CanonForm_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
IsInit = false;
MainCamera?.Dispose();
APIHandler?.Dispose();
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
#region API Events
/// <summary>
/// 图片下载完成后抛出此事件
/// </summary>
public event EventHandler DownloadCompletely;
private void APIHandler_CameraAdded(CanonAPI sender)
{
try { Invoke((Action)delegate { RefreshCamera(); }); }
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void MainCamera_StateChanged(Camera sender, StateEventID eventID, int parameter)
{
try { if (eventID == StateEventID.Shutdown && IsInit) { Invoke((Action)delegate { CloseSession(); }); } }
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void MainCamera_ProgressChanged(object sender, int progress)
{
try { Invoke((Action)delegate { MainProgressBar.Value = progress; }); }
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void MainCamera_LiveViewUpdated(Camera sender, Stream img)
{
try
{
lock (LvLock)
{
Evf_Bmp?.Dispose();
Evf_Bmp = new Bitmap(img);
}
LiveViewPicBox.Invalidate();
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void MainCamera_DownloadReady(Camera sender, DownloadInfo Info)
{
try
{
string dir = null;
Invoke((Action)delegate { dir = SavePathTextBox.Text; });
sender.DownloadFile(Info, dir);
Invoke((Action)delegate { MainProgressBar.Value = 0; });
//延时等待图片下载完毕后抛出事件
var task = Task.Run(async delegate
{
var filePath = $"{dir}\\{Info.FileName}";
await Task.Delay(1500);
if (!File.Exists(filePath)) return;
if (DownloadCompletely != null)
{
DownloadCompletely(filePath, EventArgs.Empty);
}
return;
});
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void ErrorHandler_NonSevereErrorHappened(object sender, ErrorCode ex)
{
ReportError($"SDK Error code: {ex} ({((int)ex).ToString("X")})", false);
}
private void ErrorHandler_SevereErrorHappened(object sender, Exception ex)
{
ReportError(ex.Message, true);
}
#endregion
#region Session
private void SessionButton_Click(object sender, EventArgs e)
{
if (MainCamera?.SessionOpen == true) CloseSession();
else OpenSession();
}
private void RefreshButton_Click(object sender, EventArgs e)
{
try { RefreshCamera(); }
catch (Exception ex) { ReportError(ex.Message, false); }
}
#endregion
#region Settings
private void TakePhotoButton_Click(object sender, EventArgs e)
{
try
{
if ((string)TvCoBox.SelectedItem == "Bulb") MainCamera.TakePhotoBulb((int)BulbUpDo.Value);
else MainCamera.TakePhotoShutter();
//if ((string)TvCoBox.SelectedItem == "Bulb") MainCamera.TakePhotoBulbAsync((int)BulbUpDo.Value);
//else MainCamera.TakePhotoShutterAsync();
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void BrowseButton_Click(object sender, EventArgs e)
{
try
{
if (Directory.Exists(SavePathTextBox.Text)) SaveFolderBrowser.SelectedPath = SavePathTextBox.Text;
if (SaveFolderBrowser.ShowDialog() == DialogResult.OK)
{
SavePathTextBox.Text = SaveFolderBrowser.SelectedPath;
}
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void AvCoBox_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (AvCoBox.SelectedIndex < 0) return;
MainCamera.SetSetting(PropertyID.Av, AvValues.GetValue((string)AvCoBox.SelectedItem).IntValue);
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void TvCoBox_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (TvCoBox.SelectedIndex < 0) return;
MainCamera.SetSetting(PropertyID.Tv, TvValues.GetValue((string)TvCoBox.SelectedItem).IntValue);
BulbUpDo.Enabled = (string)TvCoBox.SelectedItem == "Bulb";
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void ISOCoBox_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (ISOCoBox.SelectedIndex < 0) return;
MainCamera.SetSetting(PropertyID.ISO, ISOValues.GetValue((string)ISOCoBox.SelectedItem).IntValue);
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void SaveToRdButton_CheckedChanged(object sender, EventArgs e)
{
try
{
if (IsInit)
{
if (STCameraRdButton.Checked)
{
MainCamera.SetSetting(PropertyID.SaveTo, (int)SaveTo.Camera);
BrowseButton.Enabled = false;
SavePathTextBox.Enabled = false;
}
else
{
if (STComputerRdButton.Checked) MainCamera.SetSetting(PropertyID.SaveTo, (int)SaveTo.Host);
else if (STBothRdButton.Checked) MainCamera.SetSetting(PropertyID.SaveTo, (int)SaveTo.Both);
MainCamera.SetCapacity(4096, int.MaxValue);
BrowseButton.Enabled = true;
SavePathTextBox.Enabled = true;
}
}
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
#endregion
#region Live view
private void LiveViewButton_Click(object sender, EventArgs e)
{
try
{
if (!MainCamera.IsLiveViewOn) { MainCamera.StartLiveView(); LiveViewButton.Text = "Stop LV"; }
else { MainCamera.StopLiveView(); LiveViewButton.Text = "Start LV"; }
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void LiveViewPicBox_SizeChanged(object sender, EventArgs e)
{
try
{
LVBw = LiveViewPicBox.Width;
LVBh = LiveViewPicBox.Height;
LiveViewPicBox.Invalidate();
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void LiveViewPicBox_Paint(object sender, PaintEventArgs e)
{
if (MainCamera == null || !MainCamera.SessionOpen) return;
if (!MainCamera.IsLiveViewOn) e.Graphics.Clear(BackColor);
else
{
lock (LvLock)
{
if (Evf_Bmp != null)
{
LVBratio = LVBw / (float)LVBh;
LVration = Evf_Bmp.Width / (float)Evf_Bmp.Height;
if (LVBratio < LVration)
{
w = LVBw;
h = (int)(LVBw / LVration);
}
else
{
w = (int)(LVBh * LVration);
h = LVBh;
}
e.Graphics.DrawImage(Evf_Bmp, 0, 0, w, h);
}
}
}
}
private void FocusNear3Button_Click(object sender, EventArgs e)
{
try { MainCamera.SendCommand(CameraCommand.DriveLensEvf, (int)DriveLens.Near3); }
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void FocusNear2Button_Click(object sender, EventArgs e)
{
try { MainCamera.SendCommand(CameraCommand.DriveLensEvf, (int)DriveLens.Near2); }
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void FocusNear1Button_Click(object sender, EventArgs e)
{
try { MainCamera.SendCommand(CameraCommand.DriveLensEvf, (int)DriveLens.Near1); }
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void FocusFar1Button_Click(object sender, EventArgs e)
{
try { MainCamera.SendCommand(CameraCommand.DriveLensEvf, (int)DriveLens.Far1); }
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void FocusFar2Button_Click(object sender, EventArgs e)
{
try { MainCamera.SendCommand(CameraCommand.DriveLensEvf, (int)DriveLens.Far2); }
catch (Exception ex) { ReportError(ex.Message, false); }
}
private void FocusFar3Button_Click(object sender, EventArgs e)
{
try { MainCamera.SendCommand(CameraCommand.DriveLensEvf, (int)DriveLens.Far3); }
catch (Exception ex) { ReportError(ex.Message, false); }
}
#endregion
#region Subroutines
private void CloseSession()
{
MainCamera.CloseSession();
AvCoBox.Items.Clear();
TvCoBox.Items.Clear();
ISOCoBox.Items.Clear();
SettingsGroupBox.Enabled = false;
LiveViewGroupBox.Enabled = false;
SessionButton.Text = "Open Session";
SessionLabel.Text = "No open session";
LiveViewButton.Text = "Start LV";
}
private void RefreshCamera()
{
CameraListBox.Items.Clear();
CamList = APIHandler.GetCameraList();
foreach (Camera cam in CamList) CameraListBox.Items.Add(cam.DeviceName);
if (MainCamera?.SessionOpen == true) CameraListBox.SelectedIndex = CamList.FindIndex(t => t.ID == MainCamera.ID);
else if (CamList.Count > 0) CameraListBox.SelectedIndex = 0;
}
private void OpenSession()
{
if (CameraListBox.SelectedIndex >= 0)
{
MainCamera = CamList[CameraListBox.SelectedIndex];
MainCamera.OpenSession();
MainCamera.LiveViewUpdated += MainCamera_LiveViewUpdated;
MainCamera.ProgressChanged += MainCamera_ProgressChanged;
MainCamera.StateChanged += MainCamera_StateChanged;
MainCamera.DownloadReady += MainCamera_DownloadReady;
SessionButton.Text = "Close Session";
SessionLabel.Text = MainCamera.DeviceName;
AvList = MainCamera.GetSettingsList(PropertyID.Av);
TvList = MainCamera.GetSettingsList(PropertyID.Tv);
ISOList = MainCamera.GetSettingsList(PropertyID.ISO);
foreach (var Av in AvList) AvCoBox.Items.Add(Av.StringValue);
foreach (var Tv in TvList) TvCoBox.Items.Add(Tv.StringValue);
foreach (var ISO in ISOList) ISOCoBox.Items.Add(ISO.StringValue);
AvCoBox.SelectedIndex = AvCoBox.Items.IndexOf(AvValues.GetValue(MainCamera.GetInt32Setting(PropertyID.Av)).StringValue);
TvCoBox.SelectedIndex = TvCoBox.Items.IndexOf(TvValues.GetValue(MainCamera.GetInt32Setting(PropertyID.Tv)).StringValue);
ISOCoBox.SelectedIndex = ISOCoBox.Items.IndexOf(ISOValues.GetValue(MainCamera.GetInt32Setting(PropertyID.ISO)).StringValue);
SettingsGroupBox.Enabled = true;
LiveViewGroupBox.Enabled = true;
SaveToRdButton_CheckedChanged(null, null);
}
}
private void ReportError(string message, bool lockdown)
{
int errc;
lock (ErrLock) { errc = ++ErrCount; }
if (lockdown) EnableUI(false);
if (errc < 4) MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
else if (errc == 4) MessageBox.Show("Many errors happened!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
lock (ErrLock) { ErrCount--; }
}
private void EnableUI(bool enable)
{
if (InvokeRequired) Invoke((Action)delegate { EnableUI(enable); });
else
{
SettingsGroupBox.Enabled = enable;
InitGroupBox.Enabled = enable;
LiveViewGroupBox.Enabled = enable;
}
}
#endregion
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="SaveFolderBrowser.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{08FA5081-59F1-4E6A-B44C-309EF67159E6}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Kivii.Canon</RootNamespace>
<AssemblyName>Kivii.Client.Canon.V4.5</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="CanonForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="CanonForm.Designer.cs">
<DependentUpon>CanonForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="CanonForm.resx">
<DependentUpon>CanonForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EDSDKLib\Src\EDSDKLib.csproj">
<Project>{29a4ae92-decf-4ede-849f-4295ffa48209}</Project>
<Name>EDSDKLib</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Kivii.Canon
{
internal static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new CanonForm());
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Kivii.Client.Canon.V4.5")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Kivii.Client.Canon.V4.5")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("08fa5081-59f1-4e6a-b44c-309ef67159e6")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Kivii.Canon.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Kivii.Canon.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
\ No newline at end of file
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Kivii.Canon.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.9.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment