Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 29.11.2012, 09:19
Аватар для ilikecrunch
ilikecrunch ilikecrunch вне форума
Прохожий
 
Регистрация: 29.11.2012
Сообщения: 2
Версия Delphi: 7, xe3
Репутация: 10
Печаль Запись CD с помощью IMAPI2

Здравствуйте друзья! Призываю коллективный разум к помощи.

Как обычно наспех решаю небольшую задачу, в частности массовая запись подпапок из выбранной папки на диски (CD).
Тема в интернетах освещена довольно скудно, но удалось найти статейку по imapi2 от MS, которая и была взята за основу.
В целом получается всё, за одним небольшим исключением. После старта записи, мне нужно проверить что всё подходит для записи и если нет, то запросить смену диска и т.п. и сделать то же самое в цикле который пишет диски из массива папок, при этом нужно чтобы всё это дело ожидало вставки диска, проверяло его и соответственно либо продолжало итерацию, либо снова выплёвывало диск и ждало по новой.

Первоначальную проверку сделал на onClick кнопки записи, через exception,
а вот что делать в цикле ума не приложу, вроде как и исключение там не в тему, вроде и в библиотечках нету ничего что бы возвращало всё ОК или неОК. В общем вот код, думаю всё станет понятно.

Импортированы библиотеки типов:
Microsoft IMAPI2 Base Functionality
Microsoft IMAPI2 File System Image Creator

Из них использованы компоненты:
TMsftDiscMaster2
TMsftDiscRecorder2
TMsftFileSystemImage
TMsftDiscFormat2Data

Код:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, Winapi.ActiveX, System.SysUtils,
  System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
  Vcl.Dialogs, Vcl.OleServer, Vcl.StdCtrls, Vcl.FileCtrl, Vcl.Menus,
  Vcl.ComCtrls, IMAPI2_TLB, IMAPI2FS_TLB, System.Win.ComObj;

type
  Compare_Media_State = TOleEnum;
const
  Compare_Media_State_UNKNOWN = $00000000;
  Compare_Media_State_INFORMATIONAL_MASK = $0000000F;
  Compare_Media_State_UNSUPPORTED_MASK = $0000FC00;
  Compare_Media_State_OVERWRITE_ONLY = $00000001;
  Compare_Media_State_STATE_RANDOMLY_WRITABLE = $00000001;
  Compare_Media_State_BLANK = $00000002;
  Compare_Media_State_APPENDABLE = $00000004;
  Compare_Media_State_FINAL_SESSION = $00000008;
  Compare_Media_State_DAMAGED = $00000400;
  Compare_Media_State_ERASE_REQUIRED = $00000800;
  Compare_Media_State_NON_EMPTY_SESSION = $00001000;
  Compare_Media_State_WRITE_PROTECTED = $00002000;
  Compare_Media_State_FINALIZED = $00004000;
  Compare_Media_State_UNSUPPORTED_MEDIA = $00008000;

type
  TForm1 = class(TForm)
    GroupBox1: TGroupBox;
    Button1: TButton;
    RecorderComboBox: TComboBox;
    Button2: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    GroupBox2: TGroupBox;
    MainMenu1: TMainMenu;
    Vty1: TMenuItem;
    N1: TMenuItem;
    StatusBar1: TStatusBar;
    Label1: TLabel;
    TrackBar1: TTrackBar;
    Label2: TLabel;
    Button3: TButton;
    MsftDiscMaster: TMsftDiscMaster2;
    MsftDiscRecorder: TMsftDiscRecorder2;
    MsftFileSystemImage: TMsftFileSystemImage;
    MsftDiscFormat2Data: TMsftDiscFormat2Data;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure N1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  //Count copies of each folder.
  countCopy : integer;
  //Arrays is a folder-trees to write and to naming in log.
  treeToWrite, treeToName : array of string;
  const
    cap = 10;

implementation

{$R *.dfm}

//Update recorder-list button.
procedure TForm1.Button1Click(Sender: TObject);
var
  i:integer;
begin
  RecorderComboBox.Clear;
  for i := 0 to MsftDiscMaster.Count-1 do
    begin
      try
        MsftDiscRecorder.InitializeDiscRecorder(MsftDiscMaster.Item[i]);
        RecorderComboBox.Items.Add(MsftDiscRecorder.VendorId+' '+
          MsftDiscRecorder.ProductId);
        MsftDiscRecorder.Disconnect;
      except
        RecorderComboBox.Items.Add('---');
      end;
    end;
  RecorderComboBox.ItemIndex:=0;
end;

//Choose-directory button.
//If folder choosen, then writing subfolders to array used 4 writing & naming.
procedure TForm1.Button2Click(Sender: TObject);
var
  choosenDirectory:string;
  sr: TSearchRec;
  i : integer;
begin
  Edit1.Clear;
  i := 0;
  if SelectDirectory('Выберите каталог', '', choosenDirectory) then
    begin
    Edit1.Text := choosenDirectory;
    memo1.Lines.Add('Следующие папки будут записаны:');
    if Edit1.Text[Length(Edit1.Text)] <> '\' then
     Edit1.Text := Edit1.Text + '\';
    if FindFirst(Edit1.Text + '*.*', faAnyFile, sr) = 0 then
     repeat
      if (sr.Attr and faDirectory) <> 0 then
       if (sr.Name <> '.') and (sr.Name <> '..') then
       begin
       //Setting lenght of arrays
       if i = Length(treeToWrite) then SetLength(treeToWrite, i + cap);
       if i = Length(treeToName) then SetLength(treeToName, i + cap);
       //writing to trees
       treeToWrite[i] := Edit1.Text+sr.Name;
       treeToName[i] := sr.Name;
       //writing to log
       memo1.Lines.Add(treeToWrite[i]);
       i := i+1;
       end;
       until (FindNext(sr) <> 0);
       FindClose(sr);
    end
   else ShowMessage('Ошибка каталога! Пожалуйста выберите папку.');
end;

//Writing button.
//Create image 4 record, & writing according copycount.
procedure TForm1.Button3Click(Sender: TObject);
var
  DiscRoot : IFsiDirectoryItem;
  resimage : IFileSystemImageResult;
  DiscStream : IMAPI2_TLB.IStream;
  DR : IDiscRecorder2;
  i, j : integer;
begin
    if RecorderComboBox.Items[RecorderComboBox.ItemIndex]='---' then exit;
    if Length(treeToWrite) = 0 then exit;


    try
    for i  := 0 to Length(treeToWrite) do
      begin
      MsftDiscRecorder.InitializeDiscRecorder(MsftDiscMaster.
      Item[RecorderComboBox.ItemIndex]);

      DiscRoot:=MsftFileSystemImage.Root;
      if DirectoryExists(treeToWrite[i]) then DiscRoot.AddTree(treeToWrite[i],
        true);

      MsftDiscFormat2Data.Recorder:=MsftDiscRecorder.DefaultInterface;
      MsftDiscFormat2Data.ClientName:='IMAPI';

      DR:=IDiscRecorder2(MsftDiscRecorder.DefaultInterface);
      MsftFileSystemImage.ChooseImageDefaults(DR);

      //Setup volume name
      MsftFileSystemImage.VolumeName:= treeToName[i];
      //Writing volume name to log
      memo1.Lines.Add('Имя диска: ' + treeToName[i]);

      //Create result image to write
      resimage:=MsftFileSystemImage.CreateResultImage;
      //Create result stream
      DiscStream:=IMAPI2_TLB.IStream(resimage.ImageStream);
      memo1.Lines.Add('Подготовка диска завершена.');

      for j := 1 to countCopy do
       begin
          try
             memo1.Lines.Add('Запись копии '+IntToStr(j)+' из '+
              IntToStr(countCopy));
             MsftDiscFormat2Data.Write(DiscStream);
             MsftDiscRecorder.EjectMedia;
          except on Err : EOleException do
           begin
            MsftDiscRecorder.EjectMedia;
            ShowMessage('Пожалуйста вставьте чистый диск!');
            memo1.Lines.Add('Ожидание диска');
            repeat
              sleep(1000);
            until ;
            memo1.Lines.Add('Диск вставлен');
            j := j-1;
           end;
          end;
       end;
          MsftDiscRecorder.Disconnect;
      end;
    except on Err : EOleException do
    begin
        ShowMessage('Пожалуйста вставьте корректный диск!');
        memo1.Lines.Add('Ошибка диска!');
        MsftDiscRecorder.EjectMedia;
    end;
    end;

end;


procedure TForm1.FormCreate(Sender: TObject);
var
  i : integer;
begin
  //Setup copycount to default value.
  countCopy := TrackBar1.Position + 1;
  //Initialize recorders on start application
  RecorderComboBox.Clear;
  for i := 0 to MsftDiscMaster.Count-1 do
    begin
      try
        MsftDiscRecorder.InitializeDiscRecorder(MsftDiscMaster.Item[i]);
        RecorderComboBox.Items.Add(MsftDiscRecorder.VendorId+' '
          +MsftDiscRecorder.ProductId);
        MsftDiscRecorder.Disconnect;
      except
        RecorderComboBox.Items.Add('---');
      end;
    end;
  RecorderComboBox.ItemIndex:=0;
end;

procedure TForm1.N1Click(Sender: TObject);
begin
  Form1.Close;
end;

//Setup copycount manually by changing trackbar position
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
  countCopy := TrackBar1.Position + 1;
  memo1.Lines.Add('Количество копий каждой папки: ' + IntToStr(countCopy));
end;

end.

ps. Заранее прошу прощения, не знаю как его закатать под спойлер.
Также буду благодарен за любые советы в части улучшения кода/производительности.
Ответить с цитированием
  #2  
Старый 29.11.2012, 09:25
Аватар для ilikecrunch
ilikecrunch ilikecrunch вне форума
Прохожий
 
Регистрация: 29.11.2012
Сообщения: 2
Версия Delphi: 7, xe3
Репутация: 10
По умолчанию

Собственно вопрос заключается в том как правильно сделать циклическую проверку на наличие "корректного" диска в цикле в строке 173, сейчас там лабуда, один из вариантов на "попробовать", который не работает. ООоооооочень прошу помощииии....!!!

Последний раз редактировалось ilikecrunch, 29.11.2012 в 14:54.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:21.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter