Advertisement
Caynadian

Sinisa-Vuk_Mtp10

Jun 2nd, 2014
1,643
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 50.77 KB | None | 0 0
  1. unit mtp_main;
  2.  
  3. interface
  4.  
  5. //*******************************************************************
  6. //Created by sinisav (dec. 2013, feb. 2014) (http://www.experts-exchange.com/M_6334433.html)
  7. //*******************************************************************
  8.  
  9. uses
  10.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  11.   Dialogs, StdCtrls, PortableDeviceApiLib_TLB, ActiveX, ComObj, ComCtrls;
  12.  
  13. // based upon following texts:
  14.  
  15. // http://cgeers.com/2011/05/22/enumerating-windows-portable-devices/
  16. // http://cgeers.com/2011/06/05/wpd-enumerating-content/
  17. // http://chocotooth.blogspot.com/2011/05/controlling-digital-camera-with-delphi_10.html
  18. // http://chocotooth.blogspot.com/2011/07/controlling-digital-camera-with-delphi.html
  19. // https://github.com/notpod/wpd-lib/blob/master/wpd-lib/WindowsPortableDevice.cs
  20. // http://gzune.googlecode.com/svn/trunk/zUnlock/portabledeviceconstants.cs
  21.  
  22. // http://msdn.microsoft.com/en-us/library/ff597727.aspx
  23.  
  24. type
  25.   TForm12 = class(TForm)
  26.     ListBox1: TListBox;
  27.     bListDev: TButton;
  28.     bListAll: TButton;
  29.     bCopyFrom: TButton;
  30.     bDelete: TButton;
  31.     SaveDialog1: TSaveDialog;
  32.     bCopyTo: TButton;
  33.     OpenDialog1: TOpenDialog;
  34.     bListTop: TButton;
  35.     Memo1: TMemo;
  36.     Label1: TLabel;
  37.     CheckBox1: TCheckBox;
  38.     ListView1: TListView;
  39.     bCopySpec: TButton;
  40.     Edit1: TEdit;
  41.     Label2: TLabel;
  42.     Label3: TLabel;
  43.     procedure bListDevClick(Sender: TObject);
  44.     procedure bListAllClick(Sender: TObject);
  45.     procedure bCopyFromClick(Sender: TObject);
  46.     procedure bDeleteClick(Sender: TObject);
  47.     procedure bCopyToClick(Sender: TObject);
  48.     procedure bListTopClick(Sender: TObject);
  49.     procedure ListBox1DblClick(Sender: TObject);
  50.     procedure ListView1DblClick(Sender: TObject);
  51.     procedure ListView1Editing(Sender: TObject; Item: TListItem;
  52.       var AllowEdit: Boolean);
  53.     procedure bCopySpecClick(Sender: TObject);
  54.     procedure ListView1DrawItem(Sender: TCustomListView; Item: TListItem;
  55.       Rect: TRect; State: TOwnerDrawState);
  56.     procedure ListView1CustomDrawItem(Sender: TCustomListView; Item: TListItem;
  57.       State: TCustomDrawState; var DefaultDraw: Boolean);
  58.   private
  59.     procedure AddLog(sText: String);
  60.     procedure ClearLog;
  61.     { Private declarations }
  62.   public
  63.     { Public declarations }
  64.   end;
  65.  
  66. var
  67.   Form12: TForm12;
  68.  
  69. implementation
  70.  
  71. uses Math;
  72.  
  73. {$R *.dfm}
  74.  
  75. procedure TForm12.ClearLog;
  76. begin
  77.   Memo1.Lines.Clear;
  78. end;
  79.  
  80. procedure TForm12.AddLog(sText: String);
  81. begin
  82.   if CheckBox1.Checked then  
  83.     Memo1.Lines.Add(sText);
  84. end;
  85.  
  86. procedure PropVariantInit(out pvar: PROPVARIANT);
  87. begin
  88.   ZeroMemory(@pvar, SizeOf(PROPVARIANT));
  89. end;
  90.  
  91. procedure StringToPropVariant(sVal: WideString; var propvarValue: tag_inner_PROPVARIANT);
  92. var
  93.   pValues: IPortableDeviceValues;
  94.   dev_val: PortableDeviceApiLib_TLB._tagpropertykey;
  95. begin
  96.   pValues :=  CreateComObject(CLASS_PortableDeviceValues) as IPortableDeviceValues;
  97.   if VarIsClear(pValues) then Exit;
  98.  
  99.   // string value into IPortableDeviceValues object
  100.   dev_val.fmtid := WPD_OBJECT_ID_FMTID;
  101.   dev_val.pid := WPD_OBJECT_ID_PID;
  102.   pValues.SetStringValue(dev_val, PWideChar(sVal));
  103.  
  104.   // get back string into a PROPVARIANT
  105.   pValues.GetValue(dev_val, propvarValue);
  106.  
  107.   pValues := nil;
  108. end;
  109.  
  110. procedure PropVariantToString(propvarValue: tag_inner_PROPVARIANT; var sVal: WideString);
  111. var
  112.   pValues: IPortableDeviceValues;
  113.   dev_val: PortableDeviceApiLib_TLB._tagpropertykey;
  114.   hr: HResult;
  115.   pVal: PWideChar;
  116. begin
  117.   sVal := '';
  118.   pValues :=  CreateComObject(CLASS_PortableDeviceValues) as IPortableDeviceValues;
  119.   if VarIsClear(pValues) then Exit;
  120.  
  121.   // PROPVARIANT into IPortableDeviceValues object
  122.   dev_val.fmtid := WPD_OBJECT_ID_FMTID;
  123.   dev_val.pid := WPD_OBJECT_ID_PID;
  124.   pValues.SetValue(dev_val, propvarValue);
  125.  
  126.   //check if it is error code
  127.   if propvarValue.vt = VT_ERROR then
  128.   begin
  129.     pValues.GetErrorValue(dev_val, hr);
  130.     sVal := SysErrorMessage(hr);
  131.   end
  132.   else
  133.   begin
  134.     // get back string
  135.     pValues.GetStringValue(dev_val, pVal);
  136.     sVal := pVal;
  137.   end;
  138.  
  139.   pValues := nil;
  140. end;
  141.  
  142. function GetDevDescription(PMan: TPortableDeviceManager; sDeviceId: WideString): WideString;
  143. var
  144.   iDevNameLen: LongWord;
  145.   iRes: Integer;
  146. begin
  147.   //get length of friendly name:
  148.   iDevNameLen := 0;
  149.   Result := '';
  150.  
  151.   iRes := PMan.GetDeviceDescription(PWideChar(sDeviceId), Word(nil^), iDevNameLen);
  152.   if iRes = S_OK then
  153.   begin
  154.     Form12.AddLog('DeviceDescription len='+IntToStr(iDevNameLen));
  155.  
  156.     //Get Description
  157.     if iDevNameLen>0 then
  158.     begin
  159.       SetLength(Result, iDevNameLen);
  160.       ZeroMemory(PWideChar(Result), iDevNameLen);
  161.       PMan.GetDeviceDescription(PWideChar(sDeviceId), PWord(PWideChar(Result))^, iDevNameLen);
  162.       Result := Trim(Result);
  163.       Form12.AddLog('DeviceDescription='+Result);
  164.     end;
  165.   end
  166.   else
  167.   begin
  168.     Form12.AddLog('Cannot GetDeviceDescription! ('+IntToStr(iRes)+')');
  169.   end;
  170. end;
  171.  
  172. function GetFriendlyName(PMan: TPortableDeviceManager; sDeviceId: WideString): WideString;
  173. var
  174.   iDevNameLen{, iType}: LongWord;
  175.   iRes: Integer;
  176. begin
  177.   //get length of friendly name:
  178.   iDevNameLen := 0;
  179.   Result := '';
  180.  
  181.   iRes := PMan.GetDeviceFriendlyName(PWideChar(sDeviceId), Word(nil^), iDevNameLen);
  182.   if iRes = S_OK then
  183.   begin
  184.     Form12.AddLog('FriendlyName len='+IntToStr(iDevNameLen));
  185.  
  186.     //Get Friendly Name
  187.     if iDevNameLen>0 then
  188.     begin
  189.       SetLength(Result, iDevNameLen);
  190.       ZeroMemory(PWideChar(Result), iDevNameLen);
  191.       PMan.GetDeviceFriendlyName(PWideChar(sDeviceId), PWord(PWideChar(Result))^, iDevNameLen);
  192.       Result := Trim(Result);
  193.       Form12.AddLog('FriendlyName='+Result);
  194.     end;
  195.   end
  196.   else
  197.   begin
  198.     Form12.AddLog('Cannot GetDeviceFriendlyName! ('+IntToStr(iRes)+')');
  199.  
  200.     Result := GetDevDescription(PMan, sDeviceId);
  201.   end;
  202. end;
  203.  
  204. function DisplayObjectFormatDesc(format_id: WideString): String;
  205. var
  206.   g: TGuid;
  207. begin
  208.   Result := format_id;
  209.   if format_id='' then Exit;
  210.  
  211.   try
  212.     g := StringToGUID(format_id);
  213.  
  214.     if IsEqualGUID(WPD_OBJECT_FORMAT_3GP, g) then Result := 'WPD_OBJECT_FORMAT_3GP'
  215.     else if IsEqualGUID(WPD_OBJECT_FORMAT_AAC, g) then Result := 'WPD_OBJECT_FORMAT_AAC'
  216.     else if IsEqualGUID(WPD_OBJECT_FORMAT_ABSTRACT_CONTACT, g) then Result := 'WPD_OBJECT_FORMAT_ABSTRACT_CONTACT'
  217.     else if IsEqualGUID(WPD_OBJECT_FORMAT_ABSTRACT_CONTACT_GROUP, g) then Result := 'WPD_OBJECT_FORMAT_ABSTRACT_CONTACT_GROUP'
  218.     else if IsEqualGUID(WPD_OBJECT_FORMAT_ABSTRACT_MEDIA_CAST, g) then Result := 'WPD_OBJECT_FORMAT_ABSTRACT_MEDIA_CAST'
  219.     else if IsEqualGUID(WPD_OBJECT_FORMAT_AIFF, g) then Result := 'WPD_OBJECT_FORMAT_AIFF'
  220.     else if IsEqualGUID(WPD_OBJECT_FORMAT_ALL, g) then Result := 'WPD_OBJECT_FORMAT_ALL'
  221.     else if IsEqualGUID(WPD_OBJECT_FORMAT_ASF, g) then Result := 'WPD_OBJECT_FORMAT_ASF'
  222.     else if IsEqualGUID(WPD_OBJECT_FORMAT_ASXPLAYLIST, g) then Result := 'WPD_OBJECT_FORMAT_ASXPLAYLIST'
  223.     else if IsEqualGUID(WPD_OBJECT_FORMAT_AUDIBLE, g) then Result := 'WPD_OBJECT_FORMAT_AUDIBLE'
  224.     else if IsEqualGUID(WPD_OBJECT_FORMAT_AVI, g) then Result := 'WPD_OBJECT_FORMAT_AVI'
  225.     else if IsEqualGUID(WPD_OBJECT_FORMAT_BMP, g) then Result := 'WPD_OBJECT_FORMAT_BMP'
  226.     else if IsEqualGUID(WPD_OBJECT_FORMAT_CIFF, g) then Result := 'WPD_OBJECT_FORMAT_CIFF'
  227.     else if IsEqualGUID(WPD_OBJECT_FORMAT_DPOF, g) then Result := 'WPD_OBJECT_FORMAT_DPOF'
  228.     else if IsEqualGUID(WPD_OBJECT_FORMAT_EXECUTABLE, g) then Result := 'WPD_OBJECT_FORMAT_EXECUTABLE'
  229.     else if IsEqualGUID(WPD_OBJECT_FORMAT_EXIF, g) then Result := 'WPD_OBJECT_FORMAT_EXIF'
  230.     else if IsEqualGUID(WPD_OBJECT_FORMAT_FLAC, g) then Result := 'WPD_OBJECT_FORMAT_FLAC'
  231.     else if IsEqualGUID(WPD_OBJECT_FORMAT_FLASHPIX, g) then Result := 'WPD_OBJECT_FORMAT_FLASHPIX'
  232.     else if IsEqualGUID(WPD_OBJECT_FORMAT_GIF, g) then Result := 'WPD_OBJECT_FORMAT_GIF'
  233.     else if IsEqualGUID(WPD_OBJECT_FORMAT_HTML, g) then Result := 'WPD_OBJECT_FORMAT_HTML'
  234.     else if IsEqualGUID(WPD_OBJECT_FORMAT_ICALENDAR, g) then Result := 'WPD_OBJECT_FORMAT_ICALENDAR'
  235.     else if IsEqualGUID(WPD_OBJECT_FORMAT_ICON, g) then Result := 'WPD_OBJECT_FORMAT_ICON'
  236.     else if IsEqualGUID(WPD_OBJECT_FORMAT_JFIF, g) then Result := 'WPD_OBJECT_FORMAT_JFIF'
  237.     else if IsEqualGUID(WPD_OBJECT_FORMAT_JP2, g) then Result := 'WPD_OBJECT_FORMAT_JP2'
  238.     else if IsEqualGUID(WPD_OBJECT_FORMAT_JPX, g) then Result := 'WPD_OBJECT_FORMAT_JPX'
  239.     else if IsEqualGUID(WPD_OBJECT_FORMAT_M3UPLAYLIST, g) then Result := 'WPD_OBJECT_FORMAT_M3UPLAYLIST'
  240.     else if IsEqualGUID(WPD_OBJECT_FORMAT_M4A, g) then Result := 'WPD_OBJECT_FORMAT_M4A'
  241.     else if IsEqualGUID(WPD_OBJECT_FORMAT_MHT_COMPILED_HTML, g) then Result := 'WPD_OBJECT_FORMAT_MHT_COMPILED_HTML'
  242.     else if IsEqualGUID(WPD_OBJECT_FORMAT_MICROSOFT_EXCEL, g) then Result := 'WPD_OBJECT_FORMAT_MICROSOFT_EXCEL'
  243.     else if IsEqualGUID(WPD_OBJECT_FORMAT_MICROSOFT_POWERPOINT, g) then Result := 'WPD_OBJECT_FORMAT_MICROSOFT_POWERPOINT'
  244.     else if IsEqualGUID(WPD_OBJECT_FORMAT_MICROSOFT_WFC, g) then Result := 'WPD_OBJECT_FORMAT_MICROSOFT_WFC'
  245.     else if IsEqualGUID(WPD_OBJECT_FORMAT_MICROSOFT_WORD, g) then Result := 'WPD_OBJECT_FORMAT_MICROSOFT_WORD'
  246.     else if IsEqualGUID(WPD_OBJECT_FORMAT_MP2, g) then Result := 'WPD_OBJECT_FORMAT_MP2'
  247.     else if IsEqualGUID(WPD_OBJECT_FORMAT_MP3, g) then Result := 'WPD_OBJECT_FORMAT_MP3'
  248.     else if IsEqualGUID(WPD_OBJECT_FORMAT_MP4, g) then Result := 'WPD_OBJECT_FORMAT_MP4'
  249.     else if IsEqualGUID(WPD_OBJECT_FORMAT_MPEG, g) then Result := 'WPD_OBJECT_FORMAT_MPEG'
  250.     else if IsEqualGUID(WPD_OBJECT_FORMAT_MPLPLAYLIST, g) then Result := 'WPD_OBJECT_FORMAT_MPLPLAYLIST'
  251.     else if IsEqualGUID(WPD_OBJECT_FORMAT_NETWORK_ASSOCIATION, g) then Result := 'WPD_OBJECT_FORMAT_NETWORK_ASSOCIATION'
  252.     else if IsEqualGUID(WPD_OBJECT_FORMAT_OGG, g) then Result := 'WPD_OBJECT_FORMAT_OGG'
  253.     else if IsEqualGUID(WPD_OBJECT_FORMAT_PCD, g) then Result := 'WPD_OBJECT_FORMAT_PCD'
  254.     else if IsEqualGUID(WPD_OBJECT_FORMAT_PICT, g) then Result := 'WPD_OBJECT_FORMAT_PICT'
  255.     else if IsEqualGUID(WPD_OBJECT_FORMAT_PLSPLAYLIST, g) then Result := 'WPD_OBJECT_FORMAT_PLSPLAYLIST'
  256.     else if IsEqualGUID(WPD_OBJECT_FORMAT_PNG, g) then Result := 'WPD_OBJECT_FORMAT_PNG'
  257.     else if IsEqualGUID(WPD_OBJECT_FORMAT_PROPERTIES_ONLY, g) then Result := 'WPD_OBJECT_FORMAT_PROPERTIES_ONLY'
  258.     else if IsEqualGUID(WPD_OBJECT_FORMAT_SCRIPT, g) then Result := 'WPD_OBJECT_FORMAT_SCRIPT'
  259.     else if IsEqualGUID(WPD_OBJECT_FORMAT_TEXT, g) then Result := 'WPD_OBJECT_FORMAT_TEXT'
  260.     else if IsEqualGUID(WPD_OBJECT_FORMAT_TIFF, g) then Result := 'WPD_OBJECT_FORMAT_TIFF'
  261.     else if IsEqualGUID(WPD_OBJECT_FORMAT_TIFFEP, g) then Result := 'WPD_OBJECT_FORMAT_TIFFEP'
  262.     else if IsEqualGUID(WPD_OBJECT_FORMAT_TIFFIT, g) then Result := 'WPD_OBJECT_FORMAT_TIFFIT'
  263.     else if IsEqualGUID(WPD_OBJECT_FORMAT_UNSPECIFIED, g) then Result := 'WPD_OBJECT_FORMAT_UNSPECIFIED'
  264.     else if IsEqualGUID(WPD_OBJECT_FORMAT_VCALENDAR1, g) then Result := 'WPD_OBJECT_FORMAT_VCALENDAR1'
  265.     else if IsEqualGUID(WPD_OBJECT_FORMAT_VCARD2, g) then Result := 'WPD_OBJECT_FORMAT_VCARD2'
  266.     else if IsEqualGUID(WPD_OBJECT_FORMAT_VCARD3, g) then Result := 'WPD_OBJECT_FORMAT_VCARD3'
  267.     else if IsEqualGUID(WPD_OBJECT_FORMAT_WAVE, g) then Result := 'WPD_OBJECT_FORMAT_WAVE'
  268.     else if IsEqualGUID(WPD_OBJECT_FORMAT_WINDOWSIMAGEFORMAT, g) then Result := 'WPD_OBJECT_FORMAT_WINDOWSIMAGEFORMAT'
  269.     else if IsEqualGUID(WPD_OBJECT_FORMAT_WMA, g) then Result := 'WPD_OBJECT_FORMAT_WMA'
  270.     else if IsEqualGUID(WPD_OBJECT_FORMAT_WMV, g) then Result := 'WPD_OBJECT_FORMAT_WMV'
  271.     else if IsEqualGUID(WPD_OBJECT_FORMAT_WPLPLAYLIST, g) then Result := 'WPD_OBJECT_FORMAT_WPLPLAYLIST'
  272.     else if IsEqualGUID(WPD_OBJECT_FORMAT_X509V3CERTIFICATE, g) then Result := 'WPD_OBJECT_FORMAT_X509V3CERTIFICATE'
  273.     else if IsEqualGUID(WPD_OBJECT_FORMAT_XML, g) then Result := 'WPD_OBJECT_FORMAT_XML'
  274.     else if IsEqualGUID(WPD_OBJECT_FORMAT_WMV, g) then Result := 'WPD_OBJECT_FORMAT_WMV';
  275.   except
  276.   end;
  277. end;
  278.  
  279. function DisplayFunctionalCategory(cat_id: WideString): String;
  280. var
  281.   g: TGuid;
  282. begin
  283.   Result := cat_id;
  284.   if cat_id='' then Exit;
  285.  
  286.   try
  287.     g := StringToGUID(cat_id);
  288.  
  289.     if IsEqualGUID(WPD_FUNCTIONAL_CATEGORY_ALL, g) then Result := 'WPD_FUNCTIONAL_CATEGORY_ALL'
  290.     else if IsEqualGUID(WPD_FUNCTIONAL_CATEGORY_AUDIO_CAPTURE, g) then Result := 'WPD_FUNCTIONAL_CATEGORY_AUDIO_CAPTURE'
  291.     else if IsEqualGUID(WPD_FUNCTIONAL_CATEGORY_DEVICE, g) then Result := 'WPD_FUNCTIONAL_CATEGORY_DEVICE'
  292.     else if IsEqualGUID(WPD_FUNCTIONAL_CATEGORY_NETWORK_CONFIGURATION, g) then Result := 'WPD_FUNCTIONAL_CATEGORY_NETWORK_CONFIGURATION'
  293.     else if IsEqualGUID(WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION, g) then Result := 'WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION'
  294.     else if IsEqualGUID(WPD_FUNCTIONAL_CATEGORY_SMS, g) then Result := 'WPD_FUNCTIONAL_CATEGORY_SMS'
  295.     else if IsEqualGUID(WPD_FUNCTIONAL_CATEGORY_STILL_IMAGE_CAPTURE, g) then Result := 'WPD_FUNCTIONAL_CATEGORY_STILL_IMAGE_CAPTURE'
  296.     else if IsEqualGUID(WPD_FUNCTIONAL_CATEGORY_STORAGE, g) then Result := 'WPD_FUNCTIONAL_CATEGORY_STORAGE'
  297.     else if IsEqualGUID(WPD_FUNCTIONAL_CATEGORY_VIDEO_CAPTURE, g) then Result := 'WPD_FUNCTIONAL_CATEGORY_VIDEO_CAPTURE';
  298.   except
  299.   end;
  300. end;
  301.  
  302. function DisplayContentType(content_id: WideString): String;
  303. var
  304.   g: TGuid;
  305. begin
  306.   Result := content_id;
  307.   if content_id='' then Exit;
  308.  
  309.   try
  310.     g := StringToGUID(content_id);
  311.  
  312.     if IsEqualGUID(WPD_CONTENT_TYPE_ALL, g) then Result := 'WPD_CONTENT_TYPE_ALL'
  313.     else if IsEqualGUID(WPD_CONTENT_TYPE_APPOINTMENT, g) then Result := 'WPD_CONTENT_TYPE_APPOINTMENT'
  314.     else if IsEqualGUID(WPD_CONTENT_TYPE_AUDIO, g) then Result := 'WPD_CONTENT_TYPE_AUDIO'
  315.     else if IsEqualGUID(WPD_CONTENT_TYPE_AUDIO_ALBUM, g) then Result := 'WPD_CONTENT_TYPE_AUDIO_ALBUM'
  316.     else if IsEqualGUID(WPD_CONTENT_TYPE_CALENDAR, g) then Result := 'WPD_CONTENT_TYPE_CALENDAR'
  317.     else if IsEqualGUID(WPD_CONTENT_TYPE_CERTIFICATE, g) then Result := 'WPD_CONTENT_TYPE_CERTIFICATE'
  318.     else if IsEqualGUID(WPD_CONTENT_TYPE_CONTACT, g) then Result := 'WPD_CONTENT_TYPE_CONTACT'
  319.     else if IsEqualGUID(WPD_CONTENT_TYPE_CONTACT_GROUP, g) then Result := 'WPD_CONTENT_TYPE_CONTACT_GROUP'
  320.     else if IsEqualGUID(WPD_CONTENT_TYPE_DOCUMENT, g) then Result := 'WPD_CONTENT_TYPE_DOCUMENT'
  321.     else if IsEqualGUID(WPD_CONTENT_TYPE_EMAIL, g) then Result := 'WPD_CONTENT_TYPE_EMAIL'
  322.     else if IsEqualGUID(WPD_CONTENT_TYPE_FUNCTIONAL_OBJECT, g) then Result := 'WPD_CONTENT_TYPE_FUNCTIONAL_OBJECT'
  323.     else if IsEqualGUID(WPD_CONTENT_TYPE_GENERIC_FILE, g) then Result := 'WPD_CONTENT_TYPE_GENERIC_FILE'
  324.     else if IsEqualGUID(WPD_CONTENT_TYPE_GENERIC_MESSAGE, g) then Result := 'WPD_CONTENT_TYPE_GENERIC_MESSAGE'
  325.     else if IsEqualGUID(WPD_CONTENT_TYPE_IMAGE, g) then Result := 'WPD_CONTENT_TYPE_IMAGE'
  326.     else if IsEqualGUID(WPD_CONTENT_TYPE_IMAGE_ALBUM, g) then Result := 'WPD_CONTENT_TYPE_IMAGE_ALBUM'
  327.     else if IsEqualGUID(WPD_CONTENT_TYPE_MEDIA_CAST, g) then Result := 'WPD_CONTENT_TYPE_MEDIA_CAST'
  328.     else if IsEqualGUID(WPD_CONTENT_TYPE_MEMO, g) then Result := 'WPD_CONTENT_TYPE_MEMO'
  329.     else if IsEqualGUID(WPD_CONTENT_TYPE_MIXED_CONTENT_ALBUM, g) then Result := 'WPD_CONTENT_TYPE_MIXED_CONTENT_ALBUM'
  330.     else if IsEqualGUID(WPD_CONTENT_TYPE_NETWORK_ASSOCIATION, g) then Result := 'WPD_CONTENT_TYPE_NETWORK_ASSOCIATION'
  331.     else if IsEqualGUID(WPD_CONTENT_TYPE_PLAYLIST, g) then Result := 'WPD_CONTENT_TYPE_PLAYLIST'
  332.     else if IsEqualGUID(WPD_CONTENT_TYPE_PROGRAM, g) then Result := 'WPD_CONTENT_TYPE_PROGRAM'
  333.     else if IsEqualGUID(WPD_CONTENT_TYPE_SECTION, g) then Result := 'WPD_CONTENT_TYPE_SECTION'
  334.     else if IsEqualGUID(WPD_CONTENT_TYPE_TASK, g) then Result := 'WPD_CONTENT_TYPE_TASK'
  335.     else if IsEqualGUID(WPD_CONTENT_TYPE_TELEVISION, g) then Result := 'WPD_CONTENT_TYPE_TELEVISION'
  336.     else if IsEqualGUID(WPD_CONTENT_TYPE_UNSPECIFIED, g) then Result := 'WPD_CONTENT_TYPE_UNSPECIFIED'
  337.     else if IsEqualGUID(WPD_CONTENT_TYPE_VIDEO, g) then Result := 'WPD_CONTENT_TYPE_VIDEO'
  338.     else if IsEqualGUID(WPD_CONTENT_TYPE_VIDEO_ALBUM, g) then Result := 'WPD_CONTENT_TYPE_VIDEO_ALBUM'
  339.     else if IsEqualGUID(WPD_CONTENT_TYPE_WIRELESS_PROFILE, g) then Result := 'WPD_CONTENT_TYPE_WIRELESS_PROFILE'
  340.     else if IsEqualGUID(WPD_CONTENT_TYPE_FOLDER, g) then Result := 'WPD_CONTENT_TYPE_FOLDER'
  341.     ;
  342.   except
  343.   end;
  344. end;
  345.  
  346. function DisplaySupportedCommand(g: TGuid): String;
  347. begin
  348.   Result := GUIDToString(g);
  349.  
  350.   try
  351.     if IsEqualGUID(WPD_CATEGORY_COMMON, g) then Result := 'WPD_CATEGORY_COMMON'
  352.     else if IsEqualGUID(WPD_CATEGORY_CAPABILITIES, g) then Result := 'WPD_CATEGORY_CAPABILITIES'
  353.     else if IsEqualGUID(WPD_CATEGORY_DEVICE_HINTS, g) then Result := 'WPD_CATEGORY_DEVICE_HINTS'
  354.     else if IsEqualGUID(WPD_CATEGORY_MEDIA_CAPTURE, g) then Result := 'WPD_CATEGORY_MEDIA_CAPTURE'
  355.     else if IsEqualGUID(WPD_CATEGORY_NETWORK_CONFIGURATION, g) then Result := 'WPD_CATEGORY_NETWORK_CONFIGURATION'
  356.     else if IsEqualGUID(WPD_CATEGORY_NULL, g) then Result := 'WPD_CATEGORY_NULL'
  357.     else if IsEqualGUID(WPD_CATEGORY_OBJECT_ENUMERATION, g) then Result := 'WPD_CATEGORY_OBJECT_ENUMERATION'
  358.     else if IsEqualGUID(WPD_CATEGORY_OBJECT_MANAGEMENT, g) then Result := 'WPD_CATEGORY_OBJECT_MANAGEMENT'
  359.     else if IsEqualGUID(WPD_CATEGORY_OBJECT_PROPERTIES, g) then Result := 'WPD_CATEGORY_OBJECT_PROPERTIES'
  360.     else if IsEqualGUID(WPD_CATEGORY_OBJECT_PROPERTIES_BULK, g) then Result := 'WPD_CATEGORY_OBJECT_PROPERTIES_BULK'
  361.     else if IsEqualGUID(WPD_CATEGORY_OBJECT_RESOURCES, g) then Result := 'WPD_CATEGORY_OBJECT_RESOURCES'
  362.     else if IsEqualGUID(WPD_CATEGORY_SERVICE_CAPABILITIES, g) then Result := 'WPD_CATEGORY_SERVICE_CAPABILITIES'
  363.     else if IsEqualGUID(WPD_CATEGORY_SERVICE_COMMON, g) then Result := 'WPD_CATEGORY_SERVICE_COMMON'
  364.     else if IsEqualGUID(WPD_CATEGORY_SERVICE_METHODS, g) then Result := 'WPD_CATEGORY_SERVICE_METHODS'
  365.     else if IsEqualGUID(WPD_CATEGORY_SMS, g) then Result := 'WPD_CATEGORY_SMS'
  366.     else if IsEqualGUID(WPD_CATEGORY_STILL_IMAGE_CAPTURE, g) then Result := 'WPD_CATEGORY_STILL_IMAGE_CAPTURE'
  367.     else if IsEqualGUID(WPD_CATEGORY_STORAGE, g) then Result := 'WPD_CATEGORY_STORAGE'
  368.     ;
  369.   except
  370.   end;
  371. end;
  372.  
  373. procedure EnumContentsProperties(parentID: WideString; prop: IPortableDeviceProperties);
  374. var
  375.   ObjVal: PWideChar;
  376.   propKeys: IPortableDeviceKeyCollection;
  377.   prop_val: IPortableDeviceValues;
  378.   propKeys_val: PortableDeviceApiLib_TLB._tagpropertykey;
  379. begin
  380.   if not VarIsClear(prop) then
  381.   begin
  382.     propKeys := CreateComObject(CLSID_PortableDeviceKeyCollection) as IPortableDeviceKeyCollection;
  383.     if VarIsClear(propKeys) then Exit;
  384.  
  385.     //add props we want
  386.     propKeys_val.fmtid := WPD_OBJECT_PARENT_ID_FMTID;
  387.     propKeys_val.pid := WPD_OBJECT_PARENT_ID_PID;
  388.     propKeys.Add(propKeys_val);
  389.  
  390.     propKeys_val.fmtid := WPD_OBJECT_NAME_FMTID;
  391.     propKeys_val.pid := WPD_OBJECT_NAME_PID;
  392.     propKeys.Add(propKeys_val);
  393.  
  394.     propKeys_val.fmtid := WPD_OBJECT_PERSISTENT_UNIQUE_ID_FMTID;
  395.     propKeys_val.pid := WPD_OBJECT_PERSISTENT_UNIQUE_ID_PID;
  396.     propKeys.Add(propKeys_val);
  397.  
  398.     propKeys_val.fmtid := WPD_OBJECT_FORMAT_FMTID;
  399.     propKeys_val.pid := WPD_OBJECT_FORMAT_PID;
  400.     propKeys.Add(propKeys_val);
  401.  
  402.     propKeys_val.fmtid := WPD_OBJECT_CONTENT_TYPE_FMTID;
  403.     propKeys_val.pid := WPD_OBJECT_CONTENT_TYPE_PID;
  404.     propKeys.Add(propKeys_val);
  405.  
  406.     prop.GetValues(PWideChar(parentID), propKeys, prop_val);
  407.     if not VarIsClear(prop_val) then
  408.     begin
  409.       propKeys_val.fmtid := WPD_OBJECT_PARENT_ID_FMTID;
  410.       propKeys_val.pid := WPD_OBJECT_PARENT_ID_PID;
  411.  
  412.       prop_val.GetStringValue(propKeys_val, ObjVal);
  413.       Form12.AddLog('WPD_OBJECT_PARENT_ID: '+ ObjVal);
  414.  
  415.       propKeys_val.fmtid := WPD_OBJECT_NAME_FMTID;
  416.       propKeys_val.pid := WPD_OBJECT_NAME_PID;
  417.  
  418.       prop_val.GetStringValue(propKeys_val, ObjVal);
  419.       Form12.AddLog('WPD_OBJECT_NAME: '+ ObjVal);
  420.  
  421.       propKeys_val.fmtid := WPD_OBJECT_PERSISTENT_UNIQUE_ID_FMTID;
  422.       propKeys_val.pid := WPD_OBJECT_PERSISTENT_UNIQUE_ID_PID;
  423.  
  424.       prop_val.GetStringValue(propKeys_val, ObjVal);
  425.       Form12.AddLog('WPD_OBJECT_PERSISTENT_UNIQUE_ID: '+ ObjVal);
  426.  
  427.       propKeys_val.fmtid := WPD_OBJECT_FORMAT_FMTID;
  428.       propKeys_val.pid := WPD_OBJECT_FORMAT_PID;
  429.  
  430.       prop_val.GetStringValue(propKeys_val, ObjVal);
  431.       Form12.AddLog('WPD_OBJECT_FORMAT: '+ DisplayObjectFormatDesc(ObjVal));
  432.  
  433.       propKeys_val.fmtid := WPD_OBJECT_CONTENT_TYPE_FMTID;
  434.       propKeys_val.pid := WPD_OBJECT_CONTENT_TYPE_PID;
  435.  
  436.       prop_val.GetStringValue(propKeys_val, ObjVal);
  437.       Form12.AddLog('WPD_OBJECT_CONTENT_TYPE: '+ DisplayContentType(ObjVal));
  438.     end;
  439.   end;
  440. end;
  441.  
  442. procedure EnumFunctionalCategoryObjects(capabilities: IPortableDeviceCapabilities; sCat: WideString);
  443. var
  444.   sResultText: WideString;
  445.   pCategoryObjs: IPortableDevicePropVariantCollection;
  446.   iCount, i: Cardinal;
  447.   prop_var: tag_inner_PROPVARIANT;
  448.   gCat: TGuid;
  449. begin
  450.   if sCat='' then Exit;
  451.  
  452.   if not VarIsClear(capabilities) then
  453.   begin
  454.     gCat := StringToGUID(sCat);
  455.     try
  456.       pCategoryObjs := CreateComObject(CLASS_PortableDevicePropVariantCollection) as IPortableDevicePropVariantCollection;
  457.       if VarIsClear(pCategoryObjs) then Exit;
  458.  
  459.       capabilities.GetFunctionalObjects(gCat, pCategoryObjs);
  460.  
  461.       pCategoryObjs.GetCount(iCount);
  462.       Form12.AddLog('Functional Category Objects Count: '+IntToStr(iCount));
  463.  
  464.       if iCount>0 then
  465.       begin
  466.         for i := 0 to iCount-1 do
  467.         begin
  468.           PropVariantInit(ActiveX.PROPVARIANT(prop_var));
  469.           pCategoryObjs.GetAt(i, prop_var);
  470.           PropVariantToString(prop_var, sResultText);
  471.           Form12.AddLog('Functional Category Object: '+sResultText);
  472.         end;
  473.       end;
  474.     except
  475.     end;
  476.   end;
  477. end;
  478.  
  479. procedure EnumContentTypes(capabilities: IPortableDeviceCapabilities; sCat: WideString);
  480. var
  481.   sResultText: WideString;
  482.   contentTypes: IPortableDevicePropVariantCollection;
  483.   iCount, i: Cardinal;
  484.   prop_var: tag_inner_PROPVARIANT;
  485.   gCat: TGuid;
  486. begin
  487.   if sCat='' then Exit;
  488.  
  489.   if not VarIsClear(capabilities) then
  490.   begin
  491.     gCat := StringToGUID(sCat);
  492.     try
  493.       contentTypes := CreateComObject(CLASS_PortableDevicePropVariantCollection) as IPortableDevicePropVariantCollection;
  494.       if VarIsClear(contentTypes) then Exit;
  495.  
  496.       capabilities.GetSupportedContentTypes(gCat, contentTypes);
  497.  
  498.       contentTypes.GetCount(iCount);
  499.       Form12.AddLog('Content Types Count: '+IntToStr(iCount));
  500.  
  501.       if iCount>0 then
  502.       begin
  503.         for i := 0 to iCount-1 do
  504.         begin
  505.           PropVariantInit(ActiveX.PROPVARIANT(prop_var));
  506.           contentTypes.GetAt(i, prop_var);
  507.           PropVariantToString(prop_var, sResultText);
  508.           Form12.AddLog('Content Type: '+DisplayContentType(sResultText));
  509.         end;
  510.       end;
  511.     except
  512.     end;
  513.   end;
  514. end;
  515.  
  516. procedure EnumSupportedCommands(capabilities: IPortableDeviceCapabilities);
  517. var
  518.   CmdKeys: IPortableDeviceKeyCollection;
  519.   iCount, i: Cardinal;
  520.   cmd_key: PortableDeviceApiLib_TLB._tagpropertykey;
  521. begin
  522.   if not VarIsClear(capabilities) then
  523.   begin
  524.     try
  525.       CmdKeys := CreateComObject(CLSID_PortableDeviceKeyCollection) as IPortableDeviceKeyCollection;
  526.       if VarIsClear(CmdKeys) then Exit;
  527.  
  528.       capabilities.GetSupportedCommands(CmdKeys);
  529.  
  530.       CmdKeys.GetCount(iCount);
  531.       Form12.AddLog('Supported Commands Count: '+IntToStr(iCount));
  532.  
  533.       if iCount>0 then
  534.       begin
  535.         for i := 0 to iCount-1 do
  536.         begin
  537.           CmdKeys.GetAt(i, cmd_key);
  538.           Form12.AddLog('Supported Command: '+DisplaySupportedCommand(cmd_key.fmtid)+' ('+IntToStr(cmd_key.pid)+')');
  539.         end;
  540.       end;
  541.     except
  542.     end;
  543.   end;
  544. end;
  545.  
  546. procedure EnumDevCapabilities(PortableDev: IPortableDevice);
  547. var
  548.   sResultText: WideString;
  549.   capabilities: IPortableDeviceCapabilities;
  550.   pCategories: IPortableDevicePropVariantCollection;
  551.   iCount, i: Cardinal;
  552.   prop_var: tag_inner_PROPVARIANT;
  553. begin
  554.   if not VarIsClear(PortableDev) then
  555.   begin
  556.     try
  557.       PortableDev.Capabilities(capabilities);
  558.       if not VarIsClear(capabilities) then
  559.       begin
  560.         pCategories := CreateComObject(CLASS_PortableDevicePropVariantCollection) as IPortableDevicePropVariantCollection;
  561.         if VarIsClear(pCategories) then Exit;
  562.  
  563.         capabilities.GetFunctionalCategories(pCategories);
  564.  
  565.         pCategories.GetCount(iCount);
  566.         Form12.AddLog('Dev. Functional Categories Count: '+IntToStr(iCount));
  567.  
  568.         if iCount>0 then
  569.         begin
  570.           for i := 0 to iCount-1 do
  571.           begin
  572.             //list categories
  573.             PropVariantInit(ActiveX.PROPVARIANT(prop_var));
  574.             pCategories.GetAt(i, prop_var);
  575.             PropVariantToString(prop_var, sResultText);
  576.             Form12.AddLog('Dev. Functional Category: '+DisplayFunctionalCategory(sResultText));
  577.             //category objects....
  578.             EnumFunctionalCategoryObjects(capabilities, sResultText);
  579.             //types...
  580.             EnumContentTypes(capabilities, sResultText);
  581.           end;
  582.         end;
  583.         //comands....
  584.         EnumSupportedCommands(capabilities);
  585.       end;
  586.     finally
  587.       capabilities := nil;
  588.     end;
  589.   end;
  590. end;
  591.  
  592. const
  593.   CLIENT_NAME : WideString = 'MyClient';
  594.   CLIENT_MAJOR_VER = 1;
  595.   CLIENT_MINOR_VER = 0;
  596.   CLIENT_REVISION  = 0;
  597.  
  598. function ConnectToDevice(sDev: WideString; var PortableDev: IPortableDevice): Boolean;
  599. var
  600.   PortableDeviceValues: IPortableDeviceValues;
  601.   hr: HResult;
  602.   dev_val: PortableDeviceApiLib_TLB._tagpropertykey;
  603.   //bReadonly: Boolean;
  604. begin
  605.   Result := False;
  606.  
  607.   Form12.AddLog('Start Connecting: '+sDev);
  608.  
  609.   PortableDev := CoPortableDevice.Create;
  610.   try
  611.      //create device values:
  612.     PortableDeviceValues := CreateComObject(CLASS_PortableDeviceValues) as IPortableDeviceValues;
  613.     if VarIsClear(PortableDeviceValues) then Exit;
  614.     Form12.AddLog('Dev. val. ok! ');
  615.  
  616.     //bReadonly := False;
  617.     //set some info
  618.     dev_val.fmtid := WPD_CLIENT_NAME_FMTID;
  619.     dev_val.pid := WPD_CLIENT_NAME_PID;
  620.     PortableDeviceValues.SetStringValue(dev_val, PWideChar(CLIENT_NAME));
  621.  
  622.     dev_val.fmtid := WPD_CLIENT_MAJOR_VERSION_FMTID;
  623.     dev_val.pid := WPD_CLIENT_MAJOR_VERSION_PID;
  624.     PortableDeviceValues.SetUnsignedIntegerValue(dev_val, CLIENT_MAJOR_VER);
  625.  
  626.     dev_val.fmtid := WPD_CLIENT_MINOR_VERSION_FMTID;
  627.     dev_val.pid := WPD_CLIENT_MINOR_VERSION_PID;
  628.     PortableDeviceValues.SetUnsignedIntegerValue(dev_val, CLIENT_MINOR_VER);
  629.  
  630.     dev_val.fmtid := WPD_CLIENT_REVISION_FMTID;
  631.     dev_val.pid := WPD_CLIENT_REVISION_PID;
  632.     PortableDeviceValues.SetUnsignedIntegerValue(dev_val, CLIENT_REVISION);
  633.  
  634.     //open device
  635.     hr := PortableDev.Open(PWideChar(sDev), PortableDeviceValues);
  636.     if hr = E_ACCESSDENIED then
  637.     begin
  638.       // Attempt to open for read-only access
  639.       dev_val.fmtid := WPD_CLIENT_DESIRED_ACCESS_FMTID;
  640.       dev_val.pid := WPD_CLIENT_DESIRED_ACCESS_PID;
  641.       PortableDeviceValues.SetUnsignedIntegerValue(dev_val, GENERIC_READ);
  642.       hr := PortableDev.Open(PWideChar(sDev), PortableDeviceValues);
  643.       //bReadonly := (hr = S_OK);
  644.     end;
  645.  
  646.     //opened ok
  647.     if hr = S_OK then
  648.     begin
  649.       Form12.AddLog('Connected: '+sDev);
  650.       Result := True;
  651.     end
  652.     else
  653.     begin
  654.       Form12.AddLog('Not connected: '+IntToStr(hr));
  655.     end;
  656.   finally
  657.     PortableDeviceValues := nil;
  658.   end;
  659. end;
  660.  
  661. procedure TForm12.bListDevClick(Sender: TObject);
  662. var
  663.   PMan: TPortableDeviceManager;
  664.   iDevCount: LongWord;
  665.   pDevs: array of PWideChar;
  666.   i, iRes: Integer;
  667.   DevFriendlyName: WideString;
  668.   PortableDev: IPortableDevice;
  669. begin
  670.   ClearLog;
  671.   ListBox1.Items.Clear;
  672.   ListView1.Items.Clear;
  673.   AddLog('+++++ '+bListDev.Caption+' +++++');
  674.  
  675.   try
  676.     PMan := TPortableDeviceManager.Create(nil);
  677.     try
  678.       if PMan.RefreshDeviceList = S_OK then
  679.       begin
  680.         // Determine how many WPD devices are connected
  681.         iDevCount := 1;
  682.         if PMan.GetDevices(PWideChar(nil^), iDevCount) = S_OK then
  683.         begin
  684.           AddLog('Devices found: '+ IntToStr(iDevCount));
  685.  
  686.           if iDevCount>0 then
  687.           begin
  688.             // Retrieve the device id for each connected device
  689.             AddLog('Prepare dev. list');
  690.             SetLength(pDevs, iDevCount);
  691.             AddLog('Call: GetDevices');
  692.             iRes := PMan.GetDevices(pDevs[0], iDevCount);
  693.             AddLog('Result = '+ IntToStr(iRes));
  694.             if iRes = S_OK then
  695.             begin
  696.               AddLog('Start looping....');
  697.               for i := 0 to iDevCount - 1 do //enumerate the devices:
  698.               begin
  699.                 AddLog('dev id='+Trim(pDevs[i]));
  700.  
  701.                 //get length of friendly name:
  702.                 DevFriendlyName := GetFriendlyName(PMan, pDevs[i]);
  703.  
  704.                 ListBox1.Items.Add(DevFriendlyName + '  ' + Trim(pDevs[i])); //keep dev id 4 later
  705.  
  706.                 //list of cap.
  707.                 try
  708.                   if ConnectToDevice(pDevs[i], PortableDev) then
  709.                   begin
  710.                     EnumDevCapabilities(PortableDev);
  711.                     PortableDev.Close;
  712.                   end;
  713.                 finally
  714.                   PortableDev := nil;
  715.                 end;
  716.               end;
  717.             end
  718.             else
  719.               AddLog('Cannot get device info! ('+IntToStr(iRes)+')');
  720.           end;
  721.         end;
  722.       end;
  723.     finally
  724.       PMan.Free;
  725.     end;
  726.   except
  727.     on E: Exception do
  728.     begin
  729.       AddLog('Exception: ('+E.Message+')');
  730.     end;
  731.   end;
  732.  
  733.   if ListBox1.Items.Count>0 then
  734.     ListBox1.ItemIndex := 0;
  735. end;
  736.  
  737. function IsDirectory(prop_val: IPortableDeviceValues): Boolean;
  738. var
  739.   dev_val: PortableDeviceApiLib_TLB._tagpropertykey;
  740.   prop_guid: TGUID;
  741. begin
  742.   Result := False;
  743.  
  744.   if not VarIsClear(prop_val) then
  745.   begin
  746.     dev_val.fmtid := WPD_OBJECT_CONTENT_TYPE_FMTID;
  747.     dev_val.pid := WPD_OBJECT_CONTENT_TYPE_PID;
  748.     if prop_val.GetGuidValue(dev_val, prop_guid) = S_OK then
  749.     begin
  750.       if IsEqualGUID(prop_guid, WPD_CONTENT_TYPE_FOLDER) or
  751.         IsEqualGUID(prop_guid, WPD_CONTENT_TYPE_FUNCTIONAL_OBJECT)
  752.       then
  753.         Result := True;
  754.     end;
  755.   end;
  756. end;
  757.  
  758. function IsDrive(sObjName: WideString): Boolean;
  759. begin
  760.   Result := (ExtractFilePath(sObjName) = sObjName);
  761. end;
  762.  
  763. function GetFirstStorageID(PortableDev: IPortableDevice): WideString;
  764. var
  765.   content: IPortableDeviceContent;
  766.   objectIds: IEnumPortableDeviceObjectIDs;
  767.   objectId: PWideChar;
  768.   fetched: Cardinal;
  769. begin
  770.   Result := WPD_DEVICE_OBJECT_ID;
  771.   if PortableDev.Content(content) = S_OK then
  772.   begin
  773.     if content.EnumObjects(0, '', nil, objectIds) = S_OK then
  774.     begin
  775.       objectIds.Reset;
  776.       objectIds.Next(1, objectId, fetched);
  777.       if (fetched > 0) then
  778.         Result := objectId;
  779.     end;
  780.   end;
  781.  
  782.   Form12.AddLog('Device root: '+ Result);
  783. end;
  784.  
  785. procedure EnumContentsOfFolder(content: IPortableDeviceContent; parentID: WideString;
  786.   lst: TListItems; bGoDeep: Boolean; ParentPath: WideString);
  787. var
  788.   objectIds: IEnumPortableDeviceObjectIDs;
  789.   objectId, ObjName, ObjOrigName: PWideChar;
  790.   fetched, total: Cardinal;
  791.   keys: IPortableDeviceKeyCollection;
  792.   prop: IPortableDeviceProperties;
  793.   prop_val: IPortableDeviceValues;
  794.   dev_val: PortableDeviceApiLib_TLB._tagpropertykey;
  795.   bFolder: Boolean;
  796.   itm: TListItem;
  797.   //prop_guid: TGUID;
  798.   ObjectPath: WideString;
  799. begin
  800.   if not VarIsClear(content) then
  801.   begin
  802.     //get content properties
  803.     content.Properties(prop);
  804.     EnumContentsProperties(parentID, prop);
  805.  
  806.     if content.EnumObjects(0, PWideChar(parentID), nil, objectIds) = S_OK then
  807.     begin
  808.       total := 0;
  809.       Form12.AddLog('Enumerate: '+parentID);
  810.       repeat
  811.         objectIds.Next(1, objectId, fetched);
  812.         Inc(total, fetched);
  813.       until fetched=0;
  814.       Form12.AddLog('Enum count: '+IntToStr(total));
  815.  
  816.       objectIds.Reset;
  817.       repeat
  818.         objectIds.Next(1, objectId, fetched);
  819.         if (fetched > 0) then
  820.         begin
  821.           //Get object prop.
  822.           prop.GetSupportedProperties(objectId, keys);
  823.           prop.GetValues(objectId, keys, prop_val);
  824.           ObjName := '';
  825.           ObjOrigName := '';
  826.  
  827.           // Get the name of the object
  828.           if not VarIsClear(prop_val) then
  829.           begin
  830.             dev_val.fmtid := WPD_OBJECT_ORIGINAL_FILE_NAME_FMTID;
  831.             dev_val.pid := WPD_OBJECT_ORIGINAL_FILE_NAME_PID;
  832.  
  833.             prop_val.GetStringValue(dev_val, ObjOrigName);
  834.             if Length(Trim(ObjOrigName)) = 0 then
  835.               ObjOrigName := objectId;
  836.  
  837.             dev_val.fmtid := WPD_OBJECT_NAME_FMTID;
  838.             dev_val.pid := WPD_OBJECT_NAME_PID;
  839.  
  840.             prop_val.GetStringValue(dev_val, ObjName);
  841.           end;
  842.  
  843.           bFolder := IsDirectory(prop_val); //include zip folders
  844.           if Length(ParentPath) > 0 then
  845.             ObjectPath := IncludeTrailingPathDelimiter(ParentPath) + ObjName
  846.           else
  847.             ObjectPath := ObjName;
  848.  
  849.           //keep name
  850.           itm := lst.Add;
  851.           itm.Caption := ObjOrigName; //keep folder/file name
  852.           itm.SubItems.Add(objectId);  //obj id - full path to object
  853.           itm.SubItems.Add(ObjName); //obj name
  854.           itm.SubItems.Add(ObjectPath); //full path to object
  855.           itm.Data := Pointer(ifthen(bFolder, 1, 0));
  856.  
  857.           //go into subfolder
  858.           if bFolder and bGoDeep then
  859.           begin
  860.             Form12.AddLog('Go deep...');
  861.             EnumContentsOfFolder(content, objectId, lst, bGoDeep, ObjectPath);
  862.           end;
  863.         end;
  864.       until fetched=0;
  865.     end;
  866.   end;
  867. end;
  868.  
  869. function LocateSpecifiedFolder(content: IPortableDeviceContent; parentID: WideString;
  870.   sFindFolder, sParent: WideString; var sDestFolder: WideString): Boolean;
  871. var
  872.   objectIds: IEnumPortableDeviceObjectIDs;
  873.   objectId, ObjName, ObjOrigName: PWideChar;
  874.   fetched, total: Cardinal;
  875.   keys: IPortableDeviceKeyCollection;
  876.   prop: IPortableDeviceProperties;
  877.   prop_val: IPortableDeviceValues;
  878.   dev_val: PortableDeviceApiLib_TLB._tagpropertykey;
  879.   bFolder: Boolean;
  880.   sCurrent: WideString;
  881. begin
  882.   Result := False;
  883.  
  884.   if (not VarIsClear(content)) and (Length(sFindFolder) > 0) then
  885.   begin
  886.     //get content properties
  887.     content.Properties(prop);
  888.     EnumContentsProperties(parentID, prop);
  889.  
  890.     if content.EnumObjects(0, PWideChar(parentID), nil, objectIds) = S_OK then
  891.     begin
  892.       total := 0;
  893.       Form12.AddLog('Enumerate: '+parentID);
  894.       repeat
  895.         objectIds.Next(1, objectId, fetched);
  896.         Inc(total, fetched);
  897.       until fetched=0;
  898.       Form12.AddLog('Enum count: '+IntToStr(total));
  899.  
  900.       objectIds.Reset;
  901.       repeat
  902.         objectIds.Next(1, objectId, fetched);
  903.         if (fetched > 0) then
  904.         begin
  905.           //Get object prop.
  906.           prop.GetSupportedProperties(objectId, keys);
  907.           prop.GetValues(objectId, keys, prop_val);
  908.           ObjName := '';
  909.           ObjOrigName := '';
  910.  
  911.           // Get the name of the object
  912.           if not VarIsClear(prop_val) then
  913.           begin
  914.             dev_val.fmtid := WPD_OBJECT_ORIGINAL_FILE_NAME_FMTID;
  915.             dev_val.pid := WPD_OBJECT_ORIGINAL_FILE_NAME_PID;
  916.  
  917.             prop_val.GetStringValue(dev_val, ObjOrigName);
  918.             if Length(Trim(ObjOrigName)) = 0 then
  919.               ObjOrigName := objectId;
  920.  
  921.             dev_val.fmtid := WPD_OBJECT_NAME_FMTID;
  922.             dev_val.pid := WPD_OBJECT_NAME_PID;
  923.  
  924.             prop_val.GetStringValue(dev_val, ObjName);
  925.           end;
  926.  
  927.           bFolder := IsDirectory(prop_val); //include zip folders
  928.           if sParent<>'' then        
  929.             sCurrent := IncludeTrailingPathDelimiter(sParent)+ObjOrigName
  930.           else
  931.             sCurrent := ObjOrigName;
  932.  
  933.           if Pos(UpperCase(sCurrent), UpperCase(sFindFolder)) > 0 then
  934.           begin
  935.             if Length(sCurrent) >= Length(sFindFolder) then
  936.             begin
  937.               sDestFolder := objectId;
  938.               Result := True;
  939.             end
  940.             else
  941.             begin
  942.               //go into subfolder
  943.               if bFolder then
  944.               begin
  945.                 Form12.AddLog('Go deep...');
  946.                 Result := LocateSpecifiedFolder(content, objectId, sFindFolder,
  947.                   sCurrent, sDestFolder);
  948.               end;
  949.             end;
  950.           end;
  951.         end;
  952.       until fetched=0;
  953.     end;
  954.   end;
  955. end;
  956.  
  957. procedure ListFilesOnDevice(sDev: WideString; lst: TListItems; sParent: WideString;
  958.   bGoDeep: Boolean);
  959. var
  960.   PortableDev: IPortableDevice;
  961.   content: IPortableDeviceContent;
  962.   sPath: String;
  963. begin
  964.   try
  965.     if ConnectToDevice(sDev, PortableDev) then
  966.     begin
  967.       //read content of device
  968.       try
  969.         if PortableDev.Content(content) = S_OK then
  970.         begin
  971.           sPath := sParent;
  972.           if sParent='' then
  973.           begin
  974.             sPath := '';
  975.             sParent := GetFirstStorageID(PortableDev);
  976.           end;
  977.  
  978.           EnumContentsOfFolder(content, sParent, lst, bGoDeep, sPath);
  979.         end;
  980.       finally
  981.         PortableDev.Close;
  982.       end;
  983.     end;
  984.   finally
  985.     PortableDev := nil;
  986.   end;
  987. end;
  988.  
  989. function FindFolderOnDevice(sDev: WideString; sParent, sFindFolder: WideString;
  990.   var sDestFolder: WideString): Boolean;
  991. var
  992.   PortableDev: IPortableDevice;
  993.   content: IPortableDeviceContent;
  994. begin
  995.   Result := False;
  996.   sDestFolder := '';
  997.   try
  998.     if ConnectToDevice(sDev, PortableDev) then
  999.     begin
  1000.       //read content of device
  1001.       try
  1002.         if PortableDev.Content(content) = S_OK then
  1003.         begin
  1004.           if sParent='' then
  1005.             sParent := GetFirstStorageID(PortableDev);
  1006.  
  1007.           Result := LocateSpecifiedFolder(content, sParent, sFindFolder, '', sDestFolder);
  1008.         end;
  1009.       finally
  1010.         PortableDev.Close;
  1011.       end;
  1012.     end;
  1013.   finally
  1014.     PortableDev := nil;
  1015.   end;
  1016. end;
  1017.  
  1018. procedure TForm12.bListAllClick(Sender: TObject);
  1019. var
  1020.   sDevId: WideString;
  1021. begin
  1022.   AddLog('+++++ '+bListTop.Caption+' +++++');
  1023.  
  1024.   if ListBox1.ItemIndex >= 0 then
  1025.   begin
  1026.     //extract dev id
  1027.     sDevId := ListBox1.Items[ListBox1.ItemIndex];
  1028.     sDevId := Trim(Copy(sDevId, Pos(DEV_START_PATH, sDevId), Length(sDevId)));
  1029.  
  1030.     ListView1.Items.Clear;
  1031.     ListView1.Items.BeginUpdate;
  1032.     try
  1033.       ListFilesOnDevice(sDevId, ListView1.Items, '', True);
  1034.     finally
  1035.       ListView1.Items.EndUpdate;
  1036.     end;
  1037.   end;
  1038. end;
  1039.  
  1040. function GetFileFromDevice(sDeviceId, sFile, sSaveAs: WideString): Boolean;
  1041. var
  1042.   PortableDev: IPortableDevice;
  1043.   content: IPortableDeviceContent;
  1044.   resources: IPortableDeviceResources;
  1045.   iTransferSize, iReadBytes: Cardinal;
  1046.   res_prop: PortableDeviceApiLib_TLB._tagpropertykey;
  1047.   fDevStream: PortableDeviceApiLib_TLB.IStream;
  1048.   fFileStream: TFileStream;
  1049.   buf: array[0..(1024-1)] of Byte;
  1050. begin
  1051.   Result := False;
  1052.   try
  1053.     if ConnectToDevice(sDeviceId, PortableDev) then
  1054.     begin
  1055.       //read content of device
  1056.       try
  1057.         if PortableDev.Content(content) = S_OK then
  1058.         begin
  1059.           Form12.AddLog('Content: OK');
  1060.  
  1061.           if content.Transfer(resources) = S_OK then
  1062.           begin
  1063.             iTransferSize := 0;
  1064.             res_prop.fmtid := WPD_RESOURCE_DEFAULT_FMTID;
  1065.             res_prop.pid := WPD_RESOURCE_DEFAULT_PID;
  1066.             //request stream
  1067.             if resources.GetStream(PWideChar(sFile), res_prop, 0, iTransferSize, fDevStream) = S_OK then
  1068.             begin
  1069.               Form12.AddLog('Stream: OK');
  1070.  
  1071.               fFileStream := TFileStream.Create(sSaveAs, fmCreate);
  1072.               try
  1073.                 //read source stream using buffer
  1074.                 repeat
  1075.                   fDevStream.RemoteRead(buf[0], 1024, iReadBytes);
  1076.                   if iReadBytes>0 then
  1077.                     fFileStream.Write(buf[0], iReadBytes);
  1078.                 until (iReadBytes = 0);
  1079.  
  1080.                 Result := True;
  1081.               finally
  1082.                 fFileStream.Free;
  1083.               end;
  1084.             end;
  1085.           end;
  1086.         end;
  1087.       finally
  1088.         fDevStream := nil;
  1089.         PortableDev.Close;
  1090.       end;
  1091.     end;
  1092.   finally
  1093.     PortableDev := nil;
  1094.   end;
  1095. end;
  1096.  
  1097. procedure TForm12.bCopyFromClick(Sender: TObject);
  1098. var
  1099.   sDevId, sFile: WideString;
  1100. begin
  1101.   AddLog('+++++ '+bCopyFrom.Caption+' +++++');
  1102.  
  1103.   if (ListBox1.ItemIndex >= 0) and (ListView1.ItemIndex >= 0) and
  1104.     (Cardinal(ListView1.Items.Item[ListView1.ItemIndex].Data) = 0) then //if is file
  1105.   begin
  1106.     //extract dev id
  1107.     sDevId := ListBox1.Items[ListBox1.ItemIndex];
  1108.     sDevId := Trim(Copy(sDevId, Pos(DEV_START_PATH, sDevId), Length(sDevId)));
  1109.     //file id
  1110.     sFile := ListView1.Items.Item[ListView1.ItemIndex].SubItems[0];
  1111.  
  1112.     //get destination directory
  1113.     SaveDialog1.FileName := ExtractFileName(ListView1.Items.Item[ListView1.ItemIndex].Caption);
  1114.     if SaveDialog1.Execute then
  1115.     begin
  1116.       GetFileFromDevice(sDevId, sFile, SaveDialog1.FileName);
  1117.     end;
  1118.   end;
  1119. end;
  1120.  
  1121. function DelFileFromDevice(sDeviceId, sFile: WideString; bWithRecursion: Boolean;
  1122.   var sResultText: WideString): Boolean;
  1123. var
  1124.   PortableDev: IPortableDevice;
  1125.   content: IPortableDeviceContent;
  1126.   prop_var: tag_inner_PROPVARIANT;
  1127.   pFiles, pRes: IPortableDevicePropVariantCollection;
  1128.   iCount: Cardinal;
  1129. begin
  1130.   Result := False;
  1131.   sResultText := '';
  1132.   try
  1133.     if ConnectToDevice(sDeviceId, PortableDev) then
  1134.     begin
  1135.       //read content of device
  1136.       try
  1137.         if PortableDev.Content(content) = S_OK then
  1138.         begin
  1139.           pFiles := CreateComObject(CLASS_PortableDevicePropVariantCollection) as IPortableDevicePropVariantCollection;
  1140.           if VarIsClear(pFiles) then Exit;
  1141.  
  1142.           pRes := CreateComObject(CLASS_PortableDevicePropVariantCollection) as IPortableDevicePropVariantCollection;
  1143.           if VarIsClear(pRes) then Exit;
  1144.  
  1145.           //add  file name to list for deleting
  1146.           PropVariantInit(ActiveX.PROPVARIANT(prop_var));
  1147.           StringToPropVariant(sFile, prop_var);
  1148.           pFiles.Add(prop_var);
  1149.  
  1150.           Form12.AddLog('Try to delete: '+sFile);
  1151.           //delete
  1152.           Result := (content.Delete(Math.IfThen(bWithRecursion, 1, 0), pFiles, pRes) = S_OK); //recursion ??
  1153.  
  1154.           pRes.GetCount(iCount);
  1155.           if iCount>0 then
  1156.           begin
  1157.             PropVariantInit(ActiveX.PROPVARIANT(prop_var));
  1158.             pRes.GetAt(0, prop_var);
  1159.             PropVariantToString(prop_var, sResultText);
  1160.  
  1161.             Form12.AddLog('Delete: '+sResultText);
  1162.           end;
  1163.         end;
  1164.       finally
  1165.         PortableDev.Close;
  1166.       end;
  1167.     end;
  1168.   finally
  1169.     pFiles := nil;
  1170.     pRes := nil;
  1171.     PortableDev := nil;
  1172.   end;
  1173. end;
  1174.  
  1175. procedure TForm12.bDeleteClick(Sender: TObject);
  1176. var
  1177.   sDevId, sFile, sResultText: WideString;
  1178. begin
  1179.   AddLog('+++++ '+bDelete.Caption+' +++++');
  1180.  
  1181.   if (ListBox1.ItemIndex >= 0) and (ListView1.ItemIndex >= 0) and
  1182.     (Cardinal(ListView1.Items.Item[ListView1.ItemIndex].Data) = 0) then  //if is file
  1183.   begin
  1184.     //extract dev id
  1185.     sDevId := ListBox1.Items[ListBox1.ItemIndex];
  1186.     sDevId := Trim(Copy(sDevId, Pos(DEV_START_PATH, sDevId), Length(sDevId)));
  1187.     //file
  1188.     sFile := ListView1.Items.Item[ListView1.ItemIndex].SubItems[0];
  1189.  
  1190.     //delete
  1191.     if MessageDlg('Want to delete?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  1192.     begin
  1193.       DelFileFromDevice(sDevId, sFile, True, sResultText);
  1194.       ShowMessage(sResultText);
  1195.     end;
  1196.   end;
  1197. end;
  1198.  
  1199. procedure GetRequiredPropertiesForContent(parent: WideString; FileName: WideString;
  1200.   iSize: Cardinal; var ppObjectProperties: IPortableDeviceValues);
  1201. var
  1202.   dev_val: PortableDeviceApiLib_TLB._tagpropertykey;
  1203.   //prop_guid: TGUID;
  1204. begin
  1205.   //parent id
  1206.   dev_val.fmtid := WPD_OBJECT_PARENT_ID_FMTID;
  1207.   dev_val.pid := WPD_OBJECT_PARENT_ID_PID;
  1208.   ppObjectProperties.SetStringValue(dev_val, PWideChar(parent));
  1209.  
  1210.   //object name
  1211.   dev_val.fmtid := WPD_OBJECT_NAME_FMTID;
  1212.   dev_val.pid := WPD_OBJECT_NAME_PID;
  1213.   ppObjectProperties.SetStringValue(dev_val, PWideChar(FileName));
  1214.  
  1215.   //file name
  1216.   dev_val.fmtid := WPD_OBJECT_ORIGINAL_FILE_NAME_FMTID;
  1217.   dev_val.pid := WPD_OBJECT_ORIGINAL_FILE_NAME_PID;
  1218.   ppObjectProperties.SetStringValue(dev_val, PWideChar(FileName));
  1219.  
  1220.   //size
  1221.   dev_val.fmtid := WPD_OBJECT_SIZE_FMTID;
  1222.   dev_val.pid := WPD_OBJECT_SIZE_PID;
  1223.   ppObjectProperties.SetUnsignedLargeIntegerValue(dev_val, iSize);
  1224.  
  1225.   {dev_val.fmtid := WPD_OBJECT_CONTENT_TYPE_FMTID;
  1226.   dev_val.pid := WPD_OBJECT_CONTENT_TYPE_PID;
  1227.   prop_guid := WPD_CONTENT_TYPE_FOLDER;
  1228.   ppObjectProperties.SetGuidValue(dev_val, prop_guid);}
  1229. end;
  1230.  
  1231. function TransferFileToDevice(sDeviceId, sFile, sSaveTo: WideString): Boolean;
  1232. var
  1233.   PortableDev: IPortableDevice;
  1234.   content: IPortableDeviceContent;
  1235.   iTransferSize, iReadBytes, iWritten: Cardinal;
  1236.   fDevStream: PortableDeviceApiLib_TLB.IStream;
  1237.   pValues: IPortableDeviceValues;
  1238.   fFileStream: TFileStream;
  1239.   buf: array[0..(1024-1)] of Byte;
  1240.   ppszCookie: PWideChar;
  1241.   iRes: Integer;
  1242. begin
  1243.   Result := False;
  1244.   try
  1245.     if ConnectToDevice(sDeviceId, PortableDev) then
  1246.     begin
  1247.       //read content of device
  1248.       try
  1249.         if PortableDev.Content(content) = S_OK then
  1250.         begin
  1251.           //required properties for content
  1252.           pValues :=  CreateComObject(CLASS_PortableDeviceValues) as IPortableDeviceValues;
  1253.           if VarIsClear(pValues) then Exit;
  1254.  
  1255.           Form12.AddLog('Try to copy to dev: '+sFile+ ' - dest: '+sSaveTo);
  1256.  
  1257.           fFileStream := TFileStream.Create(sFile, fmOpenRead);
  1258.           try
  1259.             GetRequiredPropertiesForContent(sSaveTo, ExtractFileName(sFile),
  1260.               fFileStream.Size, pValues);
  1261.  
  1262.             //create dest. stream
  1263.             iTransferSize := 0;
  1264.             content.CreateObjectWithPropertiesAndData(pValues, fDevStream, iTransferSize, ppszCookie);
  1265.             if VarIsClear(fDevStream) then Exit;
  1266.  
  1267.             Form12.AddLog('Stream: OK');
  1268.  
  1269.             //transfer to dev. stream
  1270.             //read source stream using buffer
  1271.             repeat
  1272.               iReadBytes := fFileStream.Read(buf[0], 1024);
  1273.               Form12.AddLog('File - readed bytes: ' + IntToStr(iReadBytes));
  1274.               if iReadBytes>0 then
  1275.               begin
  1276.                iRes := fDevStream.RemoteWrite(buf[0], iReadBytes, iWritten);
  1277.                if iRes <> S_OK then
  1278.                  Form12.AddLog('Error writing: ' + IntToStr(iRes));
  1279.               end;
  1280.             until (iReadBytes = 0);
  1281.  
  1282.             //commit saving to stream
  1283.             Result := (fDevStream.Commit(0) = S_OK);
  1284.             if Result then
  1285.               Form12.AddLog('File Commit ok!')
  1286.             else
  1287.               Form12.AddLog('File Commit nok!');
  1288.           finally
  1289.             fFileStream.Free;
  1290.           end;
  1291.         end;
  1292.       finally
  1293.         fDevStream := nil;
  1294.         PortableDev.Close;
  1295.       end;
  1296.     end;
  1297.   finally
  1298.     PortableDev := nil;
  1299.   end;
  1300. end;
  1301.  
  1302. procedure TForm12.bCopyToClick(Sender: TObject);
  1303. var
  1304.   sDevId, sFile, sFolder: WideString;
  1305. begin
  1306.   AddLog('+++++ '+bCopyTo.Caption+' +++++');
  1307.  
  1308.   if (ListBox1.ItemIndex >= 0) then
  1309.   begin
  1310.     //extract dev id
  1311.     sDevId := ListBox1.Items[ListBox1.ItemIndex];
  1312.     sDevId := Trim(Copy(sDevId, Pos(DEV_START_PATH, sDevId), Length(sDevId)));
  1313.  
  1314.     if OpenDialog1.Execute then
  1315.     begin
  1316.       //file
  1317.       sFile := OpenDialog1.FileName;
  1318.       //dest. folder
  1319.       sFolder := '';
  1320.       if (ListView1.ItemIndex >= 0) then
  1321.       begin
  1322.         //folder is marked in TObject
  1323.         sFolder := ListView1.Items.Item[ListView1.ItemIndex].SubItems[0];
  1324.  
  1325.         if Integer(ListView1.Items.Item[ListView1.ItemIndex].Data)=0 then //is no folder
  1326.         begin
  1327.           sFolder := ExcludeTrailingPathDelimiter(ExtractFilePath(sFolder));
  1328.         end;
  1329.       end
  1330.       else
  1331.       begin
  1332.         //get main folder ....
  1333.         if ListView1.Items.Count > 0 then
  1334.         begin
  1335.           sFolder := ListView1.Items.Item[0].SubItems[0];
  1336.           sFolder := ExcludeTrailingPathDelimiter(ExtractFilePath(sFolder));
  1337.         end;
  1338.       end;
  1339.  
  1340.       AddLog('Want transfer to: ' + sFolder);
  1341.  
  1342.       //transfer to destination folder
  1343.       if TransferFileToDevice(sDevId, sFile, sFolder) then
  1344.         ShowMessage('Saved!')
  1345.       else
  1346.         ShowMessage('Error!');
  1347.     end;
  1348.   end;
  1349. end;
  1350.  
  1351. procedure TForm12.bListTopClick(Sender: TObject);
  1352. var
  1353.   sDevId, sParent: WideString;
  1354. begin
  1355.   if Sender <> nil then
  1356.     AddLog('+++++ '+bListTop.Caption+' +++++');
  1357.    
  1358.   if ListBox1.ItemIndex >= 0 then
  1359.   begin
  1360.     //extract dev id
  1361.     sDevId := ListBox1.Items[ListBox1.ItemIndex];
  1362.     sDevId := Trim(Copy(sDevId, Pos(DEV_START_PATH, sDevId), Length(sDevId)));
  1363.  
  1364.     sParent := '';
  1365.     if (ListView1.ItemIndex>=0) and (Sender = nil) then
  1366.     begin
  1367.       sParent := ListView1.Items.Item[ListView1.ItemIndex].SubItems[0];
  1368.       if Cardinal(ListView1.Items.Item[ListView1.ItemIndex].Data) = 0 then Exit;//is not folder
  1369.     end;
  1370.  
  1371.     ListView1.Items.Clear;
  1372.     ListView1.Items.BeginUpdate;
  1373.     try
  1374.       ListFilesOnDevice(sDevId, ListView1.Items, sParent, False);
  1375.     finally
  1376.       ListView1.Items.EndUpdate;
  1377.     end;
  1378.   end;
  1379. end;
  1380.  
  1381. procedure TForm12.bCopySpecClick(Sender: TObject);
  1382. var
  1383.   sDevId, sFile, sFolder: WideString;
  1384. begin
  1385.   AddLog('+++++ '+bCopySpec.Caption+' +++++');
  1386.  
  1387.   if (ListBox1.ItemIndex >= 0) then
  1388.   begin
  1389.     //extract dev id
  1390.     sDevId := ListBox1.Items[ListBox1.ItemIndex];
  1391.     sDevId := Trim(Copy(sDevId, Pos(DEV_START_PATH, sDevId), Length(sDevId)));
  1392.  
  1393.     if OpenDialog1.Execute then
  1394.     begin
  1395.       //file
  1396.       sFile := OpenDialog1.FileName;
  1397.       //dest. folder
  1398.       if FindFolderOnDevice(sDevId, '', Edit1.Text, sFolder) then
  1399.       begin
  1400.         AddLog('Folder found: ' + sFolder);
  1401.         //transfer to destination folder
  1402.         if TransferFileToDevice(sDevId, sFile, sFolder) then
  1403.           ShowMessage('Saved!')
  1404.         else
  1405.           ShowMessage('Error!');
  1406.       end
  1407.       else
  1408.         ShowMessage('Cannot locate destination folder!');
  1409.     end;
  1410.   end
  1411.   else
  1412.     ShowMessage('Please, select a device!');
  1413. end;
  1414.  
  1415. procedure TForm12.ListBox1DblClick(Sender: TObject);
  1416. begin
  1417.   bListTopClick(bListTop);
  1418. end;
  1419.  
  1420. procedure TForm12.ListView1CustomDrawItem(Sender: TCustomListView;
  1421.   Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
  1422. begin
  1423.   DefaultDraw := True; //draw by default engine anyway
  1424.   Sender.Canvas.Font.Color := clBlack;
  1425.  
  1426.   if Cardinal(Item.Data) > 0 then //is folder?
  1427.   begin
  1428.     Sender.Canvas.Font.Color := clMaroon;
  1429.   end;
  1430. end;
  1431.  
  1432. procedure TForm12.ListView1DblClick(Sender: TObject);
  1433. begin
  1434.   //maybe file is dbl clked
  1435.   if (ListView1.ItemIndex >= 0) and (Cardinal(ListView1.Items.Item[ListView1.ItemIndex].Data) = 0) then
  1436.   begin
  1437.     bCopyFromClick(nil);
  1438.   end
  1439.   else
  1440.   begin
  1441.     AddLog('+++++ List specific folder +++++');
  1442.     bListTopClick(nil);
  1443.   end;
  1444. end;
  1445.  
  1446. procedure TForm12.ListView1DrawItem(Sender: TCustomListView; Item: TListItem;
  1447.   Rect: TRect; State: TOwnerDrawState);
  1448. begin
  1449.   //
  1450. end;
  1451.  
  1452. procedure TForm12.ListView1Editing(Sender: TObject; Item: TListItem;
  1453.   var AllowEdit: Boolean);
  1454. begin
  1455.   AllowEdit := False;
  1456. end;
  1457.  
  1458. initialization
  1459.   OleInitialize(nil);
  1460.  
  1461. finalization
  1462.   OleUninitialize;
  1463.  
  1464. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement