PDA

View Full Version : Canon SDK and Delphi


emklap
23rd of November 2003 (Sun), 10:49
I am using Canon SDK together with Delphi but can't get the procedure CDGetDevicePropertyData to work.

The variant part keeps compile error's and chang the API to pointers doesn't give any better results.

I want to read the camera properties line Model ID and Model name.

Can anyone add some working code .

I also get execption when readich the camera's custom functions in stead of a nice error message.

atleypnorth
23rd of November 2003 (Sun), 15:20
Which version of the SDK are you using ?

emklap
24th of November 2003 (Mon), 02:18
I'm using SDK 6.0 and delphi 6

atleypnorth
24th of November 2003 (Mon), 03:00
function CDGetDevicePropertyData(
hSource :cdHSource;
DevPropID :cdDevicePropertyID;
var pBufSize :cdUInt32;
var pBuf :cdVoid;
Option :cdUInt32
):cdUInt32 ; stdcall;external cdsdk;

(I think all the types are defined in delphi files supplied as demos with the SDK).

What kind of exception do you get with the custom function calls ?

emklap
24th of November 2003 (Mon), 09:53
I alraady know the API, but calling this API constanly creates complier error's because Pbuf is a variant type (cdVoid=Variant) . The result is that I do not get it compled properly.

I would like see some code that makes use of this function to see what I do wrong. It should contain the variable declarations and the code calling this function, as well as the analyses of the result.

atleypnorth
24th of November 2003 (Mon), 09:59
well Variant is defined in System ... so if it isnt compiling then it sounds like something is up with Dellphi ?

I will see if can put a demo of it together

emklap
24th of November 2003 (Mon), 12:03
I have it compled but not working yet. I count 13 device properties for my G1 and 11 for my 300D.

procedure TForm_Main.Button1Click(Sender: TObject);
var
err : cdErr;
hEnum : cdhEnum;
pCount : cdUInt32;
errStr: String;
MyStr : String;
pBufSize: cdUint32;
MyVariant : Variant;
pBuf: String[32];
ModelID: String[32];
label
ErrHandler;

begin
err:=CDEnumDevicePropertyReset(m_hSource, 0, hEnum);
if err cdOK then goto ErrHandler;
err:=CDGetDevicePropertyCount(hEnum, pCount);
if err cdOK then goto ErrHandler
else
begin
str(pCount,MyStr);
showmessage('The nr of Device functions is '+ MyStr);
end;

pBuf:=' ';
pBufSize:=32;
MyVariant:=pBuf;
err:=CDGetDevicePropertyData(m_hSource, 2, pBufSize, MyVariant, 0);
if err cdOK then goto ErrHandler;
begin
pbuf:=MyVariant;
showmessage(pBuf);
end;

CDEnumDevicePropertyRelease(hEnum);

exit;

ErrHandler:
if hEnum 0 then
CDEnumDevicePropertyRelease(hEnum);

if err cdOK then
begin
str(err,errStr);
ShowMessage('Error! '+ errStr);
end;
end;

atleypnorth
24th of November 2003 (Mon), 15:03
NB

function CDGetDevicePropertyData(
hSource :cdHSource;
DevPropID :cdDevicePropertyID;
var pBufSize :cdUInt32;
pBuf :pcdVoid;
Option :cdUInt32
):cdUInt32 ; stdcall;external cdsdk;

This different to what i said before ... pBuf is a pointer really


The following functions below work. (the checkforerror
just raises an exception if get an error result back)


procedure TForm1.Button1Click(Sender: TObject);
var
hEnum : Cardinal;
rapi : cdCAPI;
devprop :cdDevicePropertyStruct;
begin
fSDK.GetConnectedCameras;
if length(fSDK.FoundCameras) > 0 then
begin
fHandle := fSDK.OpenCamera(fSDK.FoundCameras[0]);
fSDK.CheckForError(CDEnumDevicePropertyReset(fHand le, 0, hEnum));
rapi := CDEnumDevicePropertyNext(hEnum,devprop);
while (rapi = cdOK) do
begin
ShowDevProp(devProp);
rapi := CDEnumDevicePropertyNext(hEnum,devprop);
end;
CDEnumDevicePropertyRelease(hEnum);
end;
end;

procedure TForm1.ShowDevProp(Adevprop: cdDevicePropertyStruct);
var
dint : cdUInt32;
bufSize : Cardinal;
cbuff : cdStr31;
begin
if ((ADevProp.Access and cdATTRIB_READ) = cdATTRIB_READ) or
((ADevProp.Access and cdATTRIB_READ_WRITE) = cdATTRIB_READ_WRITE) then
begin
case Adevprop.DevPropID of
cdDEVICE_PROP_BATTERY_STATUS :
begin
bufSize := sizeof(cdUInt32);
CDGetDevicePropertyData(fHandle,Adevprop.DevPropID ,bufSize,
addr(dint),0);
memo1.lines.add('BATTERY STATUS='+inttostr(dint));
end;
cdDEVICE_PROP_OWNER_NAME :
begin
FillChar(cbuff,32,0);
bufsize := 32;
CDGetDevicePropertyData(fHandle,Adevprop.DevPropID ,bufSize,
addr(cbuff[0]),0);
memo1.lines.add('PROP_OWNER_NAME='+cbuff);
end;
end;
end;
end;

emklap
25th of November 2003 (Tue), 02:23
Thans, I will give it a try tonight

emklap
25th of November 2003 (Tue), 12:45
Hi atleypnorth,

Thanks for your help, its working fine now. I see two strange things but it probably normal.

The owner name is always empty, althoug I see it correctly in the EXIF data.

The time I read from the camera is exactly 1 hour less than the actual time in the camera??? The exif data has is correct time.

See here the result of it all.

procedure TForm_Main.Button1Click(Sender: TObject);
var
hEnum : Cardinal;
Err : cdErr;
devprop :cdDevicePropertyStruct;
begin
CDEnumDevicePropertyReset(m_hSource, 0, hEnum);
Err := CDEnumDevicePropertyNext(hEnum,devprop);
while (Err = cdOK) do
begin
ShowDevProp(devProp);
Err := CDEnumDevicePropertyNext(hEnum,devprop);
end;
CDEnumDevicePropertyRelease(hEnum);
end;

procedure TForm_Main.ShowDevProp(Adevprop: cdDevicePropertyStruct);
var
dint : cdUInt32;
bufSize : Cardinal;
cbuff : cdStr31;
SlideShowCap : cdSlideShowCap;
BooleanCap : cdBoolean;

begin
if ((ADevProp.Access and cdATTRIB_READ) = cdATTRIB_READ) or
((ADevProp.Access and cdATTRIB_READ_WRITE) = cdATTRIB_READ_WRITE) then
begin
case Adevprop.DevPropID of

cdDEVICE_PROP_MODEL_ID :
begin
bufSize := sizeof(cdUInt32);
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(dint),0);
memo1.lines.add('Model ID='+inttostr(dint));
end;

cdDEVICE_PROP_MODEL_NAME :
begin
FillChar(cbuff,32,0);
bufsize := 32;
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(cbuff[0]),0);
memo1.lines.add('Model Name='+cbuff);
end;

cdDEVICE_PROP_SLIDE_SHOW_CAP :
begin
bufSize := sizeof(cdSlideShowCap);
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(SlideShowCap),0);
memo1.lines.add('Slide Show Capabilities='+inttostr(SlideShowCap));
end;

cdDEVICE_PROP_UPLOAD_FILE_CAP :
begin
bufSize := sizeof(cdBoolean);
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(BooleanCap),0);
memo1.lines.add('Upload File Capabilities='+inttostr(BooleanCap));
end;

cdDEVICE_PROP_ROTATION_CAP :
begin
bufSize := sizeof(cdBoolean);
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(BooleanCap),0);
memo1.lines.add('Upload File Capabilities='+inttostr(BooleanCap));
end;

cdDEVICE_PROP_DPOF_CAP :
begin
bufSize := sizeof(cdUInt32);
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(dint),0);
memo1.lines.add('DPOF version ='+inttostr(dint));
end;

cdDEVICE_PROP_THUMB_VALID_AREA :
begin
end;

cdDEVICE_PROP_RELEASE_CONTROL_CAP:
begin
bufSize := sizeof(cdUInt32);
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(dint),0);
memo1.lines.add('Release Control Capabilities ='+inttoHex(dint, 8));
end;

cdDEVICE_PROP_RAW_DEVELOP_FACULTIES :
begin
bufSize := sizeof(cdUInt32);
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(dint),0);
memo1.lines.add('RAW Development Capabilities ='+inttohex(dint, 8));
end;

cdDEVICE_PROP_PARSE_FACULTIES:
begin
bufSize := sizeof(cdUInt32);
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(dint),0);
memo1.lines.add('Parce Capabilities ='+inttostr(dint));
end;

cdDEVICE_PROP_OWNER_NAME :
begin
FillChar(cbuff,32,0);
bufsize := 32;
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(cbuff[0]),0);
memo1.lines.add('Owner Name='+cbuff);
end;

cdDEVICE_PROP_FIRMWARE_VERSION :
begin
FillChar(cbuff,32,0);
bufsize := 32;
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(cbuff[0]),0);
memo1.lines.add('Firmware version='+cbuff);
end;

cdDEVICE_PROP_TIME :
begin
bufSize := sizeof(cdUInt32);
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(dint),0);
memo1.lines.add('Time='+ TimeToStr(UnixToDateTime(dint+3600)));
end;

cdDEVICE_PROP_BATTERY_STATUS :
begin
bufSize := sizeof(cdUInt32);
CDGetDevicePropertyData(m_hSource,Adevprop.DevProp ID,bufSize,addr(dint),0);
memo1.lines.add('Batery Status='+inttostr(dint));
end;

end;
end;
end;

emklap
25th of November 2003 (Tue), 14:01
The "time" issue is solved. The deviation is caused by the time zone adjustment in windows. Isn't it **** that I now have to counter-correct the correction windows !!

Here the corrected line

memo1.lines.add(IntToHex(Adevprop.DevPropID,8)+': Time ='+ TimeToStr(UnixToDateTime(dint+DateTimeToUnix(Offse tFromUTC))));

The "owner name filed" has a size of zero so it suppost to be empty. But where is my name stored ? I will figure it out sometime

atleypnorth
26th of November 2003 (Wed), 02:30
glad to be of help!

the time on the camera may of been set while in DST ?
Or the SDK is thinking you are in DST and correcting
back the camera time to non DST (or the other way round !).

Had noticed the same thing with it...
Have also noticed that the owner field is always blank, might well have a bit of a look at it this afternoon ...

emklap
26th of November 2003 (Wed), 09:00
I notced that when I change my timezone in windows XP that Delphi changes the result of DateTimeToUnix.

The OffsetFromUTC function solved it for me so I don't think it's a problem any more.

There are probably more ways to read the same paramater from the camera; for instance the firmware of my G1 is 1.0.0.3 and I read 1.0.0.3 from my camera. On the other hand Breezebrowser 2.7c shows version 1.03 in the Exif data. Not that I use this parameter but ist's strange that this is different.

Downloader pro shows the correct firmware version.

emklap
26th of November 2003 (Wed), 09:27
Here is some more information on the time difference, its related to daylight saving time (this text was copied form a breezebrouwser information page http://www.photocult.de/news/downloads.html )

"Added a workaround for the Daylight Saving Time (DST) bug in Canon's SDK which resulted in the file timestamp being one hour different from the time the picture was taken when DST is in force"

Now I have to check my code again. ;-)

Here the result
memo1.lines.add(IntToHex(Adevprop.DevPropID,8)+': Time ='+ TimeToStr(UnixToDateTime(dint-60*MyTimeZoneInformation.DaylightBias)));